@jsdoc/ast
Advanced tools
+33
-8
@@ -18,4 +18,6 @@ /* | ||
| // TODO: docs | ||
| import { name } from '@jsdoc/core'; | ||
| // For unknown reasons, `import { name } from '@jsdoc/core'` causes a `ReferenceError` here. | ||
| import * as name from '@jsdoc/core/lib/name.js'; | ||
| import { cast } from '@jsdoc/util'; | ||
| import moduleTypes from 'ast-module-types'; | ||
@@ -29,2 +31,8 @@ import { Syntax } from './syntax.js'; | ||
| export const MODULE_TYPES = { | ||
| AMD: 'amd', | ||
| COMMON_JS: 'commonjs', | ||
| ES6: 'es6', | ||
| }; | ||
| /** | ||
@@ -152,9 +160,3 @@ * Check whether an AST node represents a function. | ||
| case Syntax.ClassPrivateProperty: | ||
| // TODO: Strictly speaking, the name should be '#' plus node.key, but because we | ||
| // already use '#' as scope punctuation, that causes JSDoc to get extremely confused. | ||
| // The solution probably involves quoting part or all of the name, but JSDoc doesn't | ||
| // deal with quoted names very nicely right now, and most people probably won't want to | ||
| // document class private properties anyhow. So for now, we'll just cheat and omit the | ||
| // leading '#'. | ||
| str = nodeToValue(node.key.id); | ||
| str = SCOPE.PUNC.INSTANCE + nodeToValue(node.key.id); | ||
| break; | ||
@@ -291,2 +293,6 @@ | ||
| case Syntax.PrivateName: | ||
| str = SCOPE.PUNC.INSTANCE + nodeToValue(node.id); | ||
| break; | ||
| case Syntax.RestElement: | ||
@@ -574,1 +580,20 @@ str = nodeToValue(node.argument); | ||
| } | ||
| export function detectModuleType(node) { | ||
| if (moduleTypes.isES6Export(node) || moduleTypes.isES6Import(node)) { | ||
| return MODULE_TYPES.ES6; | ||
| } | ||
| if (moduleTypes.isDefineAMD(node) || moduleTypes.isAMDDriverScriptRequire(node)) { | ||
| return MODULE_TYPES.AMD; | ||
| } | ||
| if ( | ||
| moduleTypes.isExports(node) || | ||
| (moduleTypes.isRequire(node) && !moduleTypes.isDefineAMD(node)) | ||
| ) { | ||
| return MODULE_TYPES.COMMON_JS; | ||
| } | ||
| return null; | ||
| } |
+58
-51
@@ -56,5 +56,4 @@ /* | ||
| /* eslint-disable no-empty-function, no-unused-vars */ | ||
| // eslint-disable-next-line no-empty-function, no-unused-vars | ||
| function leafNode(node, parent, state, cb) {} | ||
| /* eslint-enable no-empty-function, no-unused-vars */ | ||
@@ -644,2 +643,39 @@ // TODO: docs | ||
| function handleNode(node, parent, cbState) { | ||
| let currentScope; | ||
| const isScope = astNode.isScope(node); | ||
| let moduleType; | ||
| const { walker } = cbState; | ||
| astNode.addNodeProperties(node); | ||
| node.parent = parent || null; | ||
| currentScope = getCurrentScope(cbState.scopes); | ||
| if (currentScope) { | ||
| node.enclosingScope = currentScope; | ||
| } | ||
| if (isScope) { | ||
| cbState.scopes.push(node); | ||
| } | ||
| cbState.nodes.push(node); | ||
| if (!cbState.moduleType) { | ||
| moduleType = cbState.moduleType = astNode.detectModuleType(node); | ||
| if (moduleType) { | ||
| cbState.moduleTypes.set(cbState.filename, moduleType); | ||
| } | ||
| } | ||
| if (!walker._walkers[node.type]) { | ||
| walker._logUnknownNodeType(node); | ||
| } else { | ||
| walker._walkers[node.type](node, parent, cbState, handleNode); | ||
| } | ||
| if (isScope) { | ||
| cbState.scopes.pop(); | ||
| } | ||
| } | ||
| /** | ||
@@ -650,61 +686,28 @@ * A walker that can traverse an ESTree AST. | ||
| // TODO: docs | ||
| constructor(deps, walkerFuncs = walkers) { | ||
| this._log = deps.get('log'); | ||
| constructor(env, { moduleTypes }, walkerFuncs = walkers) { | ||
| this._log = env.log; | ||
| this._moduleTypes = moduleTypes; | ||
| this._walkers = walkerFuncs; | ||
| } | ||
| _logUnknownNodeType({ type }) { | ||
| this._log.debug( | ||
| `Found a node with unrecognized type ${type}. Ignoring the node and its descendants.` | ||
| ); | ||
| } | ||
| // TODO: docs | ||
| _recurse(filename, ast) { | ||
| const self = this; | ||
| recurse(ast, visitor, filename) { | ||
| let shouldContinue; | ||
| const state = { | ||
| filename: filename, | ||
| moduleType: null, | ||
| moduleTypes: this._moduleTypes, | ||
| nodes: [], | ||
| scopes: [], | ||
| walker: this, | ||
| }; | ||
| function logUnknownNodeType({ type }) { | ||
| self._log.debug( | ||
| `Found a node with unrecognized type ${type}. Ignoring the node and its descendants.` | ||
| ); | ||
| } | ||
| handleNode(ast, null, state); | ||
| function cb(node, parent, cbState) { | ||
| let currentScope; | ||
| const isScope = astNode.isScope(node); | ||
| astNode.addNodeProperties(node); | ||
| node.parent = parent || null; | ||
| currentScope = getCurrentScope(cbState.scopes); | ||
| if (currentScope) { | ||
| node.enclosingScope = currentScope; | ||
| } | ||
| if (isScope) { | ||
| cbState.scopes.push(node); | ||
| } | ||
| cbState.nodes.push(node); | ||
| if (!self._walkers[node.type]) { | ||
| logUnknownNodeType(node); | ||
| } else { | ||
| self._walkers[node.type](node, parent, cbState, cb); | ||
| } | ||
| if (isScope) { | ||
| cbState.scopes.pop(); | ||
| } | ||
| } | ||
| cb(ast, null, state); | ||
| return state; | ||
| } | ||
| // TODO: docs | ||
| recurse(ast, visitor, filename) { | ||
| let shouldContinue; | ||
| const state = this._recurse(filename, ast); | ||
| if (visitor) { | ||
@@ -719,4 +722,8 @@ for (let node of state.nodes) { | ||
| return ast; | ||
| return { | ||
| ast, | ||
| filename: state.filename, | ||
| moduleType: state.moduleType, | ||
| }; | ||
| } | ||
| } |
+6
-5
| { | ||
| "name": "@jsdoc/ast", | ||
| "version": "0.2.10", | ||
| "version": "0.2.11", | ||
| "description": "JSDoc tools for working with abstract syntax trees (ASTs).", | ||
@@ -34,5 +34,6 @@ "keywords": [ | ||
| "dependencies": { | ||
| "@babel/parser": "^7.23.5", | ||
| "@jsdoc/core": "^0.5.7", | ||
| "@jsdoc/util": "^0.3.2", | ||
| "@babel/parser": "^7.24.4", | ||
| "@jsdoc/core": "^0.5.8", | ||
| "@jsdoc/util": "^0.3.3", | ||
| "ast-module-types": "^6.0.0", | ||
| "lodash": "^4.17.21" | ||
@@ -43,3 +44,3 @@ }, | ||
| }, | ||
| "gitHead": "db20d510665ac4ca9a363c08ea95e4ae88c09c4a" | ||
| "gitHead": "7942901ff766e74d5d800ae5c708ab72cf89cefe" | ||
| } |
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
52800
1.05%1256
2.28%0
-100%5
25%+ Added
Updated
Updated
Updated