mirror of
https://github.com/jsdoc/jsdoc.git
synced 2025-12-08 19:46:11 +00:00
refactor: move ast-builder and ast-node to @jsdoc/parse
BREAKING CHANGE: Modules no longer exist in jsdoc package.
This commit is contained in:
parent
86d18ff44a
commit
65e6db3ba4
@ -1,5 +1,9 @@
|
||||
const { AstBuilder } = require('./lib/ast-builder');
|
||||
const astNode = require('./lib/ast-node');
|
||||
const { Syntax } = require('./lib/syntax');
|
||||
|
||||
module.exports = {
|
||||
AstBuilder,
|
||||
astNode,
|
||||
Syntax
|
||||
};
|
||||
|
||||
@ -2,7 +2,7 @@ const _ = require('lodash');
|
||||
const babelParser = require('@babel/parser');
|
||||
const { log } = require('@jsdoc/util');
|
||||
|
||||
// exported so we can use them in tests
|
||||
// Exported so we can use them in tests.
|
||||
const parserOptions = exports.parserOptions = {
|
||||
allowAwaitOutsideFunction: true,
|
||||
allowImportExportEverywhere: true,
|
||||
@ -58,10 +58,8 @@ function parse(source, filename, sourceType) {
|
||||
// TODO: docs
|
||||
class AstBuilder {
|
||||
// TODO: docs
|
||||
/* eslint-disable class-methods-use-this */
|
||||
build(source, filename, sourceType) {
|
||||
static build(source, filename, sourceType) {
|
||||
return parse(source, filename, sourceType);
|
||||
}
|
||||
/* eslint-enable class-methods-use-this */
|
||||
}
|
||||
exports.AstBuilder = AstBuilder;
|
||||
@ -1,9 +1,9 @@
|
||||
// TODO: docs
|
||||
/** @module jsdoc/src/astnode */
|
||||
/** @module @jsdoc/parse.astNode */
|
||||
const _ = require('lodash');
|
||||
const { cast } = require('@jsdoc/util');
|
||||
const { SCOPE } = require('@jsdoc/core').name;
|
||||
const { Syntax } = require('@jsdoc/parse');
|
||||
const { Syntax } = require('./syntax');
|
||||
|
||||
// Counter for generating unique node IDs.
|
||||
let uid = 100000000;
|
||||
@ -11,7 +11,7 @@ let uid = 100000000;
|
||||
/**
|
||||
* Check whether an AST node represents a function.
|
||||
*
|
||||
* @alias module:jsdoc/src/astnode.isFunction
|
||||
* @alias module:@jsdoc/parse.astNode.isFunction
|
||||
* @param {(Object|string)} node - The AST node to check, or the `type` property of a node.
|
||||
* @return {boolean} Set to `true` if the node is a function or `false` in all other cases.
|
||||
*/
|
||||
@ -36,7 +36,7 @@ const isFunction = exports.isFunction = node => {
|
||||
/**
|
||||
* Check whether an AST node creates a new scope.
|
||||
*
|
||||
* @alias module:jsdoc/src/astnode.isScope
|
||||
* @alias module:@jsdoc/parse.astNode.isScope
|
||||
* @param {Object} node - The AST node to check.
|
||||
* @return {Boolean} Set to `true` if the node creates a new scope, or `false` in all other cases.
|
||||
*/
|
||||
@ -5,6 +5,22 @@ describe('@jsdoc/parse', () => {
|
||||
expect(parse).toBeObject();
|
||||
});
|
||||
|
||||
describe('AstBuilder', () => {
|
||||
it('is lib/ast-builder.AstBuilder', () => {
|
||||
const { AstBuilder } = require('../../lib/ast-builder');
|
||||
|
||||
expect(parse.AstBuilder).toBe(AstBuilder);
|
||||
});
|
||||
});
|
||||
|
||||
describe('astNode', () => {
|
||||
it('is lib/ast-node', () => {
|
||||
const astNode = require('../../lib/ast-node');
|
||||
|
||||
expect(parse.astNode).toBe(astNode);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Syntax', () => {
|
||||
it('is lib/syntax.Syntax', () => {
|
||||
const { Syntax } = require('../../lib/syntax');
|
||||
|
||||
41
packages/jsdoc-parse/test/specs/lib/ast-builder.js
Normal file
41
packages/jsdoc-parse/test/specs/lib/ast-builder.js
Normal file
@ -0,0 +1,41 @@
|
||||
/* global jsdoc */
|
||||
describe('@jsdoc/parse/lib/ast-builder', () => {
|
||||
const astBuilder = require('../../../lib/ast-builder');
|
||||
|
||||
it('is an object', () => {
|
||||
expect(astBuilder).toBeObject();
|
||||
});
|
||||
|
||||
it('exports an AstBuilder class', () => {
|
||||
expect(astBuilder.AstBuilder).toBeFunction();
|
||||
});
|
||||
|
||||
it('exports a parserOptions object', () => {
|
||||
expect(astBuilder.parserOptions).toBeObject();
|
||||
});
|
||||
|
||||
describe('AstBuilder', () => {
|
||||
const { AstBuilder } = astBuilder;
|
||||
|
||||
// TODO: more tests
|
||||
it('has a "build" static method', () => {
|
||||
expect(AstBuilder.build).toBeFunction();
|
||||
});
|
||||
|
||||
describe('build', () => {
|
||||
// TODO: more tests
|
||||
it('logs (not throws) an error when a file cannot be parsed', () => {
|
||||
function parse() {
|
||||
AstBuilder.build('qwerty!!!!!', 'bad.js');
|
||||
}
|
||||
|
||||
expect(parse).not.toThrow();
|
||||
expect(jsdoc.didLog(parse, 'error')).toBeTrue();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('parserOptions', () => {
|
||||
// TODO: tests
|
||||
});
|
||||
});
|
||||
@ -1,11 +1,11 @@
|
||||
describe('jsdoc/src/astNode', () => {
|
||||
const astBuilder = require('jsdoc/src/astbuilder');
|
||||
const astNode = require('jsdoc/src/astnode');
|
||||
describe('@jsdoc/parse/lib/ast-node', () => {
|
||||
const astNode = require('../../../lib/ast-node');
|
||||
const babelParser = require('@babel/parser');
|
||||
const { Syntax } = require('@jsdoc/parse');
|
||||
const { parserOptions } = require('../../../lib/ast-builder');
|
||||
const { Syntax } = require('../../../lib/syntax');
|
||||
|
||||
function parse(str) {
|
||||
return babelParser.parse(str, astBuilder.parserOptions).program.body[0];
|
||||
return babelParser.parse(str, parserOptions).program.body[0];
|
||||
}
|
||||
|
||||
// create the AST nodes we'll be testing
|
||||
@ -526,8 +526,8 @@ describe('jsdoc/src/astNode', () => {
|
||||
|
||||
// TODO: we can't test this here because JSDoc, not Babylon, adds the `parent` property to
|
||||
// nodes. also, we currently return an empty string instead of `<anonymous>` in this case;
|
||||
// see `module:jsdoc/src/astnode.nodeToValue` and the comment on `Syntax.MethodDefinition`
|
||||
// for details
|
||||
// see `module:@jsdoc/parse.astNode.nodeToValue` and the comment on
|
||||
// `Syntax.MethodDefinition` for details
|
||||
xit('should return `<anonymous>` for method definitions inside classes that were ' +
|
||||
'returned by an arrow function expression', () => {
|
||||
expect( astNode.nodeToValue(methodDefinition2) ).toBe('<anonymous>');
|
||||
@ -3,7 +3,7 @@
|
||||
*/
|
||||
const _ = require('lodash');
|
||||
let dictionary = require('jsdoc/tag/dictionary');
|
||||
const { isFunction } = require('jsdoc/src/astnode');
|
||||
const { isFunction } = require('@jsdoc/parse').astNode;
|
||||
const {
|
||||
applyNamespace,
|
||||
hasLeadingScope,
|
||||
@ -31,7 +31,7 @@ function fakeMeta(node) {
|
||||
}
|
||||
|
||||
// use the meta info about the source code to guess what the doclet kind should be
|
||||
// TODO: set this elsewhere (maybe jsdoc/src/astnode.getInfo)
|
||||
// TODO: set this elsewhere (maybe @jsdoc/parse.astNode.getInfo)
|
||||
function codeToKind(code) {
|
||||
let kind = 'member';
|
||||
const node = code.node;
|
||||
|
||||
@ -2,12 +2,13 @@
|
||||
* @module jsdoc/src/parser
|
||||
*/
|
||||
const _ = require('lodash');
|
||||
const astNode = require('jsdoc/src/astnode');
|
||||
const { AstBuilder, astNode, Syntax } = require('@jsdoc/parse');
|
||||
const { EventEmitter } = require('events');
|
||||
const fs = require('fs');
|
||||
const { log } = require('@jsdoc/util');
|
||||
const { getBasename, LONGNAMES, SCOPE, toParts } = require('@jsdoc/core').name;
|
||||
const { Syntax } = require('@jsdoc/parse');
|
||||
const { Visitor } = require('jsdoc/src/visitor');
|
||||
const { Walker } = require('jsdoc/src/walker');
|
||||
|
||||
const hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
|
||||
@ -61,7 +62,7 @@ exports.createParser = (type, conf) => {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new (require(modulePath).Parser)(null, null, null, conf);
|
||||
return new (require(modulePath).Parser)(conf);
|
||||
};
|
||||
|
||||
// TODO: docs
|
||||
@ -89,24 +90,18 @@ function definedInScope(doclet, basename) {
|
||||
*/
|
||||
class Parser extends EventEmitter {
|
||||
// TODO: docs
|
||||
constructor(builderInstance, visitorInstance, walkerInstance, conf) {
|
||||
constructor(conf) {
|
||||
super();
|
||||
|
||||
this.clear();
|
||||
|
||||
this._astBuilder = builderInstance || new (require('jsdoc/src/astbuilder').AstBuilder)();
|
||||
this._conf = conf || {};
|
||||
this._visitor = visitorInstance || new (require('jsdoc/src/visitor').Visitor)();
|
||||
this._walker = walkerInstance || new (require('jsdoc/src/walker').Walker)();
|
||||
this._visitor = new Visitor();
|
||||
this._walker = new Walker();
|
||||
|
||||
this._visitor.setParser(this);
|
||||
|
||||
Object.defineProperties(this, {
|
||||
astBuilder: {
|
||||
get() {
|
||||
return this._astBuilder;
|
||||
}
|
||||
},
|
||||
visitor: {
|
||||
get() {
|
||||
return this._visitor;
|
||||
@ -285,7 +280,7 @@ class Parser extends EventEmitter {
|
||||
sourceCode = pretreat(e.source);
|
||||
sourceType = this._conf.source ? this._conf.source.type : undefined;
|
||||
|
||||
ast = this._astBuilder.build(sourceCode, sourceName, sourceType);
|
||||
ast = AstBuilder.build(sourceCode, sourceName, sourceType);
|
||||
if (ast) {
|
||||
this._walkAst(ast, this._visitor, sourceName);
|
||||
}
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
* @module jsdoc/src/visitor
|
||||
*/
|
||||
// TODO: consider exporting more stuff so users can override it
|
||||
const astNode = require('jsdoc/src/astnode');
|
||||
const { astNode } = require('@jsdoc/parse');
|
||||
const combineDoclets = require('jsdoc/doclet').combine;
|
||||
const { getBasename, LONGNAMES } = require('@jsdoc/core').name;
|
||||
const { Syntax } = require('@jsdoc/parse');
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
*
|
||||
* @module jsdoc/src/walker
|
||||
*/
|
||||
const astnode = require('jsdoc/src/astnode');
|
||||
const { astNode } = require('@jsdoc/parse');
|
||||
const { log } = require('@jsdoc/util');
|
||||
const { Syntax } = require('@jsdoc/parse');
|
||||
|
||||
@ -655,9 +655,9 @@ class Walker {
|
||||
function cb(node, parent, cbState) {
|
||||
let currentScope;
|
||||
|
||||
const isScope = astnode.isScope(node);
|
||||
const isScope = astNode.isScope(node);
|
||||
|
||||
astnode.addNodeProperties(node);
|
||||
astNode.addNodeProperties(node);
|
||||
node.parent = parent || null;
|
||||
|
||||
currentScope = getCurrentScope(cbState.scopes);
|
||||
|
||||
@ -8,7 +8,7 @@ const commonPathPrefix = require('common-path-prefix');
|
||||
const env = require('jsdoc/env');
|
||||
const { isInlineTag } = require('jsdoc/tag/inline');
|
||||
const { log } = require('@jsdoc/util');
|
||||
const { nodeToValue } = require('jsdoc/src/astnode');
|
||||
const { nodeToValue } = require('@jsdoc/parse').astNode;
|
||||
const path = require('path');
|
||||
const { Syntax } = require('@jsdoc/parse');
|
||||
const parseTagType = require('jsdoc/tag/type').parse;
|
||||
|
||||
@ -20,8 +20,8 @@ describe('arrow functions', () => {
|
||||
});
|
||||
|
||||
// TODO: we currently use the wrong longname in this case; see
|
||||
// `module:jsdoc/src/astnode.nodeToValue` and the comment on `case Syntax.MethodDefinition` for
|
||||
// details
|
||||
// `module:@jsdoc/parse.astNode.nodeToValue` and the comment on `case Syntax.MethodDefinition`
|
||||
// for details
|
||||
xit('should use the correct longname for members of a class returned by an arrow function',
|
||||
() => {
|
||||
expect(name).toBeArrayOfSize(2);
|
||||
|
||||
@ -1,36 +0,0 @@
|
||||
describe('jsdoc/src/astbuilder', () => {
|
||||
const astbuilder = require('jsdoc/src/astbuilder');
|
||||
|
||||
it('should exist', () => {
|
||||
expect(astbuilder).toBeObject();
|
||||
});
|
||||
|
||||
it('should export an AstBuilder class', () => {
|
||||
expect(astbuilder.AstBuilder).toBeFunction();
|
||||
});
|
||||
|
||||
describe('AstBuilder', () => {
|
||||
// TODO: more tests
|
||||
let builder;
|
||||
|
||||
beforeEach(() => {
|
||||
builder = new astbuilder.AstBuilder();
|
||||
});
|
||||
|
||||
it('should provide a "build" method', () => {
|
||||
expect(builder.build).toBeFunction();
|
||||
});
|
||||
|
||||
describe('build', () => {
|
||||
// TODO: more tests
|
||||
it('should log (not throw) an error when a file cannot be parsed', () => {
|
||||
function parse() {
|
||||
builder.build('qwerty!!!!!', 'bad.js');
|
||||
}
|
||||
|
||||
expect(parse).not.toThrow();
|
||||
expect(jsdoc.didLog(parse, 'error')).toBeTrue();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -49,10 +49,6 @@ describe('jsdoc/src/parser', () => {
|
||||
|
||||
newParser();
|
||||
|
||||
it('should have an "astBuilder" property', () => {
|
||||
expect(parser.astBuilder).toBeObject();
|
||||
});
|
||||
|
||||
it('should have a "visitor" property', () => {
|
||||
expect(parser.visitor).toBeObject();
|
||||
});
|
||||
@ -61,22 +57,6 @@ describe('jsdoc/src/parser', () => {
|
||||
expect(parser.walker).toBeObject();
|
||||
});
|
||||
|
||||
it('should accept an astBuilder, visitor, and walker as arguments', () => {
|
||||
const astBuilder = {};
|
||||
const visitor = {
|
||||
/* eslint-disable no-empty-function */
|
||||
setParser() {}
|
||||
/* eslint-enable no-empty-function */
|
||||
};
|
||||
const walker = {};
|
||||
|
||||
const myParser = new jsdocParser.Parser(astBuilder, visitor, walker);
|
||||
|
||||
expect(myParser.astBuilder).toBe(astBuilder);
|
||||
expect(myParser.visitor).toBe(visitor);
|
||||
expect(myParser.walker).toBe(walker);
|
||||
});
|
||||
|
||||
it('should have a "parse" method', () => {
|
||||
expect(parser.parse).toBeFunction();
|
||||
});
|
||||
@ -93,14 +73,6 @@ describe('jsdoc/src/parser', () => {
|
||||
expect(parser.getAstNodeVisitors).toBeFunction();
|
||||
});
|
||||
|
||||
describe('astBuilder', () => {
|
||||
it('should contain an appropriate astBuilder by default', () => {
|
||||
const { AstBuilder } = require('jsdoc/src/astbuilder');
|
||||
|
||||
expect(parser.astBuilder instanceof AstBuilder).toBeTrue();
|
||||
});
|
||||
});
|
||||
|
||||
describe('visitor', () => {
|
||||
it('should contain an appropriate visitor by default', () => {
|
||||
const { Visitor } = require('jsdoc/src/visitor');
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user