@jsdoc/parse
Advanced tools
Comparing version 0.3.10 to 0.3.11
@@ -25,10 +25,12 @@ /* | ||
let currentModule = null; | ||
// Modules inferred from the value of an `@alias` tag, like `@alias module:foo.bar`. | ||
let inferredModules = []; | ||
class CurrentModule { | ||
class ModuleInfo { | ||
constructor(doclet) { | ||
this.doclet = doclet; | ||
this.longname = doclet.longname; | ||
this.originalName = doclet.meta.code.name || ''; | ||
this.originalName = doclet.meta?.code?.name ?? ''; | ||
} | ||
} | ||
function filterByLongname({ longname }) { | ||
@@ -93,5 +95,15 @@ // you can't document prototypes | ||
function setCurrentModule(doclet) { | ||
function getModule() { | ||
return inferredModules.length ? inferredModules[inferredModules.length - 1] : currentModule; | ||
} | ||
function setModule(doclet) { | ||
if (doclet.kind === 'module') { | ||
currentModule = new CurrentModule(doclet); | ||
currentModule = new ModuleInfo(doclet); | ||
} else if (doclet.longname.startsWith('module:')) { | ||
inferredModules.push( | ||
new ModuleInfo({ | ||
longname: name.getBasename(doclet.longname), | ||
}) | ||
); | ||
} | ||
@@ -101,2 +113,3 @@ } | ||
function setModuleScopeMemberOf(parser, doclet) { | ||
const moduleInfo = getModule(); | ||
let parentDoclet; | ||
@@ -106,22 +119,20 @@ let skipMemberof; | ||
// handle module symbols that are _not_ assigned to module.exports | ||
if (currentModule && currentModule.longname !== doclet.name) { | ||
if (moduleInfo && moduleInfo.longname !== doclet.name) { | ||
if (!doclet.scope) { | ||
// is this a method definition? if so, we usually get the scope from the node directly | ||
if (doclet.meta?.code?.node?.type === Syntax.MethodDefinition) { | ||
parentDoclet = parser._getDocletById(doclet.meta.code.node.parent.parent.nodeId); | ||
// special case for constructors of classes that have @alias tags | ||
if (doclet.meta.code.node.kind === 'constructor') { | ||
parentDoclet = parser._getDocletById(doclet.meta.code.node.parent.parent.nodeId); | ||
if (doclet.meta.code.node.kind === 'constructor' && parentDoclet?.alias) { | ||
// the constructor should use the same name as the class | ||
doclet.addTag('alias', parentDoclet.alias); | ||
doclet.addTag('name', parentDoclet.alias); | ||
// and we shouldn't try to set a memberof value | ||
skipMemberof = true; | ||
} else { | ||
doclet.addTag(doclet.meta.code.node.static ? 'static' : 'instance'); | ||
// The doclet should be a member of the parent doclet's alias. | ||
if (parentDoclet?.alias) { | ||
// the constructor should use the same name as the class | ||
doclet.addTag('alias', parentDoclet.alias); | ||
doclet.addTag('name', parentDoclet.alias); | ||
// and we shouldn't try to set a memberof value | ||
skipMemberof = true; | ||
doclet.memberof = parentDoclet.alias; | ||
} | ||
} else if (doclet.meta.code.node.static) { | ||
doclet.addTag('static'); | ||
} else { | ||
doclet.addTag('instance'); | ||
} | ||
@@ -142,3 +153,3 @@ } | ||
if (!doclet.memberof && doclet.scope !== SCOPE.NAMES.GLOBAL && !skipMemberof) { | ||
doclet.addTag('memberof', currentModule.longname); | ||
doclet.addTag('memberof', moduleInfo.longname); | ||
} | ||
@@ -159,3 +170,3 @@ } | ||
if (newDoclet) { | ||
setCurrentModule(newDoclet); | ||
setModule(newDoclet); | ||
e = { doclet: newDoclet }; | ||
@@ -374,3 +385,4 @@ parser.emit('newDoclet', e); | ||
currentModule = null; | ||
inferredModules = []; | ||
}); | ||
} |
@@ -16,2 +16,3 @@ /* | ||
*/ | ||
import EventEmitter from 'node:events'; | ||
@@ -79,4 +80,5 @@ import fs from 'node:fs'; | ||
this._log = dependencies.get('log'); | ||
this.moduleTypes = new Map(); | ||
this._visitor = new Visitor(); | ||
this._walker = new Walker(dependencies); | ||
this._walker = new Walker(dependencies, this); | ||
@@ -247,3 +249,5 @@ this._visitor.setParser(this); | ||
_walkAst(ast, visitor, sourceName) { | ||
this._walker.recurse(ast, visitor, sourceName); | ||
const { filename, moduleType } = this._walker.recurse(ast, visitor, sourceName); | ||
this.moduleTypes.set(filename, moduleType); | ||
} | ||
@@ -250,0 +254,0 @@ |
@@ -16,2 +16,5 @@ /* | ||
*/ | ||
import path from 'node:path'; | ||
import { astNode, Syntax } from '@jsdoc/ast'; | ||
@@ -57,5 +60,4 @@ import { name } from '@jsdoc/core'; | ||
// TODO: docs | ||
function getLeadingJsdocComment(node) { | ||
function getLeadingJsdocComment({ leadingComments }) { | ||
let comment = null; | ||
let leadingComments = node.leadingComments; | ||
@@ -111,2 +113,3 @@ if (Array.isArray(leadingComments) && leadingComments.length) { | ||
let documentedParams; | ||
const { doclet: eventDoclet } = e; | ||
let knownParams; | ||
@@ -125,3 +128,3 @@ let param; | ||
// a param tagged with `@exports` in an AMD module) | ||
if (e.doclet.kind !== 'param') { | ||
if (eventDoclet.kind !== 'param') { | ||
return; | ||
@@ -138,4 +141,4 @@ } | ||
// is the param already documented? if so, we don't need to use the doclet | ||
if (param?.name === e.doclet.name) { | ||
e.doclet.undocumented = true; | ||
if (param?.name === eventDoclet.name) { | ||
eventDoclet.undocumented = true; | ||
break; | ||
@@ -146,11 +149,11 @@ } | ||
// splice in the param at the current index | ||
if (!param || i === knownParams.indexOf(e.doclet.name)) { | ||
if (!param || i === knownParams.indexOf(eventDoclet.name)) { | ||
documentedParams.splice(i, 0, { | ||
type: e.doclet.type || {}, | ||
type: eventDoclet.type ?? {}, | ||
description: '', | ||
name: e.doclet.name, | ||
name: eventDoclet.name, | ||
}); | ||
// the doclet is no longer needed | ||
e.doclet.undocumented = true; | ||
eventDoclet.undocumented = true; | ||
@@ -199,4 +202,3 @@ break; | ||
function makeRestParamFinisher() { | ||
return (e) => { | ||
const doclet = e.doclet; | ||
return ({ code, doclet }) => { | ||
let documentedParams; | ||
@@ -209,5 +211,5 @@ let restNode; | ||
documentedParams = doclet.params = doclet.params || []; | ||
documentedParams = doclet.params ??= []; | ||
restNode = findRestParam( | ||
e.code.node.params || e.code.node.value?.params || e.code.node.init?.params || [] | ||
code.node.params || code.node.value?.params || code.node.init?.params || [] | ||
); | ||
@@ -263,5 +265,4 @@ | ||
function makeDefaultParamFinisher() { | ||
return (e) => { | ||
return ({ code, doclet }) => { | ||
let defaultValues; | ||
const doclet = e.doclet; | ||
let documentedParams; | ||
@@ -275,4 +276,4 @@ let paramName; | ||
documentedParams = doclet.params = doclet.params || []; | ||
params = e.code.node.params || e.code.node.value?.params || []; | ||
documentedParams = doclet.params ??= []; | ||
params = code.node.params ?? code.node.value?.params ?? []; | ||
defaultValues = findDefaultParams(params); | ||
@@ -320,6 +321,5 @@ | ||
function makeConstructorFinisher(parser) { | ||
return (e) => { | ||
return ({ code, doclet: eventDoclet }) => { | ||
let combined; | ||
let doclets; | ||
const eventDoclet = e.doclet; | ||
let nodeId; | ||
@@ -330,8 +330,8 @@ let parentDoclet; | ||
// ExportNamedDeclaration, not the ClassDeclaration | ||
if (e.code.node.parent.parent.parent?.type === Syntax.ExportNamedDeclaration) { | ||
nodeId = e.code.node.parent.parent.parent.nodeId; | ||
if (code.node.parent.parent.parent?.type === Syntax.ExportNamedDeclaration) { | ||
nodeId = code.node.parent.parent.parent.nodeId; | ||
} | ||
// otherwise, we want the ClassDeclaration | ||
else { | ||
nodeId = e.code.node.parent.parent.nodeId; | ||
nodeId = code.node.parent.parent.nodeId; | ||
} | ||
@@ -362,5 +362,3 @@ doclets = parser._docletStore.docletsByNodeId.get(nodeId); | ||
function makeAsyncFunctionFinisher() { | ||
return (e) => { | ||
const doclet = e.doclet; | ||
return ({ code, doclet }) => { | ||
if (!doclet) { | ||
@@ -370,3 +368,3 @@ return; | ||
if (e.code.node.async || e.code.node.value?.async || e.code.node.init?.async) { | ||
if (code.node.async || code.node.value?.async || code.node.init?.async) { | ||
doclet.async = true; | ||
@@ -396,5 +394,3 @@ } | ||
function makeGeneratorFinisher() { | ||
return (e) => { | ||
const doclet = e.doclet; | ||
return ({ code, doclet }) => { | ||
if (!doclet) { | ||
@@ -404,3 +400,3 @@ return; | ||
if (e.code.node.generator || e.code.node.init?.generator || e.code.node.value?.generator) { | ||
if (code.node.generator || code.node.init?.generator || code.node.value?.generator) { | ||
doclet.generator = true; | ||
@@ -411,6 +407,30 @@ } | ||
/** | ||
* Creates a function that adds the source file's module type to a doclet. | ||
* | ||
* @private | ||
* @return {function} A function that adds the module type to the doclet's `meta` info. | ||
*/ | ||
function makeModuleTypeFinisher(moduleTypes) { | ||
return ({ doclet }) => { | ||
let filepath; | ||
let type; | ||
if (!doclet || !doclet.meta.filename || !doclet.meta.path) { | ||
return; | ||
} | ||
filepath = path.join(doclet.meta.path, doclet.meta.filename); | ||
type = moduleTypes.get(filepath); | ||
if (type) { | ||
doclet.meta.moduletype = type; | ||
} | ||
}; | ||
} | ||
// TODO: docs | ||
class SymbolFound { | ||
// TODO: docs | ||
constructor(node, filename, extras = {}) { | ||
constructor(node, parser, filename, extras = {}) { | ||
this.id = extras.id || node.nodeId; | ||
@@ -426,2 +446,3 @@ this.comment = extras.comment || getLeadingJsdocComment(node) || '@undocumented'; | ||
this.finishers = extras.finishers || []; | ||
this.moduletype = null; | ||
@@ -495,2 +516,3 @@ // make sure the event includes properties that don't have default values | ||
code: astNode.getInfo(node), | ||
finishers: [makeModuleTypeFinisher(parser.moduleTypes)], | ||
}; | ||
@@ -501,3 +523,3 @@ | ||
case Syntax.AssignmentExpression: | ||
e = new SymbolFound(node, filename, extras); | ||
e = new SymbolFound(node, parser, filename, extras); | ||
@@ -518,4 +540,4 @@ trackVars(parser, node, e); | ||
if (node.leadingComments && parent && astNode.isFunction(parent)) { | ||
extras.finishers = [makeInlineParamsFinisher(parser)]; | ||
e = new SymbolFound(node, filename, extras); | ||
extras.finishers.push(makeInlineParamsFinisher(parser)); | ||
e = new SymbolFound(node, parser, filename, extras); | ||
@@ -533,3 +555,3 @@ trackVars(parser, node, e); | ||
case Syntax.ClassExpression: | ||
e = new SymbolFound(node, filename, extras); | ||
e = new SymbolFound(node, parser, filename, extras); | ||
@@ -544,5 +566,5 @@ trackVars(parser, node, e); | ||
case Syntax.ClassPrivateProperty: | ||
extras.finishers = [parser.resolveEnum, makePrivatePropertyFinisher()]; | ||
extras.finishers.push(parser.resolveEnum, makePrivatePropertyFinisher()); | ||
e = new SymbolFound(node, filename, extras); | ||
e = new SymbolFound(node, parser, filename, extras); | ||
@@ -553,5 +575,5 @@ break; | ||
case Syntax.ClassProperty: | ||
extras.finishers = [parser.resolveEnum]; | ||
extras.finishers.push(parser.resolveEnum); | ||
e = new SymbolFound(node, filename, extras); | ||
e = new SymbolFound(node, parser, filename, extras); | ||
@@ -562,3 +584,3 @@ break; | ||
case Syntax.ExportAllDeclaration: | ||
e = new SymbolFound(node, filename, extras); | ||
e = new SymbolFound(node, parser, filename, extras); | ||
@@ -578,3 +600,3 @@ break; | ||
case Syntax.ExportSpecifier: | ||
e = new SymbolFound(node, filename, extras); | ||
e = new SymbolFound(node, parser, filename, extras); | ||
@@ -595,3 +617,3 @@ trackVars(parser, node, e); | ||
case Syntax.FunctionExpression: | ||
extras.finishers = [ | ||
extras.finishers.push( | ||
// handle cases where at least one parameter has a default value | ||
@@ -604,6 +626,6 @@ makeDefaultParamFinisher(), | ||
// handle generator functions | ||
makeGeneratorFinisher(), | ||
]; | ||
makeGeneratorFinisher() | ||
); | ||
e = new SymbolFound(node, filename, extras); | ||
e = new SymbolFound(node, parser, filename, extras); | ||
@@ -626,4 +648,4 @@ trackVars(parser, node, e); | ||
if (node.leadingComments && parent && astNode.isFunction(parent)) { | ||
extras.finishers = [makeInlineParamsFinisher(parser)]; | ||
e = new SymbolFound(node, filename, extras); | ||
extras.finishers.push(makeInlineParamsFinisher(parser)); | ||
e = new SymbolFound(node, parser, filename, extras); | ||
@@ -640,3 +662,3 @@ trackVars(parser, node, e); | ||
if (node.leadingComments) { | ||
e = new SymbolFound(node, filename, extras); | ||
e = new SymbolFound(node, parser, filename, extras); | ||
} | ||
@@ -649,3 +671,3 @@ | ||
case Syntax.MethodDefinition: | ||
extras.finishers = [ | ||
extras.finishers.push( | ||
// handle cases where at least one parameter has a default value | ||
@@ -658,4 +680,4 @@ makeDefaultParamFinisher(), | ||
// handle generator functions | ||
makeGeneratorFinisher(), | ||
]; | ||
makeGeneratorFinisher() | ||
); | ||
// for constructors, we attempt to merge the constructor's docs into the class's docs | ||
@@ -666,3 +688,3 @@ if (node.kind === 'constructor') { | ||
e = new SymbolFound(node, filename, extras); | ||
e = new SymbolFound(node, parser, filename, extras); | ||
@@ -673,3 +695,3 @@ break; | ||
case Syntax.ObjectExpression: | ||
e = new SymbolFound(node, filename, extras); | ||
e = new SymbolFound(node, parser, filename, extras); | ||
@@ -682,6 +704,6 @@ break; | ||
if (node.kind !== 'get' && node.kind !== 'set') { | ||
extras.finishers = [parser.resolveEnum]; | ||
extras.finishers.push(parser.resolveEnum); | ||
} | ||
e = new SymbolFound(node, filename, extras); | ||
e = new SymbolFound(node, parser, filename, extras); | ||
@@ -695,4 +717,4 @@ break; | ||
if (node.leadingComments && parent && astNode.isFunction(parent)) { | ||
extras.finishers = [makeInlineParamsFinisher(parser)]; | ||
e = new SymbolFound(node, filename, extras); | ||
extras.finishers.push(makeInlineParamsFinisher(parser)); | ||
e = new SymbolFound(node, parser, filename, extras); | ||
@@ -706,3 +728,3 @@ trackVars(parser, node, e); | ||
case Syntax.VariableDeclarator: | ||
extras.finishers = [ | ||
extras.finishers.push( | ||
// handle cases where at least one parameter has a default value | ||
@@ -715,6 +737,6 @@ makeDefaultParamFinisher(), | ||
// handle generator functions | ||
makeGeneratorFinisher(), | ||
]; | ||
makeGeneratorFinisher() | ||
); | ||
e = new SymbolFound(node, filename, extras); | ||
e = new SymbolFound(node, parser, filename, extras); | ||
@@ -721,0 +743,0 @@ trackVars(parser, node, e); |
{ | ||
"name": "@jsdoc/parse", | ||
"version": "0.3.10", | ||
"version": "0.3.11", | ||
"description": "Parses, and extracts information from, source code.", | ||
@@ -16,8 +16,11 @@ "keywords": [ | ||
"dependencies": { | ||
"@jsdoc/ast": "^0.2.10", | ||
"@jsdoc/core": "^0.5.7", | ||
"@jsdoc/doclet": "^0.2.10", | ||
"@jsdoc/util": "^0.3.2", | ||
"@jsdoc/ast": "^0.2.11", | ||
"@jsdoc/core": "^0.5.8", | ||
"@jsdoc/doclet": "^0.2.11", | ||
"@jsdoc/util": "^0.3.3", | ||
"escape-string-regexp": "^5.0.0" | ||
}, | ||
"engines": { | ||
"node": ">=v18.12.0" | ||
}, | ||
"repository": { | ||
@@ -42,3 +45,3 @@ "type": "git", | ||
}, | ||
"gitHead": "db20d510665ac4ca9a363c08ea95e4ae88c09c4a" | ||
"gitHead": "7942901ff766e74d5d800ae5c708ab72cf89cefe" | ||
} |
67508
1575
- Removed@jsdoc/parse@0.3.11(transitive)
Updated@jsdoc/ast@^0.2.11
Updated@jsdoc/core@^0.5.8
Updated@jsdoc/doclet@^0.2.11
Updated@jsdoc/util@^0.3.3