UNPKG

@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
"use strict"; 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;