@jqassistant/ts-lce
Version:
Tool to extract language concepts from a TypeScript codebase and export them to a JSON file.
81 lines (80 loc) • 5.29 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.ParameterPropertyTraverser = exports.MethodTraverser = 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");
const function_traverser_1 = require("./function.traverser");
/**
* Traversal of method constructs that may occur within (abstract) classes, interfaces, or types.
* This includes constructors, getters, and setters.
*
* Note: This traverser tries to unify the behavior for the traversal of `MethodDefinition`s and `TSMethodSignature`s by
* hoisting the child concepts of the function expression contained within the `MethodDefinition` to the method level to
* match the concept location with `TSMethodSignature`
*/
class MethodTraverser extends traverser_1.Traverser {
static KEY_PROP = "key";
static TYPE_PARAMETERS_PROP = "type-parameters";
static PARAMETERS_PROP = "parameters";
static DECORATORS_PROP = "decorators";
static VALUE_PROP = "value";
static RETURN_TYPE_PROP = "return-type";
traverseChildren(processingContext, processors) {
const { node } = processingContext;
const conceptMaps = [];
if (node.type === utils_1.AST_NODE_TYPES.MethodDefinition ||
node.type === utils_1.AST_NODE_TYPES.TSMethodSignature ||
node.type === utils_1.AST_NODE_TYPES.TSAbstractMethodDefinition) {
(0, traverser_utils_1.runTraverserForNode)(node.key, { parentPropName: MethodTraverser.KEY_PROP }, processingContext, processors, conceptMaps);
if (node.type === utils_1.AST_NODE_TYPES.MethodDefinition || node.type === utils_1.AST_NODE_TYPES.TSAbstractMethodDefinition) {
if (node.decorators)
(0, traverser_utils_1.runTraverserForNodes)(node.decorators, { parentPropName: MethodTraverser.DECORATORS_PROP }, processingContext, processors, conceptMaps);
if (node.value) {
// This implementation hoists the function expression type parameters, parameters, and return type concepts to the method level to
// preserve the correct node parent assignment while allowing for easier processing of methods
// see also FunctionTraverser
const childConcepts = (0, traverser_utils_1.runTraverserForNode)(node.value, { parentPropName: MethodTraverser.VALUE_PROP }, processingContext, processors);
if (childConcepts) {
const conceptMap = new Map();
if (childConcepts.has(function_traverser_1.FunctionTraverser.TYPE_PARAMETERS_PROP))
conceptMap.set(MethodTraverser.TYPE_PARAMETERS_PROP, childConcepts.get(function_traverser_1.FunctionTraverser.TYPE_PARAMETERS_PROP));
if (childConcepts.has(function_traverser_1.FunctionTraverser.PARAMETERS_PROP))
conceptMap.set(MethodTraverser.PARAMETERS_PROP, childConcepts.get(function_traverser_1.FunctionTraverser.PARAMETERS_PROP));
if (childConcepts.has(function_traverser_1.FunctionTraverser.RETURN_TYPE_PROP))
conceptMap.set(MethodTraverser.RETURN_TYPE_PROP, childConcepts.get(function_traverser_1.FunctionTraverser.RETURN_TYPE_PROP));
conceptMaps.push(conceptMap);
}
}
}
else {
if (node.typeParameters)
(0, traverser_utils_1.runTraverserForNode)(node.typeParameters, { parentPropName: MethodTraverser.TYPE_PARAMETERS_PROP }, processingContext, processors, conceptMaps);
(0, traverser_utils_1.runTraverserForNodes)(node.params, { parentPropName: MethodTraverser.PARAMETERS_PROP }, processingContext, processors, conceptMaps);
if (node.returnType)
(0, traverser_utils_1.runTraverserForNode)(node.returnType, { parentPropName: MethodTraverser.RETURN_TYPE_PROP }, processingContext, processors, conceptMaps);
}
}
return (0, concept_1.mergeConceptMaps)(...conceptMaps);
}
}
exports.MethodTraverser = MethodTraverser;
/**
* Traversal of parameter properties defined within class constructors
*/
class ParameterPropertyTraverser extends traverser_1.Traverser {
static DECORATORS_PROP = "decorators";
static PARAMETER_PROP = "parameter";
traverseChildren(processingContext, processors) {
const { node } = processingContext;
const conceptMaps = [];
if (node.type === utils_1.AST_NODE_TYPES.TSParameterProperty) {
if (node.decorators)
(0, traverser_utils_1.runTraverserForNodes)(node.decorators, { parentPropName: ParameterPropertyTraverser.DECORATORS_PROP }, processingContext, processors, conceptMaps);
(0, traverser_utils_1.runTraverserForNode)(node.parameter, { parentPropName: ParameterPropertyTraverser.PARAMETER_PROP }, processingContext, processors, conceptMaps);
}
return (0, concept_1.mergeConceptMaps)(...conceptMaps);
}
}
exports.ParameterPropertyTraverser = ParameterPropertyTraverser;