@jqassistant/ts-lce
Version:
Tool to extract language concepts from a TypeScript codebase and export them to a JSON file.
79 lines (78 loc) • 4.17 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.StaticBlockTraverser = exports.ClassBodyTraverser = exports.ClassTraverser = void 0;
const utils_1 = require("@typescript-eslint/utils");
const concept_1 = require("../concept");
const traverser_1 = require("../traverser");
const traverser_utils_1 = require("../utils/traverser.utils");
/**
* Traversal of class declaration and class expressions
*
* Note that this Traverser mainly delegates to Traversers that handle "class signature" constructs like decorators, inheritance, or type parameters.
* The traversal of the actual class members is handled one level below via the `ClassBodyTraverser`
*/
class ClassTraverser extends traverser_1.Traverser {
static DECORATORS_PROP = "decorators";
static TYPE_PARAMETERS_PROP = "type-parameters";
static EXTENDS_PROP = "extends";
static IMPLEMENTS_PROP = "implements";
static EXTENDS_TYPE_PARAMETERS_PROP = "extends-type-parameters";
static BODY_PROP = "body";
traverseChildren(processingContext, processors) {
const { node } = processingContext;
const conceptMaps = [];
if (node.type === utils_1.AST_NODE_TYPES.ClassDeclaration || node.type === utils_1.AST_NODE_TYPES.ClassExpression) {
if (node.decorators) {
(0, traverser_utils_1.runTraverserForNodes)(node.decorators, { parentPropName: ClassTraverser.DECORATORS_PROP }, processingContext, processors, conceptMaps);
}
if (node.typeParameters) {
(0, traverser_utils_1.runTraverserForNodes)(node.typeParameters.params, // TODO: remove direct hoisting
{ parentPropName: ClassTraverser.TYPE_PARAMETERS_PROP }, processingContext, processors, conceptMaps);
}
if (node.superClass) {
(0, traverser_utils_1.runTraverserForNode)(node.superClass, { parentPropName: ClassTraverser.EXTENDS_PROP }, processingContext, processors, conceptMaps);
}
if (node.implements) {
(0, traverser_utils_1.runTraverserForNodes)(node.implements, { parentPropName: ClassTraverser.IMPLEMENTS_PROP }, processingContext, processors, conceptMaps);
}
if (node.superTypeArguments) {
(0, traverser_utils_1.runTraverserForNodes)(node.superTypeArguments.params, {
parentPropName: ClassTraverser.EXTENDS_TYPE_PARAMETERS_PROP,
}, processingContext, processors, conceptMaps);
}
(0, traverser_utils_1.runTraverserForNode)(node.body, { parentPropName: ClassTraverser.BODY_PROP }, processingContext, processors, conceptMaps);
}
return (0, concept_1.mergeConceptMaps)(...conceptMaps);
}
}
exports.ClassTraverser = ClassTraverser;
/**
* Traversal of the members of a class declaration/expression
*/
class ClassBodyTraverser extends traverser_1.Traverser {
static MEMBERS_PROP = "members";
traverseChildren(processingContext, processors) {
const { node } = processingContext;
const conceptMaps = [];
if (node.type === utils_1.AST_NODE_TYPES.ClassBody) {
(0, traverser_utils_1.runTraverserForNodes)(node.body, { parentPropName: ClassBodyTraverser.MEMBERS_PROP }, processingContext, processors, conceptMaps);
}
return (0, concept_1.mergeConceptMaps)(...conceptMaps);
}
}
exports.ClassBodyTraverser = ClassBodyTraverser;
/**
* Traversal of static blocks of a class declaration/expression that are part of the class body (see `ClassBodyTraverser`)
*/
class StaticBlockTraverser extends traverser_1.Traverser {
static BODY_PROP = "body";
traverseChildren(processingContext, processors) {
const { node } = processingContext;
const conceptMaps = [];
if (node.type === utils_1.AST_NODE_TYPES.StaticBlock) {
(0, traverser_utils_1.runTraverserForNodes)(node.body, { parentPropName: StaticBlockTraverser.BODY_PROP }, processingContext, processors, conceptMaps);
}
return (0, concept_1.mergeConceptMaps)(...conceptMaps);
}
}
exports.StaticBlockTraverser = StaticBlockTraverser;