ts2famix 1.4.1 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/analyze.js +4 -2
- package/dist/analyze_functions/process_functions.js +248 -100
- package/dist/famix2puml.js +1 -0
- package/dist/famix_functions/EntityDictionary.js +661 -155
- package/dist/famix_functions/helpers_creation.js +26 -6
- package/dist/fqn.js +156 -69
- package/dist/lib/famix/src/famix_JSON_exporter.js +1 -0
- package/dist/lib/famix/src/famix_base_element.js +1 -0
- package/dist/lib/famix/src/famix_repository.js +9 -8
- package/dist/lib/famix/src/index.js +1 -0
- package/dist/lib/famix/src/model/famix/access.js +3 -2
- package/dist/lib/famix/src/model/famix/accessor.js +1 -0
- package/dist/lib/famix/src/model/famix/alias.js +2 -1
- package/dist/lib/famix/src/model/famix/arrowFunction.js +17 -0
- package/dist/lib/famix/src/model/famix/behavioral_entity.js +13 -15
- package/dist/lib/famix/src/model/famix/class.js +1 -0
- package/dist/lib/famix/src/model/famix/comment.js +2 -1
- package/dist/lib/famix/src/model/famix/concretisation.js +31 -0
- package/dist/lib/famix/src/model/famix/container_entity.js +7 -6
- package/dist/lib/famix/src/model/famix/decorator.js +2 -1
- package/dist/lib/famix/src/model/famix/entity.js +1 -0
- package/dist/lib/famix/src/model/famix/enum.js +2 -1
- package/dist/lib/famix/src/model/famix/enum_value.js +2 -1
- package/dist/lib/famix/src/model/famix/function.js +1 -0
- package/dist/lib/famix/src/model/famix/implicit_variable.js +1 -0
- package/dist/lib/famix/src/model/famix/import_clause.js +5 -3
- package/dist/lib/famix/src/model/famix/index.js +18 -11
- package/dist/lib/famix/src/model/famix/indexed_file_anchor.js +3 -2
- package/dist/lib/famix/src/model/famix/inheritance.js +3 -2
- package/dist/lib/famix/src/model/famix/interface.js +2 -1
- package/dist/lib/famix/src/model/famix/invocation.js +3 -2
- package/dist/lib/famix/src/model/famix/method.js +2 -1
- package/dist/lib/famix/src/model/famix/module.js +53 -0
- package/dist/lib/famix/src/model/famix/named_entity.js +4 -3
- package/dist/lib/famix/src/model/famix/parameter.js +2 -1
- package/dist/lib/famix/src/model/famix/parameterConcretisation.js +44 -0
- package/dist/lib/famix/src/model/famix/parameter_type.js +22 -1
- package/dist/lib/famix/src/model/famix/parametric_arrow_function.js +31 -0
- package/dist/lib/famix/src/model/famix/parametric_class.js +44 -0
- package/dist/lib/famix/src/model/famix/parametric_function.js +31 -0
- package/dist/lib/famix/src/model/famix/parametric_interface.js +44 -0
- package/dist/lib/famix/src/model/famix/parametric_method.js +31 -0
- package/dist/lib/famix/src/model/famix/primitive_type.js +1 -0
- package/dist/lib/famix/src/model/famix/property.js +91 -9
- package/dist/lib/famix/src/model/famix/reference.js +3 -2
- package/dist/lib/famix/src/model/famix/scoping_entity.js +12 -10
- package/dist/lib/famix/src/model/famix/script_entity.js +1 -2
- package/dist/lib/famix/src/model/famix/source_anchor.js +1 -0
- package/dist/lib/famix/src/model/famix/source_language.js +1 -1
- package/dist/lib/famix/src/model/famix/sourced_entity.js +2 -1
- package/dist/lib/famix/src/model/famix/structural_entity.js +1 -0
- package/dist/lib/famix/src/model/famix/text_anchor.js +1 -0
- package/dist/lib/famix/src/model/famix/type.js +6 -4
- package/dist/lib/famix/src/model/famix/variable.js +1 -0
- package/dist/lib/ts-complex/cyclomatic-service.js +2 -2
- package/dist/ts2famix-cli-wrapper.js +16 -0
- package/dist/ts2famix-cli.js +8 -1
- package/dist/ts2famix-tsconfig.js +1 -0
- package/doc-uml/famix-typescript-model.puml +559 -0
- package/doc-uml/famix-typescript-model.svg +1 -0
- package/jest.config.json +2 -1
- package/package.json +10 -10
- package/src/analyze.ts +22 -21
- package/src/analyze_functions/process_functions.ts +272 -96
- package/src/famix_functions/EntityDictionary.ts +731 -182
- package/src/famix_functions/helpers_creation.ts +28 -2
- package/src/fqn.ts +132 -10
- package/src/lib/famix/src/famix_repository.ts +9 -9
- package/src/lib/famix/src/model/famix/access.ts +2 -2
- package/src/lib/famix/src/model/famix/alias.ts +1 -1
- package/src/lib/famix/src/model/famix/arrowFunction.ts +15 -0
- package/src/lib/famix/src/model/famix/behavioral_entity.ts +12 -19
- package/src/lib/famix/src/model/famix/comment.ts +1 -1
- package/src/lib/famix/src/model/famix/concretisation.ts +42 -0
- package/src/lib/famix/src/model/famix/container_entity.ts +6 -6
- package/src/lib/famix/src/model/famix/decorator.ts +1 -1
- package/src/lib/famix/src/model/famix/enum.ts +1 -1
- package/src/lib/famix/src/model/famix/enum_value.ts +1 -1
- package/src/lib/famix/src/model/famix/import_clause.ts +4 -3
- package/src/lib/famix/src/model/famix/index.ts +8 -5
- package/src/lib/famix/src/model/famix/indexed_file_anchor.ts +2 -2
- package/src/lib/famix/src/model/famix/inheritance.ts +3 -4
- package/src/lib/famix/src/model/famix/interface.ts +1 -1
- package/src/lib/famix/src/model/famix/invocation.ts +2 -2
- package/src/lib/famix/src/model/famix/method.ts +1 -1
- package/src/lib/famix/src/model/famix/module.ts +67 -1
- package/src/lib/famix/src/model/famix/named_entity.ts +3 -3
- package/src/lib/famix/src/model/famix/parameter.ts +1 -1
- package/src/lib/famix/src/model/famix/parameterConcretisation.ts +54 -0
- package/src/lib/famix/src/model/famix/parameter_type.ts +33 -6
- package/src/lib/famix/src/model/famix/parametric_arrow_function.ts +32 -0
- package/src/lib/famix/src/model/famix/parametric_class.ts +49 -0
- package/src/lib/famix/src/model/famix/parametric_function.ts +32 -0
- package/src/lib/famix/src/model/famix/parametric_interface.ts +49 -0
- package/src/lib/famix/src/model/famix/parametric_method.ts +32 -0
- package/src/lib/famix/src/model/famix/property.ts +109 -11
- package/src/lib/famix/src/model/famix/reference.ts +2 -2
- package/src/lib/famix/src/model/famix/scoping_entity.ts +12 -11
- package/src/lib/famix/src/model/famix/script_entity.ts +0 -2
- package/src/lib/famix/src/model/famix/source_language.ts +0 -1
- package/src/lib/famix/src/model/famix/sourced_entity.ts +1 -1
- package/src/lib/famix/src/model/famix/type.ts +5 -4
- package/src/ts2famix-cli-wrapper.ts +17 -0
- package/src/ts2famix-cli.ts +7 -1
- package/tsconfig.json +5 -5
- package/dist/lib/famix/src/model/famix/association.js +0 -36
- package/dist/lib/famix/src/model/famix/namespace.js +0 -24
- package/dist/lib/famix/src/model/famix/parameterizable_class.js +0 -30
- package/dist/lib/famix/src/model/famix/parameterizable_interface.js +0 -30
- package/dist/lib/famix/src/model/famix/parameterized_type.js +0 -36
- package/doc-uml/metamodel-full.svg +0 -1
- package/doc-uml/metamodel.svg +0 -1
- package/plantuml.jar +0 -0
- package/src/lib/famix/src/model/famix/association.ts +0 -44
- package/src/lib/famix/src/model/famix/namespace.ts +0 -28
- package/src/lib/famix/src/model/famix/parameterizable_class.ts +0 -31
- package/src/lib/famix/src/model/famix/parameterizable_interface.ts +0 -31
- package/src/lib/famix/src/model/famix/parameterized_type.ts +0 -40
|
@@ -1,15 +1,20 @@
|
|
|
1
|
-
import { ClassDeclaration, MethodDeclaration, VariableStatement, FunctionDeclaration, VariableDeclaration, InterfaceDeclaration, ParameterDeclaration, ConstructorDeclaration, MethodSignature, SourceFile, ModuleDeclaration, PropertyDeclaration, PropertySignature, Decorator, GetAccessorDeclaration, SetAccessorDeclaration, ExportedDeclarations, CommentRange, EnumDeclaration, EnumMember, TypeParameterDeclaration, TypeAliasDeclaration, SyntaxKind, FunctionExpression, Block, Identifier, ExpressionWithTypeArguments, ImportDeclaration, Node } from "ts-morph";
|
|
1
|
+
import { ClassDeclaration, MethodDeclaration, VariableStatement, FunctionDeclaration, VariableDeclaration, InterfaceDeclaration, ParameterDeclaration, ConstructorDeclaration, MethodSignature, SourceFile, ModuleDeclaration, PropertyDeclaration, PropertySignature, Decorator, GetAccessorDeclaration, SetAccessorDeclaration, ExportedDeclarations, CommentRange, EnumDeclaration, EnumMember, TypeParameterDeclaration, TypeAliasDeclaration, SyntaxKind, FunctionExpression, Block, Identifier, ExpressionWithTypeArguments, ImportDeclaration, Node, ArrowFunction, Scope, ClassExpression } from "ts-morph";
|
|
2
2
|
import * as Famix from "../lib/famix/src/model/famix";
|
|
3
3
|
import { calculate } from "../lib/ts-complex/cyclomatic-service";
|
|
4
4
|
import * as fs from 'fs';
|
|
5
5
|
import { logger , entityDictionary } from "../analyze";
|
|
6
|
+
import { getFQN } from "../fqn";
|
|
6
7
|
|
|
7
|
-
export
|
|
8
|
-
export
|
|
8
|
+
export type AccessibleTSMorphElement = ParameterDeclaration | VariableDeclaration | PropertyDeclaration | EnumMember;
|
|
9
|
+
export type FamixID = number;
|
|
10
|
+
|
|
11
|
+
export const methodsAndFunctionsWithId = new Map<number, MethodDeclaration | ConstructorDeclaration | GetAccessorDeclaration | SetAccessorDeclaration | FunctionDeclaration | FunctionExpression | ArrowFunction>(); // Maps the Famix method, constructor, getter, setter and function ids to their ts-morph method, constructor, getter, setter or function object
|
|
12
|
+
|
|
13
|
+
export const accessMap = new Map<FamixID, AccessibleTSMorphElement>(); // Maps the Famix parameter, variable, property and enum value ids to their ts-morph parameter, variable, property or enum member object
|
|
9
14
|
export const classes = new Array<ClassDeclaration>(); // Array of all the classes of the source files
|
|
10
15
|
export const interfaces = new Array<InterfaceDeclaration>(); // Array of all the interfaces of the source files
|
|
11
16
|
export const modules = new Array<SourceFile>(); // Array of all the source files which are modules
|
|
12
|
-
export const
|
|
17
|
+
export const listOfExportMaps = new Array<ReadonlyMap<string, ExportedDeclarations[]>>(); // Array of all the export maps
|
|
13
18
|
export let currentCC: unknown; // Stores the cyclomatic complexity metrics for the current source file
|
|
14
19
|
|
|
15
20
|
/**
|
|
@@ -17,7 +22,7 @@ export let currentCC: unknown; // Stores the cyclomatic complexity metrics for t
|
|
|
17
22
|
* @param sourceFile A source file
|
|
18
23
|
* @returns A boolean indicating if the file is a module
|
|
19
24
|
*/
|
|
20
|
-
function
|
|
25
|
+
function isSourceFileAModule(sourceFile: SourceFile): boolean {
|
|
21
26
|
return sourceFile.getImportDeclarations().length > 0 || sourceFile.getExportedDeclarations().size > 0;
|
|
22
27
|
}
|
|
23
28
|
|
|
@@ -95,13 +100,15 @@ export function processFiles(sourceFiles: Array<SourceFile>): void {
|
|
|
95
100
|
* @param f A source file
|
|
96
101
|
*/
|
|
97
102
|
function processFile(f: SourceFile): void {
|
|
98
|
-
const isModule =
|
|
103
|
+
const isModule = isSourceFileAModule(f);
|
|
99
104
|
|
|
100
105
|
if (isModule) {
|
|
101
106
|
modules.push(f);
|
|
102
|
-
exportedMap.push(f.getExportedDeclarations());
|
|
103
107
|
}
|
|
104
108
|
|
|
109
|
+
const exportMap = f.getExportedDeclarations();
|
|
110
|
+
if (exportMap) listOfExportMaps.push(exportMap);
|
|
111
|
+
|
|
105
112
|
const fmxFile = entityDictionary.createOrGetFamixFile(f, isModule);
|
|
106
113
|
|
|
107
114
|
logger.debug(`processFile: file: ${f.getBaseName()}, fqn = ${fmxFile.getFullyQualifiedName()}`);
|
|
@@ -120,44 +127,59 @@ function processFile(f: SourceFile): void {
|
|
|
120
127
|
|
|
121
128
|
processFunctions(f, fmxFile);
|
|
122
129
|
|
|
123
|
-
|
|
130
|
+
processModules(f, fmxFile);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
export function isAmbient(node: ModuleDeclaration): boolean {
|
|
134
|
+
// An ambient module has the DeclareKeyword modifier.
|
|
135
|
+
return (node.getModifiers()?.some(modifier => modifier.getKind() === SyntaxKind.DeclareKeyword)) ?? false;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
export function isNamespace(node: ModuleDeclaration): boolean {
|
|
139
|
+
// Check if the module declaration has a namespace keyword.
|
|
140
|
+
// This approach uses the getChildren() method to inspect the syntax directly.
|
|
141
|
+
return node.getChildrenOfKind(SyntaxKind.NamespaceKeyword).length > 0;
|
|
124
142
|
}
|
|
125
143
|
|
|
126
144
|
/**
|
|
127
|
-
* Builds a Famix model for a namespace
|
|
145
|
+
* Builds a Famix model for a module (also namespace)
|
|
128
146
|
* @param m A namespace
|
|
129
|
-
* @returns A Famix.
|
|
147
|
+
* @returns A Famix.Module representing the module
|
|
130
148
|
*/
|
|
131
|
-
function
|
|
132
|
-
const
|
|
149
|
+
function processModule(m: ModuleDeclaration): Famix.Module {
|
|
150
|
+
const fmxModule = entityDictionary.createOrGetFamixModule(m);
|
|
133
151
|
|
|
134
|
-
logger.debug(`
|
|
152
|
+
logger.debug(`module: ${m.getName()}, (${m.getType().getText()}), ${fmxModule.getFullyQualifiedName()}`);
|
|
135
153
|
|
|
136
|
-
processComments(m,
|
|
154
|
+
processComments(m, fmxModule);
|
|
137
155
|
|
|
138
|
-
processAliases(m,
|
|
156
|
+
processAliases(m, fmxModule);
|
|
139
157
|
|
|
140
|
-
processClasses(m,
|
|
158
|
+
processClasses(m, fmxModule);
|
|
141
159
|
|
|
142
|
-
processInterfaces(m,
|
|
160
|
+
processInterfaces(m, fmxModule);
|
|
143
161
|
|
|
144
|
-
processVariables(m,
|
|
162
|
+
processVariables(m, fmxModule);
|
|
145
163
|
|
|
146
|
-
processEnums(m,
|
|
164
|
+
processEnums(m, fmxModule);
|
|
147
165
|
|
|
148
|
-
processFunctions(m,
|
|
166
|
+
processFunctions(m, fmxModule);
|
|
149
167
|
|
|
150
|
-
|
|
168
|
+
processModules(m, fmxModule);
|
|
151
169
|
|
|
152
|
-
return
|
|
170
|
+
return fmxModule;
|
|
153
171
|
}
|
|
154
172
|
|
|
173
|
+
type ContainerTypes = SourceFile | ModuleDeclaration | FunctionDeclaration | FunctionExpression | MethodDeclaration | ConstructorDeclaration | GetAccessorDeclaration | SetAccessorDeclaration | ArrowFunction;
|
|
174
|
+
|
|
175
|
+
type ScopedTypes = Famix.ScriptEntity | Famix.Module | Famix.Function | Famix.Method | Famix.Accessor;
|
|
176
|
+
|
|
155
177
|
/**
|
|
156
178
|
* Builds a Famix model for the aliases of a container
|
|
157
179
|
* @param m A container (a source file, a namespace, a function or a method)
|
|
158
180
|
* @param fmxScope The Famix model of the container
|
|
159
181
|
*/
|
|
160
|
-
function processAliases(m:
|
|
182
|
+
function processAliases(m: ContainerTypes, fmxScope: ScopedTypes): void {
|
|
161
183
|
logger.debug(`processAliases: ---------- Finding Aliases:`);
|
|
162
184
|
m.getTypeAliases().forEach(a => {
|
|
163
185
|
const fmxAlias = processAlias(a);
|
|
@@ -170,20 +192,47 @@ function processAliases(m: SourceFile | ModuleDeclaration | FunctionDeclaration
|
|
|
170
192
|
* @param m A container (a source file or a namespace)
|
|
171
193
|
* @param fmxScope The Famix model of the container
|
|
172
194
|
*/
|
|
173
|
-
function processClasses(m: SourceFile | ModuleDeclaration, fmxScope: Famix.ScriptEntity | Famix.Module
|
|
195
|
+
function processClasses(m: SourceFile | ModuleDeclaration, fmxScope: Famix.ScriptEntity | Famix.Module ): void {
|
|
174
196
|
logger.debug(`processClasses: ---------- Finding Classes:`);
|
|
175
|
-
m
|
|
197
|
+
const classesInArrowFunctions = getClassesDeclaredInArrowFunctions(m);
|
|
198
|
+
const classes = m.getClasses().concat(classesInArrowFunctions);
|
|
199
|
+
classes.forEach(c => {
|
|
176
200
|
const fmxClass = processClass(c);
|
|
177
201
|
fmxScope.addType(fmxClass);
|
|
178
202
|
});
|
|
179
203
|
}
|
|
180
204
|
|
|
205
|
+
function getArrowFunctionClasses(f: ArrowFunction): ClassDeclaration[] {
|
|
206
|
+
const classes: ClassDeclaration[] = [];
|
|
207
|
+
|
|
208
|
+
function findClasses(node: any) {
|
|
209
|
+
if (node.getKind() === SyntaxKind.ClassDeclaration) {
|
|
210
|
+
classes.push(node as ClassDeclaration);
|
|
211
|
+
}
|
|
212
|
+
node.getChildren().forEach(findClasses);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
findClasses(f);
|
|
216
|
+
return classes;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* ts-morph doesn't find classes in arrow functions, so we need to find them manually
|
|
221
|
+
* @param s A source file
|
|
222
|
+
* @returns the ClassDeclaration objects found in arrow functions of the source file
|
|
223
|
+
*/
|
|
224
|
+
function getClassesDeclaredInArrowFunctions(s: SourceFile | ModuleDeclaration): ClassDeclaration[] {
|
|
225
|
+
const arrowFunctions = s.getDescendantsOfKind(SyntaxKind.ArrowFunction);
|
|
226
|
+
const classesInArrowFunctions = arrowFunctions.map(f => getArrowFunctionClasses(f)).flat();
|
|
227
|
+
return classesInArrowFunctions;
|
|
228
|
+
}
|
|
229
|
+
|
|
181
230
|
/**
|
|
182
231
|
* Builds a Famix model for the interfaces of a container
|
|
183
232
|
* @param m A container (a source file or a namespace)
|
|
184
233
|
* @param fmxScope The Famix model of the container
|
|
185
234
|
*/
|
|
186
|
-
function processInterfaces(m: SourceFile | ModuleDeclaration, fmxScope: Famix.ScriptEntity | Famix.Module
|
|
235
|
+
function processInterfaces(m: SourceFile | ModuleDeclaration, fmxScope: Famix.ScriptEntity | Famix.Module ): void {
|
|
187
236
|
logger.debug(`processInterfaces: ---------- Finding Interfaces:`);
|
|
188
237
|
m.getInterfaces().forEach(i => {
|
|
189
238
|
const fmxInterface = processInterface(i);
|
|
@@ -196,7 +245,7 @@ function processInterfaces(m: SourceFile | ModuleDeclaration, fmxScope: Famix.Sc
|
|
|
196
245
|
* @param m A container (a source file, a namespace, a function or a method)
|
|
197
246
|
* @param fmxScope The Famix model of the container
|
|
198
247
|
*/
|
|
199
|
-
function processVariables(m:
|
|
248
|
+
function processVariables(m: ContainerTypes, fmxScope: Famix.ScriptEntity | Famix.Module | Famix.Function | Famix.Method | Famix.Accessor): void {
|
|
200
249
|
logger.debug(`processVariables: ---------- Finding Variables:`);
|
|
201
250
|
m.getVariableStatements().forEach(v => {
|
|
202
251
|
const fmxVariables = processVariableStatement(v);
|
|
@@ -211,7 +260,7 @@ function processVariables(m: SourceFile | ModuleDeclaration | FunctionDeclaratio
|
|
|
211
260
|
* @param m A container (a source file, a namespace, a function or a method)
|
|
212
261
|
* @param fmxScope The Famix model of the container
|
|
213
262
|
*/
|
|
214
|
-
function processEnums(m:
|
|
263
|
+
function processEnums(m: ContainerTypes, fmxScope: ScopedTypes): void {
|
|
215
264
|
logger.debug(`processEnums: ---------- Finding Enums:`);
|
|
216
265
|
m.getEnums().forEach(e => {
|
|
217
266
|
const fmxEnum = processEnum(e);
|
|
@@ -224,24 +273,32 @@ function processEnums(m: SourceFile | ModuleDeclaration | FunctionDeclaration |
|
|
|
224
273
|
* @param m A container (a source file, a namespace, a function or a method)
|
|
225
274
|
* @param fmxScope The Famix model of the container
|
|
226
275
|
*/
|
|
227
|
-
function processFunctions(m:
|
|
276
|
+
function processFunctions(m: ContainerTypes, fmxScope: ScopedTypes): void {
|
|
228
277
|
logger.debug(`Finding Functions:`);
|
|
229
278
|
m.getFunctions().forEach(f => {
|
|
230
279
|
const fmxFunction = processFunction(f);
|
|
231
280
|
fmxScope.addFunction(fmxFunction);
|
|
232
281
|
});
|
|
282
|
+
|
|
283
|
+
//find arrow functions
|
|
284
|
+
logger.debug(`Finding Functions:`);
|
|
285
|
+
const arrowFunctions = m.getDescendantsOfKind(SyntaxKind.ArrowFunction);
|
|
286
|
+
arrowFunctions.forEach(af => {
|
|
287
|
+
const fmxFunction = processFunction(af);
|
|
288
|
+
fmxScope.addFunction(fmxFunction);
|
|
289
|
+
})
|
|
233
290
|
}
|
|
234
291
|
|
|
235
292
|
/**
|
|
236
|
-
* Builds a Famix model for the
|
|
293
|
+
* Builds a Famix model for the modules of a container.
|
|
237
294
|
* @param m A container (a source file or a namespace)
|
|
238
295
|
* @param fmxScope The Famix model of the container
|
|
239
296
|
*/
|
|
240
|
-
function
|
|
241
|
-
logger.debug(`Finding
|
|
297
|
+
function processModules(m: SourceFile | ModuleDeclaration, fmxScope: Famix.ScriptEntity | Famix.Module ): void {
|
|
298
|
+
logger.debug(`Finding Modules:`);
|
|
242
299
|
m.getModules().forEach(md => {
|
|
243
|
-
const
|
|
244
|
-
fmxScope.
|
|
300
|
+
const fmxModule = processModule(md);
|
|
301
|
+
fmxScope.addModule(fmxModule);
|
|
245
302
|
});
|
|
246
303
|
}
|
|
247
304
|
|
|
@@ -263,9 +320,9 @@ function processAlias(a: TypeAliasDeclaration): Famix.Alias {
|
|
|
263
320
|
/**
|
|
264
321
|
* Builds a Famix model for a class
|
|
265
322
|
* @param c A class
|
|
266
|
-
* @returns A Famix.Class or a Famix.
|
|
323
|
+
* @returns A Famix.Class or a Famix.ParametricClass representing the class
|
|
267
324
|
*/
|
|
268
|
-
function processClass(c: ClassDeclaration): Famix.Class | Famix.
|
|
325
|
+
function processClass(c: ClassDeclaration): Famix.Class | Famix.ParametricClass {
|
|
269
326
|
classes.push(c);
|
|
270
327
|
|
|
271
328
|
const fmxClass = entityDictionary.createOrGetFamixClass(c);
|
|
@@ -299,9 +356,9 @@ function processClass(c: ClassDeclaration): Famix.Class | Famix.ParameterizableC
|
|
|
299
356
|
/**
|
|
300
357
|
* Builds a Famix model for an interface
|
|
301
358
|
* @param i An interface
|
|
302
|
-
* @returns A Famix.Interface or a Famix.
|
|
359
|
+
* @returns A Famix.Interface or a Famix.ParametricInterface representing the interface
|
|
303
360
|
*/
|
|
304
|
-
function processInterface(i: InterfaceDeclaration): Famix.Interface | Famix.
|
|
361
|
+
function processInterface(i: InterfaceDeclaration): Famix.Interface | Famix.ParametricInterface {
|
|
305
362
|
interfaces.push(i);
|
|
306
363
|
|
|
307
364
|
const fmxInterface = entityDictionary.createOrGetFamixInterface(i);
|
|
@@ -320,9 +377,9 @@ function processInterface(i: InterfaceDeclaration): Famix.Interface | Famix.Para
|
|
|
320
377
|
* @param c A structured type (a class or an interface)
|
|
321
378
|
* @param fmxScope The Famix model of the structured type
|
|
322
379
|
*/
|
|
323
|
-
function processStructuredType(c: ClassDeclaration | InterfaceDeclaration, fmxScope: Famix.Class | Famix.
|
|
380
|
+
function processStructuredType(c: ClassDeclaration | InterfaceDeclaration, fmxScope: Famix.Class | Famix.ParametricClass | Famix.Interface | Famix.ParametricInterface): void {
|
|
324
381
|
logger.debug(`Finding Properties and Methods:`);
|
|
325
|
-
if (fmxScope instanceof Famix.
|
|
382
|
+
if (fmxScope instanceof Famix.ParametricClass || fmxScope instanceof Famix.ParametricInterface) {
|
|
326
383
|
processTypeParameters(c, fmxScope);
|
|
327
384
|
}
|
|
328
385
|
|
|
@@ -350,11 +407,12 @@ function processProperty(p: PropertyDeclaration | PropertySignature): Famix.Prop
|
|
|
350
407
|
const ancestor = p.getFirstAncestorOrThrow();
|
|
351
408
|
logger.debug(` ---> Its first ancestor is a ${ancestor.getKindName()}`);
|
|
352
409
|
|
|
410
|
+
// decorators
|
|
353
411
|
if (!(p instanceof PropertySignature)) {
|
|
354
412
|
processDecorators(p, fmxProperty);
|
|
355
413
|
// only add access if the p's first ancestor is not a PropertyDeclaration
|
|
356
414
|
if (ancestor.getKindName() !== "PropertyDeclaration") {
|
|
357
|
-
logger.debug(`adding access: ${p.getName()}, (${p.getType().getText()}) Famix ${fmxProperty.getName()}`);
|
|
415
|
+
logger.debug(`adding access to map: ${p.getName()}, (${p.getType().getText()}) Famix ${fmxProperty.getName()} id: ${fmxProperty.id}`);
|
|
358
416
|
accessMap.set(fmxProperty.id, p);
|
|
359
417
|
}
|
|
360
418
|
}
|
|
@@ -370,7 +428,7 @@ function processProperty(p: PropertyDeclaration | PropertySignature): Famix.Prop
|
|
|
370
428
|
* @returns A Famix.Method or a Famix.Accessor representing the method or the accessor
|
|
371
429
|
*/
|
|
372
430
|
function processMethod(m: MethodDeclaration | ConstructorDeclaration | MethodSignature | GetAccessorDeclaration | SetAccessorDeclaration): Famix.Method | Famix.Accessor {
|
|
373
|
-
const fmxMethod = entityDictionary.
|
|
431
|
+
const fmxMethod = entityDictionary.createOrGetFamixMethod(m, currentCC);
|
|
374
432
|
|
|
375
433
|
logger.debug(`Method: ${!(m instanceof ConstructorDeclaration) ? m.getName() : "constructor"}, (${m.getType().getText()}), parent: ${(m.getParent() as ClassDeclaration | InterfaceDeclaration).getName()}, fqn = ${fmxMethod.getFullyQualifiedName()}`);
|
|
376
434
|
|
|
@@ -406,10 +464,16 @@ function processMethod(m: MethodDeclaration | ConstructorDeclaration | MethodSig
|
|
|
406
464
|
* @param f A function
|
|
407
465
|
* @returns A Famix.Function representing the function
|
|
408
466
|
*/
|
|
409
|
-
function processFunction(f: FunctionDeclaration | FunctionExpression): Famix.Function {
|
|
410
|
-
const fmxFunction = entityDictionary.createFamixFunction(f, currentCC);
|
|
467
|
+
function processFunction(f: FunctionDeclaration | FunctionExpression | ArrowFunction): Famix.Function {
|
|
411
468
|
|
|
412
|
-
logger.debug(`Function: ${(f.getName()
|
|
469
|
+
logger.debug(`Function: ${(f instanceof ArrowFunction ? "anonymous" : f.getName() ? f.getName() : "anonymous")}, (${f.getType().getText()}), fqn = ${getFQN(f)}`);
|
|
470
|
+
|
|
471
|
+
let fmxFunction;
|
|
472
|
+
if( f instanceof ArrowFunction) {
|
|
473
|
+
fmxFunction = entityDictionary.createFamixArrowFunction(f, currentCC);
|
|
474
|
+
} else {
|
|
475
|
+
fmxFunction = entityDictionary.createOrGetFamixFunction(f, currentCC);
|
|
476
|
+
}
|
|
413
477
|
|
|
414
478
|
processComments(f, fmxFunction);
|
|
415
479
|
|
|
@@ -453,14 +517,84 @@ function processFunctionExpressions(f: FunctionDeclaration | MethodDeclaration |
|
|
|
453
517
|
* @param m A method or a function
|
|
454
518
|
* @param fmxScope The Famix model of the method or the function
|
|
455
519
|
*/
|
|
456
|
-
function processParameters(m: MethodDeclaration | ConstructorDeclaration | MethodSignature | GetAccessorDeclaration | SetAccessorDeclaration | FunctionDeclaration | FunctionExpression, fmxScope: Famix.Method | Famix.Accessor | Famix.Function): void {
|
|
520
|
+
function processParameters(m: MethodDeclaration | ConstructorDeclaration | MethodSignature | GetAccessorDeclaration | SetAccessorDeclaration | FunctionDeclaration | FunctionExpression | ArrowFunction, fmxScope: Famix.Method | Famix.Accessor | Famix.Function): void {
|
|
457
521
|
logger.debug(`Finding Parameters:`);
|
|
458
522
|
m.getParameters().forEach(param => {
|
|
459
523
|
const fmxParam = processParameter(param);
|
|
460
524
|
fmxScope.addParameter(fmxParam);
|
|
525
|
+
// Additional handling for Parameter Properties in constructors
|
|
526
|
+
if (m instanceof ConstructorDeclaration) {
|
|
527
|
+
// Check if the parameter has any visibility modifier
|
|
528
|
+
if (param.hasModifier(SyntaxKind.PrivateKeyword) || param.hasModifier(SyntaxKind.PublicKeyword) || param.hasModifier(SyntaxKind.ProtectedKeyword) || param.hasModifier(SyntaxKind.ReadonlyKeyword)) {
|
|
529
|
+
const classOfConstructor = m.getParent();
|
|
530
|
+
logger.info(`Parameter Property ${param.getName()} in constructor of ${classOfConstructor.getName()}.`);
|
|
531
|
+
// Treat the parameter as a property and add it to the class
|
|
532
|
+
const fmxProperty = processParameterAsProperty(param, classOfConstructor);
|
|
533
|
+
fmxProperty.readOnly = param.hasModifier(SyntaxKind.ReadonlyKeyword);
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
|
|
461
537
|
});
|
|
462
538
|
}
|
|
463
539
|
|
|
540
|
+
// This function should create a Famix.Property model from a ParameterDeclaration
|
|
541
|
+
// You'll need to implement it according to your Famix model structure
|
|
542
|
+
function processParameterAsProperty(param: ParameterDeclaration, c: ClassDeclaration | ClassExpression): Famix.Property {
|
|
543
|
+
// Convert the parameter into a Property
|
|
544
|
+
const propertyRepresentation = convertParameterToPropertyRepresentation(param);
|
|
545
|
+
|
|
546
|
+
// Add the property to the class so we can have a PropertyDeclaration object
|
|
547
|
+
c.addProperty(propertyRepresentation);
|
|
548
|
+
|
|
549
|
+
const p = c.getProperty(propertyRepresentation.name);
|
|
550
|
+
const fmxProperty = entityDictionary.createFamixProperty(p);
|
|
551
|
+
if (c instanceof ClassDeclaration) {
|
|
552
|
+
const fmxClass = entityDictionary.createOrGetFamixClass(c);
|
|
553
|
+
fmxClass.addProperty(fmxProperty);
|
|
554
|
+
} else {
|
|
555
|
+
throw new Error("Unexpected type ClassExpression.");
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
processComments(p, fmxProperty);
|
|
559
|
+
|
|
560
|
+
// remove the property from the class
|
|
561
|
+
p.remove();
|
|
562
|
+
|
|
563
|
+
return fmxProperty;
|
|
564
|
+
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
function convertParameterToPropertyRepresentation(param: ParameterDeclaration) {
|
|
568
|
+
// Extract name
|
|
569
|
+
const paramName = param.getName();
|
|
570
|
+
|
|
571
|
+
// Extract type
|
|
572
|
+
const paramType = param.getType().getText(param);
|
|
573
|
+
|
|
574
|
+
// Determine visibility
|
|
575
|
+
let scope: Scope;
|
|
576
|
+
if (param.hasModifier(SyntaxKind.PrivateKeyword)) {
|
|
577
|
+
scope = Scope.Private;
|
|
578
|
+
} else if (param.hasModifier(SyntaxKind.ProtectedKeyword)) {
|
|
579
|
+
scope = Scope.Protected;
|
|
580
|
+
} else if (param.hasModifier(SyntaxKind.PublicKeyword)) {
|
|
581
|
+
scope = Scope.Public;
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
// Determine if readonly
|
|
585
|
+
const isReadonly = param.hasModifier(SyntaxKind.ReadonlyKeyword);
|
|
586
|
+
|
|
587
|
+
// Create a representation of the property
|
|
588
|
+
const propertyRepresentation = {
|
|
589
|
+
name: paramName,
|
|
590
|
+
type: paramType,
|
|
591
|
+
scope: scope,
|
|
592
|
+
isReadonly: isReadonly,
|
|
593
|
+
};
|
|
594
|
+
|
|
595
|
+
return propertyRepresentation;
|
|
596
|
+
}
|
|
597
|
+
|
|
464
598
|
/**
|
|
465
599
|
* Builds a Famix model for a parameter
|
|
466
600
|
* @param p A parameter
|
|
@@ -490,11 +624,11 @@ function processParameter(p: ParameterDeclaration): Famix.Parameter {
|
|
|
490
624
|
* @param e A class, an interface, a method or a function
|
|
491
625
|
* @param fmxScope The Famix model of the class, the interface, the method or the function
|
|
492
626
|
*/
|
|
493
|
-
function processTypeParameters(e: ClassDeclaration | InterfaceDeclaration | MethodDeclaration | ConstructorDeclaration | MethodSignature | GetAccessorDeclaration | SetAccessorDeclaration | FunctionDeclaration | FunctionExpression, fmxScope: Famix.
|
|
627
|
+
function processTypeParameters(e: ClassDeclaration | InterfaceDeclaration | MethodDeclaration | ConstructorDeclaration | MethodSignature | GetAccessorDeclaration | SetAccessorDeclaration | FunctionDeclaration | FunctionExpression |ArrowFunction, fmxScope: Famix.ParametricClass | Famix.ParametricInterface | Famix.Method | Famix.Accessor | Famix.Function | Famix.ArrowFunction): void {
|
|
494
628
|
logger.debug(`Finding Type Parameters:`);
|
|
495
629
|
e.getTypeParameters().forEach(tp => {
|
|
496
630
|
const fmxParam = processTypeParameter(tp);
|
|
497
|
-
fmxScope.
|
|
631
|
+
fmxScope.addGenericParameter(fmxParam);
|
|
498
632
|
});
|
|
499
633
|
}
|
|
500
634
|
|
|
@@ -593,7 +727,7 @@ function processEnumValue(v: EnumMember): Famix.EnumValue {
|
|
|
593
727
|
* @param e A class, a method, a parameter or a property
|
|
594
728
|
* @param fmxScope The Famix model of the class, the method, the parameter or the property
|
|
595
729
|
*/
|
|
596
|
-
function processDecorators(e: ClassDeclaration | MethodDeclaration | GetAccessorDeclaration | SetAccessorDeclaration | ParameterDeclaration | PropertyDeclaration, fmxScope: Famix.Class | Famix.
|
|
730
|
+
function processDecorators(e: ClassDeclaration | MethodDeclaration | GetAccessorDeclaration | SetAccessorDeclaration | ParameterDeclaration | PropertyDeclaration, fmxScope: Famix.Class | Famix.ParametricClass | Famix.Method | Famix.Accessor | Famix.Parameter | Famix.Property): void {
|
|
597
731
|
logger.debug(`Finding Decorators:`);
|
|
598
732
|
e.getDecorators().forEach(dec => {
|
|
599
733
|
const fmxDec = processDecorator(dec, e);
|
|
@@ -622,7 +756,7 @@ function processDecorator(d: Decorator, e: ClassDeclaration | MethodDeclaration
|
|
|
622
756
|
* @param e A ts-morph element
|
|
623
757
|
* @param fmxScope The Famix model of the named entity
|
|
624
758
|
*/
|
|
625
|
-
function processComments(e: SourceFile | ModuleDeclaration | ClassDeclaration | InterfaceDeclaration | MethodDeclaration | ConstructorDeclaration | MethodSignature | GetAccessorDeclaration | SetAccessorDeclaration | FunctionDeclaration | FunctionExpression | ParameterDeclaration | VariableDeclaration | PropertyDeclaration | PropertySignature | Decorator | EnumDeclaration | EnumMember | TypeParameterDeclaration | VariableStatement | TypeAliasDeclaration, fmxScope: Famix.NamedEntity): void {
|
|
759
|
+
function processComments(e: SourceFile | ModuleDeclaration | ClassDeclaration | InterfaceDeclaration | MethodDeclaration | ConstructorDeclaration | MethodSignature | GetAccessorDeclaration | SetAccessorDeclaration | FunctionDeclaration | FunctionExpression | ParameterDeclaration | VariableDeclaration | PropertyDeclaration | PropertySignature | Decorator | EnumDeclaration | EnumMember | TypeParameterDeclaration | VariableStatement | TypeAliasDeclaration | ArrowFunction, fmxScope: Famix.NamedEntity): void {
|
|
626
760
|
logger.debug(`Process comments:`);
|
|
627
761
|
e.getLeadingCommentRanges().forEach(c => {
|
|
628
762
|
const fmxComment = processComment(c, fmxScope);
|
|
@@ -654,16 +788,16 @@ function processComment(c: CommentRange, fmxScope: Famix.NamedEntity): Famix.Com
|
|
|
654
788
|
* Builds a Famix model for the accesses on the parameters, variables, properties and enum members of the source files
|
|
655
789
|
* @param accessMap A map of parameters, variables, properties and enum members with their id
|
|
656
790
|
*/
|
|
657
|
-
export function processAccesses(accessMap: Map<
|
|
658
|
-
logger.debug(`
|
|
791
|
+
export function processAccesses(accessMap: Map<FamixID, AccessibleTSMorphElement>): void {
|
|
792
|
+
logger.debug(`Creating accesses:`);
|
|
659
793
|
accessMap.forEach((v, id) => {
|
|
660
|
-
logger.debug(`
|
|
661
|
-
try {
|
|
794
|
+
logger.debug(`Accesses to ${v.getName()}`);
|
|
795
|
+
// try {
|
|
662
796
|
const temp_nodes = v.findReferencesAsNodes() as Array<Identifier>;
|
|
663
797
|
temp_nodes.forEach(node => processNodeForAccesses(node, id));
|
|
664
|
-
} catch (error) {
|
|
665
|
-
|
|
666
|
-
}
|
|
798
|
+
// } catch (error) {
|
|
799
|
+
// logger.error(`> WARNING: got exception "${error}".\nContinuing...`);
|
|
800
|
+
// }
|
|
667
801
|
});
|
|
668
802
|
}
|
|
669
803
|
|
|
@@ -673,7 +807,7 @@ export function processAccesses(accessMap: Map<number, ParameterDeclaration | Va
|
|
|
673
807
|
* @param id An id of a parameter, a variable, a property or an enum member
|
|
674
808
|
*/
|
|
675
809
|
function processNodeForAccesses(n: Identifier, id: number): void {
|
|
676
|
-
try {
|
|
810
|
+
// try {
|
|
677
811
|
// sometimes node's first ancestor is a PropertyDeclaration, which is not an access
|
|
678
812
|
// see https://github.com/fuhrmanator/FamixTypeScriptImporter/issues/9
|
|
679
813
|
// check for a node whose first ancestor is a property declaration and bail?
|
|
@@ -684,11 +818,15 @@ function processNodeForAccesses(n: Identifier, id: number): void {
|
|
|
684
818
|
}
|
|
685
819
|
entityDictionary.createFamixAccess(n, id);
|
|
686
820
|
logger.debug(`processNodeForAccesses: node kind: ${n.getKindName()}, ${n.getText()}, (${n.getType().getText()})`);
|
|
687
|
-
} catch (error) {
|
|
688
|
-
|
|
689
|
-
}
|
|
821
|
+
// } catch (error) {
|
|
822
|
+
// logger.error(`> Got exception "${error}".\nScopeDeclaration invalid for "${n.getSymbol().getFullyQualifiedName()}".\nContinuing...`);
|
|
823
|
+
// }
|
|
690
824
|
}
|
|
691
825
|
|
|
826
|
+
|
|
827
|
+
// exports has name -> Declaration -- the declaration can be used to find the FamixElement
|
|
828
|
+
|
|
829
|
+
// handle `import path = require("path")` for example
|
|
692
830
|
export function processImportClausesForImportEqualsDeclarations(sourceFiles: Array<SourceFile>, exports: Array<ReadonlyMap<string, ExportedDeclarations[]>>): void {
|
|
693
831
|
logger.info(`Creating import clauses from ImportEqualsDeclarations in source files:`);
|
|
694
832
|
sourceFiles.forEach(sourceFile => {
|
|
@@ -697,44 +835,42 @@ export function processImportClausesForImportEqualsDeclarations(sourceFiles: Arr
|
|
|
697
835
|
// You've found an ImportEqualsDeclaration
|
|
698
836
|
logger.info("Declaration Name:", node.getName());
|
|
699
837
|
logger.info("Module Reference Text:", node.getModuleReference().getText());
|
|
838
|
+
// what's the name of the imported entity?
|
|
839
|
+
// const importedEntity = node.getName();
|
|
700
840
|
// create a famix import clause
|
|
701
841
|
const namedImport = node.getNameNode();
|
|
702
|
-
entityDictionary.
|
|
703
|
-
|
|
842
|
+
entityDictionary.oldCreateFamixImportClause({importDeclaration: node,
|
|
843
|
+
importerSourceFile: sourceFile,
|
|
704
844
|
moduleSpecifierFilePath: node.getModuleReference().getText(),
|
|
705
845
|
importElement: namedImport,
|
|
706
846
|
isInExports: exports.find(e => e.has(namedImport.getText())) !== undefined,
|
|
707
847
|
isDefaultExport: false});
|
|
848
|
+
// entityDictionary.createFamixImportClause(importedEntity, importingEntity);
|
|
708
849
|
}
|
|
709
850
|
});
|
|
710
851
|
}
|
|
711
852
|
);
|
|
712
|
-
|
|
713
853
|
}
|
|
714
854
|
|
|
715
855
|
/**
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
856
|
+
* Builds a Famix model for the import clauses of the source files which are modules
|
|
857
|
+
* @param modules An array of modules
|
|
858
|
+
* @param exports An array of maps of exported declarations
|
|
859
|
+
*/
|
|
720
860
|
export function processImportClausesForModules(modules: Array<SourceFile>, exports: Array<ReadonlyMap<string, ExportedDeclarations[]>>): void {
|
|
721
861
|
logger.info(`Creating import clauses from ${modules.length} modules:`);
|
|
722
862
|
modules.forEach(module => {
|
|
863
|
+
const modulePath = module.getFilePath() + module.getBaseName();
|
|
723
864
|
module.getImportDeclarations().forEach(impDecl => {
|
|
724
|
-
logger.
|
|
865
|
+
logger.info(`Importing ${impDecl.getModuleSpecifierValue()} in ${modulePath}`);
|
|
725
866
|
const path = getModulePath(impDecl);
|
|
726
867
|
|
|
727
868
|
impDecl.getNamedImports().forEach(namedImport => {
|
|
728
|
-
logger.
|
|
869
|
+
logger.info(`Importing (named) ${namedImport.getName()} from ${impDecl.getModuleSpecifierValue()} in ${modulePath}`);
|
|
729
870
|
const importedEntityName = namedImport.getName();
|
|
730
|
-
let importFoundInExports =
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
importFoundInExports = true;
|
|
734
|
-
}
|
|
735
|
-
});
|
|
736
|
-
entityDictionary.createFamixImportClause({importDeclaration: impDecl,
|
|
737
|
-
importer: module,
|
|
871
|
+
let importFoundInExports = isInExports(exports, importedEntityName);
|
|
872
|
+
entityDictionary.oldCreateFamixImportClause({importDeclaration: impDecl,
|
|
873
|
+
importerSourceFile: module,
|
|
738
874
|
moduleSpecifierFilePath: path,
|
|
739
875
|
importElement: namedImport,
|
|
740
876
|
isInExports: importFoundInExports,
|
|
@@ -743,10 +879,10 @@ export function processImportClausesForModules(modules: Array<SourceFile>, expor
|
|
|
743
879
|
|
|
744
880
|
const defaultImport = impDecl.getDefaultImport();
|
|
745
881
|
if (defaultImport !== undefined) {
|
|
746
|
-
logger.
|
|
882
|
+
logger.info(`Importing (default) ${defaultImport.getText()} from ${impDecl.getModuleSpecifierValue()} in ${modulePath}`);
|
|
747
883
|
// call with module, impDecl.getModuleSpecifierValue(), path, defaultImport, false, true
|
|
748
|
-
entityDictionary.
|
|
749
|
-
|
|
884
|
+
entityDictionary.oldCreateFamixImportClause({importDeclaration: impDecl,
|
|
885
|
+
importerSourceFile: module,
|
|
750
886
|
moduleSpecifierFilePath: path,
|
|
751
887
|
importElement: defaultImport,
|
|
752
888
|
isInExports: false,
|
|
@@ -755,9 +891,9 @@ export function processImportClausesForModules(modules: Array<SourceFile>, expor
|
|
|
755
891
|
|
|
756
892
|
const namespaceImport = impDecl.getNamespaceImport();
|
|
757
893
|
if (namespaceImport !== undefined) {
|
|
758
|
-
logger.
|
|
759
|
-
entityDictionary.
|
|
760
|
-
|
|
894
|
+
logger.info(`Importing (namespace) ${namespaceImport.getText()} from ${impDecl.getModuleSpecifierValue()} in ${modulePath}`);
|
|
895
|
+
entityDictionary.oldCreateFamixImportClause({importDeclaration: impDecl,
|
|
896
|
+
importerSourceFile: module,
|
|
761
897
|
moduleSpecifierFilePath: path,
|
|
762
898
|
importElement: namespaceImport,
|
|
763
899
|
isInExports: false,
|
|
@@ -768,11 +904,21 @@ export function processImportClausesForModules(modules: Array<SourceFile>, expor
|
|
|
768
904
|
});
|
|
769
905
|
}
|
|
770
906
|
|
|
907
|
+
function isInExports(exports: ReadonlyMap<string, ExportedDeclarations[]>[], importedEntityName: string) {
|
|
908
|
+
let importFoundInExports = false;
|
|
909
|
+
exports.forEach(e => {
|
|
910
|
+
if (e.has(importedEntityName)) {
|
|
911
|
+
importFoundInExports = true;
|
|
912
|
+
}
|
|
913
|
+
});
|
|
914
|
+
return importFoundInExports;
|
|
915
|
+
}
|
|
916
|
+
|
|
771
917
|
/**
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
918
|
+
* Builds a Famix model for the inheritances of the classes and interfaces of the source files
|
|
919
|
+
* @param classes An array of classes
|
|
920
|
+
* @param interfaces An array of interfaces
|
|
921
|
+
*/
|
|
776
922
|
export function processInheritances(classes: ClassDeclaration[], interfaces: InterfaceDeclaration[]): void {
|
|
777
923
|
logger.info(`processInheritances: Creating inheritances:`);
|
|
778
924
|
classes.forEach(cls => {
|
|
@@ -808,15 +954,17 @@ export function processInheritances(classes: ClassDeclaration[], interfaces: Int
|
|
|
808
954
|
* Builds a Famix model for the invocations of the methods and functions of the source files
|
|
809
955
|
* @param methodsAndFunctionsWithId A map of methods and functions with their id
|
|
810
956
|
*/
|
|
811
|
-
export function processInvocations(methodsAndFunctionsWithId: Map<number, MethodDeclaration | ConstructorDeclaration | GetAccessorDeclaration | SetAccessorDeclaration | FunctionDeclaration | FunctionExpression>): void {
|
|
957
|
+
export function processInvocations(methodsAndFunctionsWithId: Map<number, MethodDeclaration | ConstructorDeclaration | GetAccessorDeclaration | SetAccessorDeclaration | FunctionDeclaration | FunctionExpression | ArrowFunction>): void {
|
|
812
958
|
logger.info(`Creating invocations:`);
|
|
813
959
|
methodsAndFunctionsWithId.forEach((m, id) => {
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
960
|
+
if (!(m instanceof ArrowFunction)) {
|
|
961
|
+
logger.debug(`Invocations to ${(m instanceof MethodDeclaration || m instanceof GetAccessorDeclaration || m instanceof SetAccessorDeclaration || m instanceof FunctionDeclaration) ? m.getName() : ((m instanceof ConstructorDeclaration) ? 'constructor' : (m.getName() ? m.getName() : 'anonymous'))}`);
|
|
962
|
+
try {
|
|
963
|
+
const temp_nodes = m.findReferencesAsNodes() as Array<Identifier>;
|
|
964
|
+
temp_nodes.forEach(node => processNodeForInvocations(node, m, id));
|
|
965
|
+
} catch (error) {
|
|
966
|
+
logger.error(`> WARNING: got exception ${error}. Continuing...`);
|
|
967
|
+
}
|
|
820
968
|
}
|
|
821
969
|
});
|
|
822
970
|
}
|
|
@@ -835,4 +983,32 @@ function processNodeForInvocations(n: Identifier, m: MethodDeclaration | Constru
|
|
|
835
983
|
} catch (error) {
|
|
836
984
|
logger.error(`> WARNING: got exception ${error}. ScopeDeclaration invalid for ${n.getSymbol().getFullyQualifiedName()}. Continuing...`);
|
|
837
985
|
}
|
|
838
|
-
}
|
|
986
|
+
}
|
|
987
|
+
|
|
988
|
+
/**
|
|
989
|
+
* Builds a Famix model for the inheritances of the classes and interfaces of the source files
|
|
990
|
+
* @param classes An array of classes
|
|
991
|
+
* @param interfaces An array of interfaces
|
|
992
|
+
*/
|
|
993
|
+
export function processConcretisations(classes: ClassDeclaration[], interfaces: InterfaceDeclaration[], functions: Map<number, MethodDeclaration | ConstructorDeclaration | GetAccessorDeclaration | SetAccessorDeclaration | FunctionDeclaration | FunctionExpression | ArrowFunction>): void {
|
|
994
|
+
logger.info(`processConcretisations: Creating concretisations:`);
|
|
995
|
+
classes.forEach(cls => {
|
|
996
|
+
logger.debug(`processConcretisations: Checking class concretisation for ${cls.getName()}`);
|
|
997
|
+
entityDictionary.createFamixConcretisationClassOrInterfaceSpecialisation(cls);
|
|
998
|
+
entityDictionary.createFamixConcretisationGenericInstantiation(cls);
|
|
999
|
+
entityDictionary.createFamixConcretisationInterfaceClass(cls);
|
|
1000
|
+
entityDictionary.createFamixConcretisationTypeInstanciation(cls);
|
|
1001
|
+
|
|
1002
|
+
});
|
|
1003
|
+
interfaces.forEach(inter => {
|
|
1004
|
+
logger.debug(`processConcretisations: Checking interface concretisation for ${inter.getName()}`);
|
|
1005
|
+
entityDictionary.createFamixConcretisationTypeInstanciation(inter);
|
|
1006
|
+
entityDictionary.createFamixConcretisationClassOrInterfaceSpecialisation(inter)
|
|
1007
|
+
});
|
|
1008
|
+
functions.forEach(func => {
|
|
1009
|
+
if(func instanceof FunctionDeclaration || func instanceof MethodDeclaration ){
|
|
1010
|
+
logger.debug(`processConcretisations: Checking Method concretisation`);
|
|
1011
|
+
entityDictionary.createFamixConcretisationFunctionInstantiation(func);
|
|
1012
|
+
}
|
|
1013
|
+
})
|
|
1014
|
+
}
|