ts2famix 1.0.14 → 1.0.16
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/dist/analyze_functions/processImportClauses.js +15 -15
- package/dist/famix_functions/famix_functions.js +5 -0
- package/dist/famix_functions/famix_functions_associations.js +12 -2
- package/dist/famix_functions/famix_functions_types.js +2 -2
- package/dist/lib/famix/src/famix_repository.js +12 -0
- package/dist/lib/famix/src/model/famix/container_entity.js +1 -1
- package/dist/lib/famix/src/model/famix/import_clause.js +7 -7
- package/dist/lib/famix/src/model/famix/module.js +9 -8
- package/dist/lib/famix/src/model/famix/named_entity.js +8 -8
- package/dist/lib/famix/src/model/famix/scoping_entity.js +4 -0
- package/dist/lib/famix/src/model/famix/variable.js +1 -1
- package/package.json +6 -6
- package/src/analyze_functions/processImportClauses.ts +15 -15
- package/src/famix_functions/famix_functions.ts +7 -1
- package/src/famix_functions/famix_functions_associations.ts +12 -2
- package/src/famix_functions/famix_functions_types.ts +2 -2
- package/src/lib/famix/src/famix_repository.ts +17 -4
- package/src/lib/famix/src/model/famix/container_entity.ts +1 -1
- package/src/lib/famix/src/model/famix/import_clause.ts +8 -8
- package/src/lib/famix/src/model/famix/module.ts +10 -10
- package/src/lib/famix/src/model/famix/named_entity.ts +8 -8
- package/src/lib/famix/src/model/famix/scoping_entity.ts +3 -0
- package/src/lib/famix/src/model/famix/variable.ts +1 -1
|
@@ -19,29 +19,29 @@ class ProcessImportClauses {
|
|
|
19
19
|
*/
|
|
20
20
|
processImportClauses(modules, exports) {
|
|
21
21
|
console.info(`processImportClauses: Creating import clauses:`);
|
|
22
|
-
modules.forEach(
|
|
23
|
-
|
|
24
|
-
const path = this.getModulePath(
|
|
25
|
-
|
|
26
|
-
console.info(`processImportClauses: Importing (named) ${
|
|
27
|
-
const importedEntityName =
|
|
28
|
-
let
|
|
22
|
+
modules.forEach(module => {
|
|
23
|
+
module.getImportDeclarations().forEach(impDecl => {
|
|
24
|
+
const path = this.getModulePath(impDecl);
|
|
25
|
+
impDecl.getNamedImports().forEach(namedImport => {
|
|
26
|
+
console.info(`processImportClauses: Importing (named) ${namedImport.getName()} from ${impDecl.getModuleSpecifierValue()}`);
|
|
27
|
+
const importedEntityName = namedImport.getName();
|
|
28
|
+
let importFoundInExports = false;
|
|
29
29
|
exports.forEach(e => {
|
|
30
30
|
if (e.has(importedEntityName)) {
|
|
31
|
-
|
|
31
|
+
importFoundInExports = true;
|
|
32
32
|
}
|
|
33
33
|
});
|
|
34
|
-
this.famixFunctions.
|
|
34
|
+
this.famixFunctions.createFamixImportClause2({ importer: module, moduleSpecifier: impDecl.getModuleSpecifierValue(), moduleSpecifierFilePath: path, importElement: namedImport, isInExports: importFoundInExports, isDefaultExport: false });
|
|
35
35
|
});
|
|
36
|
-
const defaultImport =
|
|
36
|
+
const defaultImport = impDecl.getDefaultImport();
|
|
37
37
|
if (defaultImport !== undefined) {
|
|
38
|
-
console.info(`processImportClauses: Importing (default) ${defaultImport.getText()} from ${
|
|
39
|
-
this.famixFunctions.createFamixImportClause(
|
|
38
|
+
console.info(`processImportClauses: Importing (default) ${defaultImport.getText()} from ${impDecl.getModuleSpecifierValue()}`);
|
|
39
|
+
this.famixFunctions.createFamixImportClause(module, impDecl.getModuleSpecifierValue(), path, defaultImport, false, true);
|
|
40
40
|
}
|
|
41
|
-
const namespaceImport =
|
|
41
|
+
const namespaceImport = impDecl.getNamespaceImport();
|
|
42
42
|
if (namespaceImport !== undefined) {
|
|
43
|
-
console.info(`processImportClauses: Importing (namespace) ${namespaceImport.getText()} from ${
|
|
44
|
-
this.famixFunctions.createFamixImportClause(
|
|
43
|
+
console.info(`processImportClauses: Importing (namespace) ${namespaceImport.getText()} from ${impDecl.getModuleSpecifierValue()}`);
|
|
44
|
+
this.famixFunctions.createFamixImportClause(module, impDecl.getModuleSpecifierValue(), path, namespaceImport, false, false);
|
|
45
45
|
}
|
|
46
46
|
});
|
|
47
47
|
});
|
|
@@ -499,6 +499,11 @@ class FamixFunctions {
|
|
|
499
499
|
createFamixImportClause(importer, moduleSpecifier, moduleSpecifierFilePath, importElement, isInExports, isDefaultExport) {
|
|
500
500
|
this.famixFunctionsAssociations.createFamixImportClause(importer, moduleSpecifier, moduleSpecifierFilePath, importElement, isInExports, isDefaultExport);
|
|
501
501
|
}
|
|
502
|
+
// create the same function as createFamixImportClause but with a signature that has a single object parameter that has all the parameters
|
|
503
|
+
// this way we can call this function from the processImportClauses.ts file
|
|
504
|
+
createFamixImportClause2(importClause) {
|
|
505
|
+
this.famixFunctionsAssociations.createFamixImportClause(importClause.importer, importClause.moduleSpecifier, importClause.moduleSpecifierFilePath, importClause.importElement, importClause.isInExports, importClause.isDefaultExport);
|
|
506
|
+
}
|
|
502
507
|
/**
|
|
503
508
|
* Gets a Famix entity by fully qualified name
|
|
504
509
|
* @param fullyQualifiedName A fully qualified name
|
|
@@ -28,6 +28,7 @@ const ts_morph_1 = require("ts-morph");
|
|
|
28
28
|
const Famix = __importStar(require("../lib/famix/src/model/famix"));
|
|
29
29
|
const fqn_1 = require("../fqn");
|
|
30
30
|
const famix_functions_index_1 = require("./famix_functions_index");
|
|
31
|
+
const famix_1 = require("../lib/famix/src/model/famix");
|
|
31
32
|
/**
|
|
32
33
|
* This class is used to build a Famix model for the associations
|
|
33
34
|
*/
|
|
@@ -144,6 +145,8 @@ class FamixFunctionsAssociations {
|
|
|
144
145
|
* @param isDefaultExport A boolean indicating if the imported entity is a default export
|
|
145
146
|
*/
|
|
146
147
|
createFamixImportClause(importer, moduleSpecifier, moduleSpecifierFilePath, importElement, isInExports, isDefaultExport) {
|
|
148
|
+
var _a, _b;
|
|
149
|
+
console.info(`createFamixImportClause: Creating import clause:`);
|
|
147
150
|
const fmxImportClause = new Famix.ImportClause(this.famixRep);
|
|
148
151
|
let importedEntity;
|
|
149
152
|
let importedEntityName;
|
|
@@ -179,11 +182,18 @@ class FamixFunctionsAssociations {
|
|
|
179
182
|
}
|
|
180
183
|
const importerFullyQualifiedName = this.FQNFunctions.getFQN(importer);
|
|
181
184
|
const fmxImporter = this.getFamixEntityByFullyQualifiedName(importerFullyQualifiedName);
|
|
182
|
-
fmxImportClause.
|
|
185
|
+
fmxImportClause.setImportingEntity(fmxImporter);
|
|
183
186
|
fmxImportClause.setImportedEntity(importedEntity);
|
|
184
187
|
fmxImportClause.setModuleSpecifier(moduleSpecifier);
|
|
188
|
+
console.info(`createFamixImportClause: ${(_a = fmxImportClause.getImportedEntity()) === null || _a === void 0 ? void 0 : _a.getName()} (of type ${fmxImportClause.getImportedEntity() instanceof famix_1.Class ? 'Class' :
|
|
189
|
+
fmxImportClause.getImportedEntity() instanceof famix_1.Interface ? 'Interface' :
|
|
190
|
+
fmxImportClause.getImportedEntity() instanceof Function ? 'Function' :
|
|
191
|
+
fmxImportClause.getImportedEntity() instanceof famix_1.Enum ? 'Enum' :
|
|
192
|
+
fmxImportClause.getImportedEntity() instanceof famix_1.Alias ? 'Alias' :
|
|
193
|
+
fmxImportClause.getImportedEntity() instanceof famix_1.Variable ? 'Variable' :
|
|
194
|
+
'NamedEntity'}) is imported by ${(_b = fmxImportClause.getImportingEntity()) === null || _b === void 0 ? void 0 : _b.getName()}`);
|
|
185
195
|
this.famixFunctionsIndex.makeFamixIndexFileAnchor(null, fmxImportClause);
|
|
186
|
-
fmxImporter.
|
|
196
|
+
fmxImporter.addOutgoingImport(fmxImportClause);
|
|
187
197
|
}
|
|
188
198
|
/**
|
|
189
199
|
* Gets a Famix entity by id
|
|
@@ -52,14 +52,14 @@ class FamixFunctionsTypes {
|
|
|
52
52
|
let fmxType;
|
|
53
53
|
let isPrimitiveType = false;
|
|
54
54
|
let isParameterizedType = false;
|
|
55
|
-
console.info("Creating (or getting) type: " + typeName + "' of element: " + element.getText() + " of kind: " + element.getKindName());
|
|
55
|
+
console.info("Creating (or getting) type: '" + typeName + "' of element: " + element.getText() + " of kind: " + element.getKindName());
|
|
56
56
|
const typeAncestor = this.findTypeAncestor(element);
|
|
57
57
|
const ancestorFullyQualifiedName = this.FQNFunctions.getFQN(typeAncestor);
|
|
58
58
|
const ancestor = this.getFamixEntityByFullyQualifiedName(ancestorFullyQualifiedName);
|
|
59
59
|
if (!ancestor) {
|
|
60
60
|
throw new Error(`Ancestor ${ancestorFullyQualifiedName} not found.`);
|
|
61
61
|
}
|
|
62
|
-
if (typeName === "number" || typeName === "string" || typeName === "boolean" || typeName === "bigint" || typeName === "symbol" || typeName === "undefined" || typeName === "null") {
|
|
62
|
+
if (typeName === "number" || typeName === "string" || typeName === "boolean" || typeName === "bigint" || typeName === "symbol" || typeName === "undefined" || typeName === "null" || typeName === "any" || typeName === "unknown" || typeName === "never" || typeName === "void") {
|
|
63
63
|
isPrimitiveType = true;
|
|
64
64
|
}
|
|
65
65
|
if (!isPrimitiveType && typeName.includes("<") && typeName.includes(">") && !(typeName.includes("=>"))) {
|
|
@@ -12,6 +12,7 @@ class FamixRepository {
|
|
|
12
12
|
this.famixInterfaces = new Set(); // All Famix interfaces
|
|
13
13
|
this.famixNamespaces = new Set(); // All Famix namespaces
|
|
14
14
|
this.famixMethods = new Set(); // All Famix methods
|
|
15
|
+
this.famixVariables = new Set(); // All Famix variables
|
|
15
16
|
this.famixFunctions = new Set(); // All Famix functions
|
|
16
17
|
this.famixFiles = new Set(); // All Famix files
|
|
17
18
|
this.idCounter = 1; // Id counter
|
|
@@ -83,6 +84,14 @@ class FamixRepository {
|
|
|
83
84
|
_getFamixFunction(name) {
|
|
84
85
|
return Array.from(this.famixFunctions.values()).find(ns => ns.getName() === name);
|
|
85
86
|
}
|
|
87
|
+
/**
|
|
88
|
+
* Gets a Famix variable by name
|
|
89
|
+
* @param name A variable name
|
|
90
|
+
* @returns The Famix variable corresponding to the name or undefined if it doesn't exist
|
|
91
|
+
*/
|
|
92
|
+
_getFamixVariable(name) {
|
|
93
|
+
return Array.from(this.famixVariables.values()).find(v => v.getName() === name);
|
|
94
|
+
}
|
|
86
95
|
/**
|
|
87
96
|
* Gets a Famix namespace by name
|
|
88
97
|
* @param name A namespace name
|
|
@@ -158,6 +167,9 @@ class FamixRepository {
|
|
|
158
167
|
else if (element instanceof famix_1.Namespace) {
|
|
159
168
|
this.famixNamespaces.add(element);
|
|
160
169
|
}
|
|
170
|
+
else if (element instanceof famix_1.Variable) {
|
|
171
|
+
this.famixVariables.add(element);
|
|
172
|
+
}
|
|
161
173
|
else if (element instanceof famix_1.Method) {
|
|
162
174
|
this.famixMethods.add(element);
|
|
163
175
|
}
|
|
@@ -109,7 +109,7 @@ class ContainerEntity extends named_entity_1.NamedEntity {
|
|
|
109
109
|
}
|
|
110
110
|
addPropertiesToExporter(exporter) {
|
|
111
111
|
super.addPropertiesToExporter(exporter);
|
|
112
|
-
exporter.addProperty("
|
|
112
|
+
exporter.addProperty("parentBehaviouralEntity", this.getParentContainerEntity());
|
|
113
113
|
exporter.addProperty("childrenContainerEntities", this.getChildrenContainerEntities());
|
|
114
114
|
exporter.addProperty("cyclomaticComplexity", this.getCyclomaticComplexity());
|
|
115
115
|
exporter.addProperty("numberOfStatements", this.getNumberOfStatements());
|
|
@@ -4,19 +4,19 @@ exports.ImportClause = void 0;
|
|
|
4
4
|
const famix_JSON_exporter_1 = require("../../famix_JSON_exporter");
|
|
5
5
|
const association_1 = require("./association");
|
|
6
6
|
class ImportClause extends association_1.Association {
|
|
7
|
-
|
|
8
|
-
return this.
|
|
7
|
+
getImportingEntity() {
|
|
8
|
+
return this.importingEntity;
|
|
9
9
|
}
|
|
10
|
-
|
|
11
|
-
this.
|
|
12
|
-
importer.
|
|
10
|
+
setImportingEntity(importer) {
|
|
11
|
+
this.importingEntity = importer;
|
|
12
|
+
importer.addOutgoingImport(this); // opposite
|
|
13
13
|
}
|
|
14
14
|
getImportedEntity() {
|
|
15
15
|
return this.importedEntity;
|
|
16
16
|
}
|
|
17
17
|
setImportedEntity(importedEntity) {
|
|
18
18
|
this.importedEntity = importedEntity;
|
|
19
|
-
importedEntity.
|
|
19
|
+
importedEntity.addIncomingImport(this); // incomingImports in Famix TImportable/TImport
|
|
20
20
|
}
|
|
21
21
|
getModuleSpecifier() {
|
|
22
22
|
return this.moduleSpecifier;
|
|
@@ -31,7 +31,7 @@ class ImportClause extends association_1.Association {
|
|
|
31
31
|
}
|
|
32
32
|
addPropertiesToExporter(exporter) {
|
|
33
33
|
super.addPropertiesToExporter(exporter);
|
|
34
|
-
exporter.addProperty("
|
|
34
|
+
exporter.addProperty("importingEntity", this.getImportingEntity());
|
|
35
35
|
exporter.addProperty("importedEntity", this.getImportedEntity());
|
|
36
36
|
exporter.addProperty("moduleSpecifier", this.getModuleSpecifier());
|
|
37
37
|
}
|
|
@@ -6,15 +6,16 @@ const script_entity_1 = require("./script_entity");
|
|
|
6
6
|
class Module extends script_entity_1.ScriptEntity {
|
|
7
7
|
constructor() {
|
|
8
8
|
super(...arguments);
|
|
9
|
-
|
|
9
|
+
// incomingImports are in NamedEntity
|
|
10
|
+
this.outgoingImports = new Set();
|
|
10
11
|
}
|
|
11
|
-
|
|
12
|
-
return this.
|
|
12
|
+
getOutgoingImports() {
|
|
13
|
+
return this.outgoingImports;
|
|
13
14
|
}
|
|
14
|
-
|
|
15
|
-
if (!this.
|
|
16
|
-
this.
|
|
17
|
-
importClause.
|
|
15
|
+
addOutgoingImport(importClause) {
|
|
16
|
+
if (!this.outgoingImports.has(importClause)) {
|
|
17
|
+
this.outgoingImports.add(importClause);
|
|
18
|
+
importClause.setImportingEntity(this); // opposite
|
|
18
19
|
}
|
|
19
20
|
}
|
|
20
21
|
getJSON() {
|
|
@@ -24,7 +25,7 @@ class Module extends script_entity_1.ScriptEntity {
|
|
|
24
25
|
}
|
|
25
26
|
addPropertiesToExporter(exporter) {
|
|
26
27
|
super.addPropertiesToExporter(exporter);
|
|
27
|
-
exporter.addProperty("
|
|
28
|
+
exporter.addProperty("outgoingImports", this.getOutgoingImports());
|
|
28
29
|
}
|
|
29
30
|
}
|
|
30
31
|
exports.Module = Module;
|
|
@@ -7,7 +7,7 @@ class NamedEntity extends sourced_entity_1.SourcedEntity {
|
|
|
7
7
|
constructor() {
|
|
8
8
|
super(...arguments);
|
|
9
9
|
this.receivedInvocations = new Set();
|
|
10
|
-
this.
|
|
10
|
+
this.incomingImports = new Set();
|
|
11
11
|
this.aliases = new Set();
|
|
12
12
|
this.decorators = new Set();
|
|
13
13
|
}
|
|
@@ -26,13 +26,13 @@ class NamedEntity extends sourced_entity_1.SourcedEntity {
|
|
|
26
26
|
receivedInvocation.setReceiver(this);
|
|
27
27
|
}
|
|
28
28
|
}
|
|
29
|
-
|
|
30
|
-
return this.
|
|
29
|
+
getIncomingImports() {
|
|
30
|
+
return this.incomingImports;
|
|
31
31
|
}
|
|
32
|
-
|
|
33
|
-
if (!this.
|
|
34
|
-
this.
|
|
35
|
-
anImport.setImportedEntity(this);
|
|
32
|
+
addIncomingImport(anImport) {
|
|
33
|
+
if (!this.incomingImports.has(anImport)) {
|
|
34
|
+
this.incomingImports.add(anImport);
|
|
35
|
+
anImport.setImportedEntity(this); // opposite
|
|
36
36
|
}
|
|
37
37
|
}
|
|
38
38
|
getName() {
|
|
@@ -68,7 +68,7 @@ class NamedEntity extends sourced_entity_1.SourcedEntity {
|
|
|
68
68
|
super.addPropertiesToExporter(exporter);
|
|
69
69
|
exporter.addProperty("fullyQualifiedName", this.getFullyQualifiedName());
|
|
70
70
|
exporter.addProperty("receivedInvocations", this.getReceivedInvocations());
|
|
71
|
-
exporter.addProperty("
|
|
71
|
+
exporter.addProperty("incomingImports", this.getIncomingImports());
|
|
72
72
|
exporter.addProperty("name", this.getName());
|
|
73
73
|
exporter.addProperty("aliases", this.getAliases());
|
|
74
74
|
exporter.addProperty("decorators", this.getDecorators());
|
|
@@ -13,9 +13,13 @@ class ScopingEntity extends container_entity_1.ContainerEntity {
|
|
|
13
13
|
}
|
|
14
14
|
addNamespace(childNamespace) {
|
|
15
15
|
if (!this.childrenNamespaces.has(childNamespace)) {
|
|
16
|
+
console.info("Adding namespace " + childNamespace.getName() + " to " + this.getName());
|
|
16
17
|
this.childrenNamespaces.add(childNamespace);
|
|
17
18
|
childNamespace.setParentScope(this);
|
|
18
19
|
}
|
|
20
|
+
else {
|
|
21
|
+
console.info("Namespace " + childNamespace.getName() + " already added to " + this.getName());
|
|
22
|
+
}
|
|
19
23
|
}
|
|
20
24
|
getJSON() {
|
|
21
25
|
const mse = new famix_JSON_exporter_1.FamixJSONExporter("ScopingEntity", this);
|
|
@@ -17,7 +17,7 @@ class Variable extends structural_entity_1.StructuralEntity {
|
|
|
17
17
|
}
|
|
18
18
|
addPropertiesToExporter(exporter) {
|
|
19
19
|
super.addPropertiesToExporter(exporter);
|
|
20
|
-
exporter.addProperty("
|
|
20
|
+
exporter.addProperty("parentBehaviouralEntity", this.getParentContainerEntity());
|
|
21
21
|
}
|
|
22
22
|
}
|
|
23
23
|
exports.Variable = Variable;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ts2famix",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.16",
|
|
4
4
|
"description": "A TypeScript to JSON importer for Moose 10.",
|
|
5
5
|
"main": "dist/ts2famix-cli.js",
|
|
6
6
|
"scripts": {
|
|
@@ -26,13 +26,13 @@
|
|
|
26
26
|
},
|
|
27
27
|
"license": "MIT",
|
|
28
28
|
"devDependencies": {
|
|
29
|
-
"@types/jest": "^29.5.
|
|
30
|
-
"@types/node": "^20.6.
|
|
29
|
+
"@types/jest": "^29.5.5",
|
|
30
|
+
"@types/node": "^20.6.3",
|
|
31
31
|
"@types/yargs": "^17.0.24",
|
|
32
|
-
"@typescript-eslint/eslint-plugin": "^6.
|
|
33
|
-
"@typescript-eslint/parser": "^6.
|
|
32
|
+
"@typescript-eslint/eslint-plugin": "^6.7.2",
|
|
33
|
+
"@typescript-eslint/parser": "^6.7.2",
|
|
34
34
|
"eslint": "^8.49.0",
|
|
35
|
-
"jest": "^29.
|
|
35
|
+
"jest": "^29.7.0",
|
|
36
36
|
"tplant": "^3.1.2",
|
|
37
37
|
"ts-jest": "^29.1.1",
|
|
38
38
|
"ts-node": "^10.9.1",
|
|
@@ -23,32 +23,32 @@ export class ProcessImportClauses {
|
|
|
23
23
|
*/
|
|
24
24
|
public processImportClauses(modules: Array<SourceFile>, exports: Array<ReadonlyMap<string, ExportedDeclarations[]>>): void {
|
|
25
25
|
console.info(`processImportClauses: Creating import clauses:`);
|
|
26
|
-
modules.forEach(
|
|
27
|
-
|
|
28
|
-
const path = this.getModulePath(
|
|
26
|
+
modules.forEach(module => {
|
|
27
|
+
module.getImportDeclarations().forEach(impDecl => {
|
|
28
|
+
const path = this.getModulePath(impDecl);
|
|
29
29
|
|
|
30
|
-
|
|
31
|
-
console.info(`processImportClauses: Importing (named) ${
|
|
32
|
-
const importedEntityName =
|
|
33
|
-
let
|
|
30
|
+
impDecl.getNamedImports().forEach(namedImport => {
|
|
31
|
+
console.info(`processImportClauses: Importing (named) ${namedImport.getName()} from ${impDecl.getModuleSpecifierValue()}`);
|
|
32
|
+
const importedEntityName = namedImport.getName();
|
|
33
|
+
let importFoundInExports = false;
|
|
34
34
|
exports.forEach(e => {
|
|
35
35
|
if (e.has(importedEntityName)) {
|
|
36
|
-
|
|
36
|
+
importFoundInExports = true;
|
|
37
37
|
}
|
|
38
38
|
});
|
|
39
|
-
this.famixFunctions.
|
|
39
|
+
this.famixFunctions.createFamixImportClause2({importer: module, moduleSpecifier: impDecl.getModuleSpecifierValue(), moduleSpecifierFilePath: path, importElement: namedImport, isInExports: importFoundInExports, isDefaultExport: false});
|
|
40
40
|
});
|
|
41
41
|
|
|
42
|
-
const defaultImport =
|
|
42
|
+
const defaultImport = impDecl.getDefaultImport();
|
|
43
43
|
if (defaultImport !== undefined) {
|
|
44
|
-
console.info(`processImportClauses: Importing (default) ${defaultImport.getText()} from ${
|
|
45
|
-
this.famixFunctions.createFamixImportClause(
|
|
44
|
+
console.info(`processImportClauses: Importing (default) ${defaultImport.getText()} from ${impDecl.getModuleSpecifierValue()}`);
|
|
45
|
+
this.famixFunctions.createFamixImportClause(module, impDecl.getModuleSpecifierValue(), path, defaultImport, false, true);
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
-
const namespaceImport =
|
|
48
|
+
const namespaceImport = impDecl.getNamespaceImport();
|
|
49
49
|
if (namespaceImport !== undefined) {
|
|
50
|
-
console.info(`processImportClauses: Importing (namespace) ${namespaceImport.getText()} from ${
|
|
51
|
-
this.famixFunctions.createFamixImportClause(
|
|
50
|
+
console.info(`processImportClauses: Importing (namespace) ${namespaceImport.getText()} from ${impDecl.getModuleSpecifierValue()}`);
|
|
51
|
+
this.famixFunctions.createFamixImportClause(module, impDecl.getModuleSpecifierValue(), path, namespaceImport, false, false);
|
|
52
52
|
}
|
|
53
53
|
});
|
|
54
54
|
});
|
|
@@ -533,11 +533,17 @@ export class FamixFunctions {
|
|
|
533
533
|
* @param importElement The imported entity
|
|
534
534
|
* @param isInExports A boolean indicating if the imported entity is in the exports
|
|
535
535
|
* @param isDefaultExport A boolean indicating if the imported entity is a default export
|
|
536
|
-
*/
|
|
536
|
+
*/
|
|
537
537
|
public createFamixImportClause(importer: SourceFile, moduleSpecifier: string, moduleSpecifierFilePath: string, importElement: ImportSpecifier | Identifier, isInExports: boolean, isDefaultExport: boolean): void {
|
|
538
538
|
this.famixFunctionsAssociations.createFamixImportClause(importer, moduleSpecifier, moduleSpecifierFilePath, importElement, isInExports, isDefaultExport);
|
|
539
539
|
}
|
|
540
540
|
|
|
541
|
+
// create the same function as createFamixImportClause but with a signature that has a single object parameter that has all the parameters
|
|
542
|
+
// this way we can call this function from the processImportClauses.ts file
|
|
543
|
+
public createFamixImportClause2(importClause: {importer: SourceFile, moduleSpecifier: string, moduleSpecifierFilePath: string, importElement: ImportSpecifier | Identifier, isInExports: boolean, isDefaultExport: boolean}): void {
|
|
544
|
+
this.famixFunctionsAssociations.createFamixImportClause(importClause.importer, importClause.moduleSpecifier, importClause.moduleSpecifierFilePath, importClause.importElement, importClause.isInExports, importClause.isDefaultExport);
|
|
545
|
+
}
|
|
546
|
+
|
|
541
547
|
/**
|
|
542
548
|
* Gets a Famix entity by fully qualified name
|
|
543
549
|
* @param fullyQualifiedName A fully qualified name
|
|
@@ -3,6 +3,7 @@ import * as Famix from "../lib/famix/src/model/famix";
|
|
|
3
3
|
import { FamixRepository } from "../lib/famix/src/famix_repository";
|
|
4
4
|
import { FQNFunctions } from "../fqn";
|
|
5
5
|
import { FamixFunctionsIndex } from "./famix_functions_index";
|
|
6
|
+
import { Alias, Class, Enum, Interface, Variable } from "../lib/famix/src/model/famix";
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
9
|
* This class is used to build a Famix model for the associations
|
|
@@ -140,6 +141,7 @@ export class FamixFunctionsAssociations {
|
|
|
140
141
|
* @param isDefaultExport A boolean indicating if the imported entity is a default export
|
|
141
142
|
*/
|
|
142
143
|
public createFamixImportClause(importer: SourceFile, moduleSpecifier: string, moduleSpecifierFilePath: string, importElement: ImportSpecifier | Identifier, isInExports: boolean, isDefaultExport: boolean): void {
|
|
144
|
+
console.info(`createFamixImportClause: Creating import clause:`);
|
|
143
145
|
const fmxImportClause = new Famix.ImportClause(this.famixRep);
|
|
144
146
|
|
|
145
147
|
let importedEntity: Famix.NamedEntity;
|
|
@@ -177,13 +179,21 @@ export class FamixFunctionsAssociations {
|
|
|
177
179
|
|
|
178
180
|
const importerFullyQualifiedName = this.FQNFunctions.getFQN(importer);
|
|
179
181
|
const fmxImporter = this.getFamixEntityByFullyQualifiedName(importerFullyQualifiedName) as Famix.Module;
|
|
180
|
-
fmxImportClause.
|
|
182
|
+
fmxImportClause.setImportingEntity(fmxImporter);
|
|
181
183
|
fmxImportClause.setImportedEntity(importedEntity);
|
|
182
184
|
fmxImportClause.setModuleSpecifier(moduleSpecifier);
|
|
183
185
|
|
|
186
|
+
console.info(`createFamixImportClause: ${fmxImportClause.getImportedEntity()?.getName()} (of type ${fmxImportClause.getImportedEntity() instanceof Class ? 'Class' :
|
|
187
|
+
fmxImportClause.getImportedEntity() instanceof Interface ? 'Interface' :
|
|
188
|
+
fmxImportClause.getImportedEntity() instanceof Function ? 'Function' :
|
|
189
|
+
fmxImportClause.getImportedEntity() instanceof Enum ? 'Enum' :
|
|
190
|
+
fmxImportClause.getImportedEntity() instanceof Alias ? 'Alias' :
|
|
191
|
+
fmxImportClause.getImportedEntity() instanceof Variable ? 'Variable' :
|
|
192
|
+
'NamedEntity'}) is imported by ${fmxImportClause.getImportingEntity()?.getName()}`);
|
|
193
|
+
|
|
184
194
|
this.famixFunctionsIndex.makeFamixIndexFileAnchor(null, fmxImportClause);
|
|
185
195
|
|
|
186
|
-
fmxImporter.
|
|
196
|
+
fmxImporter.addOutgoingImport(fmxImportClause);
|
|
187
197
|
}
|
|
188
198
|
|
|
189
199
|
/**
|
|
@@ -34,7 +34,7 @@ export class FamixFunctionsTypes {
|
|
|
34
34
|
let isPrimitiveType = false;
|
|
35
35
|
let isParameterizedType = false;
|
|
36
36
|
|
|
37
|
-
console.info("Creating (or getting) type: " + typeName + "' of element: " + element.getText() + " of kind: " + element.getKindName());
|
|
37
|
+
console.info("Creating (or getting) type: '" + typeName + "' of element: " + element.getText() + " of kind: " + element.getKindName());
|
|
38
38
|
|
|
39
39
|
const typeAncestor = this.findTypeAncestor(element);
|
|
40
40
|
const ancestorFullyQualifiedName = this.FQNFunctions.getFQN(typeAncestor);
|
|
@@ -43,7 +43,7 @@ export class FamixFunctionsTypes {
|
|
|
43
43
|
throw new Error(`Ancestor ${ancestorFullyQualifiedName} not found.`);
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
-
if (typeName === "number" || typeName === "string" || typeName === "boolean" || typeName === "bigint" || typeName === "symbol" || typeName === "undefined" || typeName === "null") {
|
|
46
|
+
if (typeName === "number" || typeName === "string" || typeName === "boolean" || typeName === "bigint" || typeName === "symbol" || typeName === "undefined" || typeName === "null" || typeName === "any" || typeName === "unknown" || typeName === "never" || typeName === "void") {
|
|
47
47
|
isPrimitiveType = true;
|
|
48
48
|
}
|
|
49
49
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { FamixBaseElement } from "./famix_base_element";
|
|
2
|
-
import { Class, Interface, Namespace, Method, Function, Type, NamedEntity, ScriptEntity, Module } from "./model/famix";
|
|
2
|
+
import { Class, Interface, Namespace, Variable, Method, Function as FamixFunctionEntity, Type, NamedEntity, ScriptEntity, Module } from "./model/famix";
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* This class is used to store all Famix elements
|
|
@@ -11,7 +11,8 @@ export class FamixRepository {
|
|
|
11
11
|
private famixInterfaces = new Set<Interface>(); // All Famix interfaces
|
|
12
12
|
private famixNamespaces = new Set<Namespace>(); // All Famix namespaces
|
|
13
13
|
private famixMethods = new Set<Method>(); // All Famix methods
|
|
14
|
-
private
|
|
14
|
+
private famixVariables = new Set<Variable>(); // All Famix variables
|
|
15
|
+
private famixFunctions = new Set<FamixFunctionEntity>(); // All Famix functions
|
|
15
16
|
private famixFiles = new Set<ScriptEntity | Module>(); // All Famix files
|
|
16
17
|
private idCounter = 1; // Id counter
|
|
17
18
|
|
|
@@ -88,10 +89,20 @@ export class FamixRepository {
|
|
|
88
89
|
* @param name A function name
|
|
89
90
|
* @returns The Famix function corresponding to the name or undefined if it doesn't exist
|
|
90
91
|
*/
|
|
91
|
-
public _getFamixFunction(name: string):
|
|
92
|
+
public _getFamixFunction(name: string): FamixFunctionEntity | undefined {
|
|
92
93
|
return Array.from(this.famixFunctions.values()).find(ns => ns.getName() === name);
|
|
93
94
|
}
|
|
94
95
|
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Gets a Famix variable by name
|
|
99
|
+
* @param name A variable name
|
|
100
|
+
* @returns The Famix variable corresponding to the name or undefined if it doesn't exist
|
|
101
|
+
*/
|
|
102
|
+
public _getFamixVariable(name: string): Variable | undefined {
|
|
103
|
+
return Array.from(this.famixVariables.values()).find(v => v.getName() === name);
|
|
104
|
+
}
|
|
105
|
+
|
|
95
106
|
/**
|
|
96
107
|
* Gets a Famix namespace by name
|
|
97
108
|
* @param name A namespace name
|
|
@@ -172,9 +183,11 @@ export class FamixRepository {
|
|
|
172
183
|
this.famixInterfaces.add(element);
|
|
173
184
|
} else if (element instanceof Namespace) {
|
|
174
185
|
this.famixNamespaces.add(element);
|
|
186
|
+
} else if (element instanceof Variable) {
|
|
187
|
+
this.famixVariables.add(element);
|
|
175
188
|
} else if (element instanceof Method) {
|
|
176
189
|
this.famixMethods.add(element);
|
|
177
|
-
} else if (element instanceof
|
|
190
|
+
} else if (element instanceof FamixFunctionEntity) {
|
|
178
191
|
this.famixFunctions.add(element);
|
|
179
192
|
} else if (element instanceof ScriptEntity || element instanceof Module) {
|
|
180
193
|
this.famixFiles.add(element);
|
|
@@ -150,7 +150,7 @@ export class ContainerEntity extends NamedEntity {
|
|
|
150
150
|
|
|
151
151
|
public addPropertiesToExporter(exporter: FamixJSONExporter): void {
|
|
152
152
|
super.addPropertiesToExporter(exporter);
|
|
153
|
-
exporter.addProperty("
|
|
153
|
+
exporter.addProperty("parentBehaviouralEntity", this.getParentContainerEntity());
|
|
154
154
|
exporter.addProperty("childrenContainerEntities", this.getChildrenContainerEntities());
|
|
155
155
|
exporter.addProperty("cyclomaticComplexity", this.getCyclomaticComplexity());
|
|
156
156
|
exporter.addProperty("numberOfStatements", this.getNumberOfStatements());
|
|
@@ -5,15 +5,15 @@ import { NamedEntity } from "./named_entity";
|
|
|
5
5
|
|
|
6
6
|
export class ImportClause extends Association {
|
|
7
7
|
|
|
8
|
-
private
|
|
8
|
+
private importingEntity: Module;
|
|
9
9
|
|
|
10
|
-
public
|
|
11
|
-
return this.
|
|
10
|
+
public getImportingEntity(): Module {
|
|
11
|
+
return this.importingEntity;
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
-
public
|
|
15
|
-
this.
|
|
16
|
-
importer.
|
|
14
|
+
public setImportingEntity(importer: Module): void {
|
|
15
|
+
this.importingEntity = importer;
|
|
16
|
+
importer.addOutgoingImport(this); // opposite
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
private importedEntity: NamedEntity;
|
|
@@ -24,7 +24,7 @@ export class ImportClause extends Association {
|
|
|
24
24
|
|
|
25
25
|
public setImportedEntity(importedEntity: NamedEntity): void {
|
|
26
26
|
this.importedEntity = importedEntity;
|
|
27
|
-
importedEntity.
|
|
27
|
+
importedEntity.addIncomingImport(this); // incomingImports in Famix TImportable/TImport
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
private moduleSpecifier: string;
|
|
@@ -46,7 +46,7 @@ export class ImportClause extends Association {
|
|
|
46
46
|
|
|
47
47
|
public addPropertiesToExporter(exporter: FamixJSONExporter): void {
|
|
48
48
|
super.addPropertiesToExporter(exporter);
|
|
49
|
-
exporter.addProperty("
|
|
49
|
+
exporter.addProperty("importingEntity", this.getImportingEntity());
|
|
50
50
|
exporter.addProperty("importedEntity", this.getImportedEntity());
|
|
51
51
|
exporter.addProperty("moduleSpecifier", this.getModuleSpecifier());
|
|
52
52
|
}
|
|
@@ -4,20 +4,20 @@ import { ImportClause } from "./import_clause";
|
|
|
4
4
|
|
|
5
5
|
export class Module extends ScriptEntity {
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
// incomingImports are in NamedEntity
|
|
8
|
+
private outgoingImports: Set<ImportClause> = new Set();
|
|
9
|
+
|
|
10
|
+
getOutgoingImports() {
|
|
11
|
+
return this.outgoingImports;
|
|
11
12
|
}
|
|
12
13
|
|
|
13
|
-
|
|
14
|
-
if (!this.
|
|
15
|
-
this.
|
|
16
|
-
importClause.
|
|
14
|
+
addOutgoingImport(importClause: ImportClause) {
|
|
15
|
+
if (!this.outgoingImports.has(importClause)) {
|
|
16
|
+
this.outgoingImports.add(importClause);
|
|
17
|
+
importClause.setImportingEntity(this); // opposite
|
|
17
18
|
}
|
|
18
19
|
}
|
|
19
20
|
|
|
20
|
-
|
|
21
21
|
public getJSON(): string {
|
|
22
22
|
const mse: FamixJSONExporter = new FamixJSONExporter("Module", this);
|
|
23
23
|
this.addPropertiesToExporter(mse);
|
|
@@ -26,6 +26,6 @@ export class Module extends ScriptEntity {
|
|
|
26
26
|
|
|
27
27
|
public addPropertiesToExporter(exporter: FamixJSONExporter): void {
|
|
28
28
|
super.addPropertiesToExporter(exporter);
|
|
29
|
-
exporter.addProperty("
|
|
29
|
+
exporter.addProperty("outgoingImports", this.getOutgoingImports());
|
|
30
30
|
}
|
|
31
31
|
}
|
|
@@ -30,16 +30,16 @@ export class NamedEntity extends SourcedEntity {
|
|
|
30
30
|
}
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
private
|
|
33
|
+
private incomingImports: Set<ImportClause> = new Set();
|
|
34
34
|
|
|
35
|
-
public
|
|
36
|
-
return this.
|
|
35
|
+
public getIncomingImports(): Set<ImportClause> {
|
|
36
|
+
return this.incomingImports;
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
-
public
|
|
40
|
-
if (!this.
|
|
41
|
-
this.
|
|
42
|
-
anImport.setImportedEntity(this);
|
|
39
|
+
public addIncomingImport(anImport: ImportClause): void {
|
|
40
|
+
if (!this.incomingImports.has(anImport)) {
|
|
41
|
+
this.incomingImports.add(anImport);
|
|
42
|
+
anImport.setImportedEntity(this); // opposite
|
|
43
43
|
}
|
|
44
44
|
}
|
|
45
45
|
|
|
@@ -90,7 +90,7 @@ export class NamedEntity extends SourcedEntity {
|
|
|
90
90
|
super.addPropertiesToExporter(exporter);
|
|
91
91
|
exporter.addProperty("fullyQualifiedName", this.getFullyQualifiedName());
|
|
92
92
|
exporter.addProperty("receivedInvocations", this.getReceivedInvocations());
|
|
93
|
-
exporter.addProperty("
|
|
93
|
+
exporter.addProperty("incomingImports", this.getIncomingImports());
|
|
94
94
|
exporter.addProperty("name", this.getName());
|
|
95
95
|
exporter.addProperty("aliases", this.getAliases());
|
|
96
96
|
exporter.addProperty("decorators", this.getDecorators());
|
|
@@ -12,8 +12,11 @@ export class ScopingEntity extends ContainerEntity {
|
|
|
12
12
|
|
|
13
13
|
public addNamespace(childNamespace: Namespace): void {
|
|
14
14
|
if (!this.childrenNamespaces.has(childNamespace)) {
|
|
15
|
+
console.info("Adding namespace " + childNamespace.getName() + " to " + this.getName());
|
|
15
16
|
this.childrenNamespaces.add(childNamespace);
|
|
16
17
|
childNamespace.setParentScope(this);
|
|
18
|
+
} else {
|
|
19
|
+
console.info("Namespace " + childNamespace.getName() + " already added to " + this.getName());
|
|
17
20
|
}
|
|
18
21
|
}
|
|
19
22
|
|
|
@@ -23,6 +23,6 @@ export class Variable extends StructuralEntity {
|
|
|
23
23
|
|
|
24
24
|
public addPropertiesToExporter(exporter: FamixJSONExporter): void {
|
|
25
25
|
super.addPropertiesToExporter(exporter);
|
|
26
|
-
exporter.addProperty("
|
|
26
|
+
exporter.addProperty("parentBehaviouralEntity", this.getParentContainerEntity());
|
|
27
27
|
}
|
|
28
28
|
}
|