ts2famix 1.3.1 → 1.4.1
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.js +38 -27
- package/dist/analyze_functions/process_functions.js +723 -0
- package/dist/famix_functions/EntityDictionary.js +798 -0
- package/dist/famix_functions/helpers_creation.js +97 -0
- package/dist/fqn.js +106 -95
- package/dist/lib/famix/src/famix_base_element.js +8 -4
- package/dist/lib/famix/src/famix_repository.js +32 -15
- package/dist/lib/ts-complex/cyclomatic-service.js +2 -3
- package/doc-uml/metamodel-full.svg +1 -0
- package/doc-uml/metamodel.svg +1 -0
- package/package.json +1 -1
- package/plantuml.jar +0 -0
- package/src/analyze.ts +48 -29
- package/src/analyze_functions/process_functions.ts +838 -0
- package/src/famix_functions/EntityDictionary.ts +915 -0
- package/src/famix_functions/helpers_creation.ts +77 -0
- package/src/fqn.ts +101 -92
- package/src/lib/famix/src/famix_base_element.ts +9 -5
- package/src/lib/famix/src/famix_repository.ts +45 -23
- package/src/lib/ts-complex/cyclomatic-service.ts +2 -4
- package/src/ts2famix-cli.ts +1 -0
- package/dist/analyze_functions/processAccesses.js +0 -56
- package/dist/analyze_functions/processFiles.js +0 -554
- package/dist/analyze_functions/processImportClauses.js +0 -88
- package/dist/analyze_functions/processInheritances.js +0 -74
- package/dist/analyze_functions/processInvocations.js +0 -50
- package/dist/famix_functions/famix_functions.js +0 -523
- package/dist/famix_functions/famix_functions_associations.js +0 -238
- package/dist/famix_functions/famix_functions_index.js +0 -135
- package/dist/famix_functions/famix_functions_types.js +0 -115
- package/docs/.gitkeep +0 -0
- package/src/analyze_functions/processAccesses.ts +0 -58
- package/src/analyze_functions/processFiles.ts +0 -667
- package/src/analyze_functions/processImportClauses.ts +0 -95
- package/src/analyze_functions/processInheritances.ts +0 -85
- package/src/analyze_functions/processInvocations.ts +0 -52
- package/src/famix_functions/famix_functions.ts +0 -562
- package/src/famix_functions/famix_functions_associations.ts +0 -242
- package/src/famix_functions/famix_functions_index.ts +0 -120
- package/src/famix_functions/famix_functions_types.ts +0 -106
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import * as Famix from "../lib/famix/src/model/famix";
|
|
2
|
+
import { logger } from "../analyze";
|
|
3
|
+
import { ConstructorDeclaration, Identifier, FunctionDeclaration, MethodDeclaration, MethodSignature, PropertyDeclaration, PropertySignature, VariableDeclaration, ParameterDeclaration, GetAccessorDeclaration, SetAccessorDeclaration, EnumMember, TypeAliasDeclaration, Node, SyntaxKind, FunctionExpression } from "ts-morph";
|
|
4
|
+
|
|
5
|
+
interface SearchParameters {
|
|
6
|
+
searchArray: string[];
|
|
7
|
+
targetArray: string[];
|
|
8
|
+
start?: number;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* This function works like indexOf, but it works with arrays of grapheme clusters.
|
|
13
|
+
* @param targetArray
|
|
14
|
+
*/
|
|
15
|
+
export function indexOfSplitArray(params: SearchParameters): number {
|
|
16
|
+
const {searchArray, targetArray, start = 0} = params;
|
|
17
|
+
for (let i = start; i <= searchArray.length - targetArray.length; i++) {
|
|
18
|
+
let found = true;
|
|
19
|
+
for (let j = 0; j < targetArray.length; j++) {
|
|
20
|
+
if (searchArray[i + j] !== targetArray[j]) {
|
|
21
|
+
found = false;
|
|
22
|
+
break;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
if (found) {
|
|
26
|
+
return i; // Return the index where the target array was found
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return -1; // Return -1 if the target array was not found in the search array
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function getSubTypeName(fmxNamedEntity: Famix.NamedEntity) {
|
|
33
|
+
const name = fmxNamedEntity instanceof Famix.Class ? 'Class' :
|
|
34
|
+
fmxNamedEntity instanceof Famix.Interface ? 'Interface' :
|
|
35
|
+
fmxNamedEntity instanceof Famix.Function ? 'Function' :
|
|
36
|
+
fmxNamedEntity instanceof Famix.Enum ? 'Enum' :
|
|
37
|
+
fmxNamedEntity instanceof Famix.EnumValue ? 'EnumValue' :
|
|
38
|
+
fmxNamedEntity instanceof Famix.Alias ? 'Alias' :
|
|
39
|
+
fmxNamedEntity instanceof Famix.Variable ? 'Variable' :
|
|
40
|
+
fmxNamedEntity instanceof Famix.Type ? 'Type' :
|
|
41
|
+
fmxNamedEntity instanceof Famix.Method ? 'Method' :
|
|
42
|
+
fmxNamedEntity instanceof Famix.Decorator ? 'Decorator' :
|
|
43
|
+
fmxNamedEntity instanceof Famix.Accessor ? 'Accessor' :
|
|
44
|
+
fmxNamedEntity instanceof Famix.Parameter ? 'Parameter' :
|
|
45
|
+
fmxNamedEntity instanceof Famix.Property ? 'Property' :
|
|
46
|
+
'NamedEntity';
|
|
47
|
+
logger.debug(`${fmxNamedEntity.getName()} is of type ${name}`);
|
|
48
|
+
return name;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Gets the signature of a method or a function
|
|
53
|
+
* @param text A method or a function source code
|
|
54
|
+
* @returns The signature of the method or the function
|
|
55
|
+
*/
|
|
56
|
+
export function computeSignature(text: string): string {
|
|
57
|
+
const endSignatureText = text.indexOf("{");
|
|
58
|
+
return text.substring(0, endSignatureText).trim();
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Finds the ancestor of a node
|
|
63
|
+
* @param node A node
|
|
64
|
+
* @returns The ancestor of the node
|
|
65
|
+
*/
|
|
66
|
+
export function findAncestor(node: Identifier): Node {
|
|
67
|
+
return node.getAncestors().find(a => a.getKind() === SyntaxKind.MethodDeclaration || a.getKind() === SyntaxKind.Constructor || a.getKind() === SyntaxKind.FunctionDeclaration || a.getKind() === SyntaxKind.FunctionExpression || a.getKind() === SyntaxKind.ModuleDeclaration || a.getKind() === SyntaxKind.SourceFile || a.getKindName() === "GetAccessor" || a.getKindName() === "SetAccessor" || a.getKind() === SyntaxKind.ClassDeclaration);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Finds the ancestor of a ts-morph element
|
|
72
|
+
* @param element A ts-morph element
|
|
73
|
+
* @returns The ancestor of the ts-morph element
|
|
74
|
+
*/
|
|
75
|
+
export function findTypeAncestor(element: TypeAliasDeclaration | PropertyDeclaration | PropertySignature | MethodDeclaration | ConstructorDeclaration | MethodSignature | GetAccessorDeclaration | SetAccessorDeclaration | FunctionDeclaration | FunctionExpression | ParameterDeclaration | VariableDeclaration | EnumMember): Node {
|
|
76
|
+
return element.getAncestors().find(a => a.getKind() === SyntaxKind.MethodDeclaration || a.getKind() === SyntaxKind.Constructor || a.getKind() === SyntaxKind.MethodSignature || a.getKind() === SyntaxKind.FunctionDeclaration || a.getKind() === SyntaxKind.FunctionExpression || a.getKind() === SyntaxKind.ModuleDeclaration || a.getKind() === SyntaxKind.SourceFile || a.getKindName() === "GetAccessor" || a.getKindName() === "SetAccessor" || a.getKind() === SyntaxKind.ClassDeclaration || a.getKind() === SyntaxKind.InterfaceDeclaration);
|
|
77
|
+
}
|
package/src/fqn.ts
CHANGED
|
@@ -1,127 +1,136 @@
|
|
|
1
1
|
import * as ts from "ts-morph";
|
|
2
|
+
import { entityDictionary } from "./analyze";
|
|
3
|
+
import path from "path";
|
|
2
4
|
|
|
3
5
|
/**
|
|
4
|
-
*
|
|
6
|
+
* Gets the fully qualified name of a node, if it has one
|
|
7
|
+
* @param node A node
|
|
8
|
+
* @returns The fully qualified name of the node, or undefined if it doesn't have one
|
|
5
9
|
*/
|
|
6
|
-
export
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
public getFQN(node: ts.Node): string {
|
|
14
|
-
if (node instanceof ts.SourceFile) {
|
|
15
|
-
return `"${node.getFilePath()}"`;
|
|
16
|
-
}
|
|
10
|
+
export function getFQN(node: ts.Node): string {
|
|
11
|
+
const absolutePathProject = entityDictionary.famixRep.getAbsolutePath();
|
|
12
|
+
|
|
13
|
+
if (node instanceof ts.SourceFile) {
|
|
14
|
+
return entityDictionary.convertToRelativePath(path.normalize(node.getFilePath()),
|
|
15
|
+
absolutePathProject).replace(/\\/sg, "/");
|
|
16
|
+
}
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
18
|
+
const symbol = node.getSymbol();
|
|
19
|
+
if (!symbol) {
|
|
20
|
+
return undefined;
|
|
21
|
+
}
|
|
22
22
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
23
|
+
const declarations = symbol.getDeclarations();
|
|
24
|
+
if (!declarations) {
|
|
25
|
+
return undefined;
|
|
26
|
+
}
|
|
27
27
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
28
|
+
const sourceFile = declarations[0].getSourceFile();
|
|
29
|
+
if (!sourceFile) {
|
|
30
|
+
return undefined;
|
|
31
|
+
}
|
|
32
32
|
|
|
33
|
-
|
|
34
|
-
|
|
33
|
+
const absolutePath = path.normalize(sourceFile.getFilePath());
|
|
34
|
+
const positionNodeModules = absolutePath.indexOf('node_modules');
|
|
35
|
+
let pathInProject: string = "";
|
|
35
36
|
|
|
36
|
-
|
|
37
|
+
if (positionNodeModules !== -1) {
|
|
38
|
+
const pathFromNodeModules = absolutePath.substring(positionNodeModules);
|
|
39
|
+
pathInProject = pathFromNodeModules;
|
|
40
|
+
} else {
|
|
41
|
+
pathInProject = entityDictionary.convertToRelativePath(absolutePath, absolutePathProject).replace(/\\/g, "/");
|
|
42
|
+
}
|
|
37
43
|
|
|
38
|
-
|
|
39
|
-
if (nodeName) qualifiedNameParts.push(nodeName);
|
|
44
|
+
const qualifiedNameParts: Array<string> = [];
|
|
40
45
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
const partName = this.getNameOfNode(a);
|
|
44
|
-
if (partName) qualifiedNameParts.push(partName);
|
|
45
|
-
});
|
|
46
|
+
const nodeName = this.getNameOfNode(node);
|
|
47
|
+
if (nodeName) qualifiedNameParts.push(nodeName);
|
|
46
48
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
49
|
+
const ancestors = node.getAncestors();
|
|
50
|
+
ancestors.forEach(a => {
|
|
51
|
+
const partName = this.getNameOfNode(a);
|
|
52
|
+
if (partName) qualifiedNameParts.push(partName);
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
qualifiedNameParts.pop();
|
|
56
|
+
|
|
57
|
+
if (qualifiedNameParts.length > 0) {
|
|
58
|
+
return `{${pathInProject}}.${qualifiedNameParts.reverse().join(".")}`;
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
return undefined;
|
|
53
62
|
}
|
|
63
|
+
}
|
|
54
64
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
65
|
+
/**
|
|
66
|
+
* Gets the name of a node, if it has one
|
|
67
|
+
* @param a A node
|
|
68
|
+
* @returns The name of the node, or an empty string if it doesn't have one
|
|
69
|
+
*/
|
|
70
|
+
export function getNameOfNode(a: ts.Node<ts.ts.Node>): string {
|
|
71
|
+
switch (a.getKind()) {
|
|
72
|
+
case ts.SyntaxKind.SourceFile:
|
|
73
|
+
return a.asKind(ts.SyntaxKind.SourceFile)?.getBaseName();
|
|
64
74
|
|
|
65
|
-
|
|
66
|
-
|
|
75
|
+
case ts.SyntaxKind.ModuleDeclaration:
|
|
76
|
+
return a.asKind(ts.SyntaxKind.ModuleDeclaration)?.getName();
|
|
67
77
|
|
|
68
|
-
|
|
69
|
-
|
|
78
|
+
case ts.SyntaxKind.ClassDeclaration:
|
|
79
|
+
return a.asKind(ts.SyntaxKind.ClassDeclaration)?.getName();
|
|
70
80
|
|
|
71
|
-
|
|
72
|
-
|
|
81
|
+
case ts.SyntaxKind.InterfaceDeclaration:
|
|
82
|
+
return a.asKind(ts.SyntaxKind.InterfaceDeclaration)?.getName();
|
|
73
83
|
|
|
74
|
-
|
|
75
|
-
|
|
84
|
+
case ts.SyntaxKind.PropertyDeclaration:
|
|
85
|
+
return a.asKind(ts.SyntaxKind.PropertyDeclaration)?.getName();
|
|
76
86
|
|
|
77
|
-
|
|
78
|
-
|
|
87
|
+
case ts.SyntaxKind.PropertySignature:
|
|
88
|
+
return a.asKind(ts.SyntaxKind.PropertySignature)?.getName();
|
|
79
89
|
|
|
80
|
-
|
|
81
|
-
|
|
90
|
+
case ts.SyntaxKind.MethodDeclaration:
|
|
91
|
+
return a.asKind(ts.SyntaxKind.MethodDeclaration)?.getName();
|
|
82
92
|
|
|
83
|
-
|
|
84
|
-
|
|
93
|
+
case ts.SyntaxKind.MethodSignature:
|
|
94
|
+
return a.asKind(ts.SyntaxKind.MethodSignature)?.getName();
|
|
85
95
|
|
|
86
|
-
|
|
87
|
-
|
|
96
|
+
case ts.SyntaxKind.GetAccessor:
|
|
97
|
+
return a.asKind(ts.SyntaxKind.GetAccessor)?.getName();
|
|
88
98
|
|
|
89
|
-
|
|
90
|
-
|
|
99
|
+
case ts.SyntaxKind.SetAccessor:
|
|
100
|
+
return a.asKind(ts.SyntaxKind.SetAccessor)?.getName();
|
|
91
101
|
|
|
92
|
-
|
|
93
|
-
|
|
102
|
+
case ts.SyntaxKind.FunctionDeclaration:
|
|
103
|
+
return a.asKind(ts.SyntaxKind.FunctionDeclaration)?.getName();
|
|
94
104
|
|
|
95
|
-
|
|
96
|
-
|
|
105
|
+
case ts.SyntaxKind.FunctionExpression:
|
|
106
|
+
return (a.asKind(ts.SyntaxKind.FunctionExpression)?.getName()) ? a.asKind(ts.SyntaxKind.FunctionExpression)?.getName() : "anonymous";
|
|
97
107
|
|
|
98
|
-
|
|
99
|
-
|
|
108
|
+
case ts.SyntaxKind.Parameter:
|
|
109
|
+
return a.asKind(ts.SyntaxKind.Parameter)?.getName();
|
|
100
110
|
|
|
101
|
-
|
|
102
|
-
|
|
111
|
+
case ts.SyntaxKind.VariableDeclaration:
|
|
112
|
+
return a.asKind(ts.SyntaxKind.VariableDeclaration)?.getName();
|
|
103
113
|
|
|
104
|
-
|
|
105
|
-
|
|
114
|
+
case ts.SyntaxKind.Decorator:
|
|
115
|
+
return "@" + a.asKind(ts.SyntaxKind.Decorator)?.getName();
|
|
106
116
|
|
|
107
|
-
|
|
108
|
-
|
|
117
|
+
case ts.SyntaxKind.TypeParameter:
|
|
118
|
+
return a.asKind(ts.SyntaxKind.TypeParameter)?.getName();
|
|
109
119
|
|
|
110
|
-
|
|
111
|
-
|
|
120
|
+
case ts.SyntaxKind.EnumDeclaration:
|
|
121
|
+
return a.asKind(ts.SyntaxKind.EnumDeclaration)?.getName();
|
|
112
122
|
|
|
113
|
-
|
|
114
|
-
|
|
123
|
+
case ts.SyntaxKind.EnumMember:
|
|
124
|
+
return a.asKind(ts.SyntaxKind.EnumMember)?.getName();
|
|
115
125
|
|
|
116
|
-
|
|
117
|
-
|
|
126
|
+
case ts.SyntaxKind.TypeAliasDeclaration:
|
|
127
|
+
return a.asKind(ts.SyntaxKind.TypeAliasDeclaration)?.getName();
|
|
118
128
|
|
|
119
|
-
|
|
120
|
-
|
|
129
|
+
case ts.SyntaxKind.Constructor:
|
|
130
|
+
return "constructor";
|
|
121
131
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
132
|
+
default:
|
|
133
|
+
// ancestor hasn't got a useful name
|
|
134
|
+
return "";
|
|
125
135
|
}
|
|
126
|
-
|
|
127
|
-
}
|
|
136
|
+
}
|
|
@@ -1,18 +1,22 @@
|
|
|
1
|
+
import { logger } from "../../../analyze";
|
|
1
2
|
import { FamixJSONExporter } from "./famix_JSON_exporter";
|
|
2
|
-
import { FamixRepository } from "./famix_repository";
|
|
3
|
+
// import { FamixRepository } from "./famix_repository";
|
|
3
4
|
|
|
4
5
|
export abstract class FamixBaseElement {
|
|
5
6
|
|
|
6
7
|
public id: number;
|
|
7
8
|
|
|
8
|
-
constructor(repo: FamixRepository) {
|
|
9
|
-
|
|
9
|
+
// constructor(repo: FamixRepository) {
|
|
10
|
+
// repo.addElement(this);
|
|
11
|
+
// }
|
|
12
|
+
|
|
13
|
+
constructor(){
|
|
10
14
|
}
|
|
11
15
|
|
|
12
16
|
public abstract getJSON(): string;
|
|
13
17
|
|
|
14
|
-
// @
|
|
15
|
-
// tslint:disable-next-line:no-empty
|
|
18
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
16
19
|
public addPropertiesToExporter(exporter: FamixJSONExporter): void {
|
|
20
|
+
logger.debug("addPropertiesToExporter not implemented for " + this.constructor.name + `(${exporter})`);
|
|
17
21
|
}
|
|
18
22
|
}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { FamixBaseElement } from "./famix_base_element";
|
|
2
2
|
import { Class, Interface, Namespace, Variable, Method, Function as FamixFunctionEntity, Type, NamedEntity, ScriptEntity, Module, SourceLanguage } from "./model/famix";
|
|
3
|
-
|
|
3
|
+
// import { ClassDeclaration, ConstructorDeclaration, FunctionDeclaration, Identifier, InterfaceDeclaration, MethodDeclaration, MethodSignature, ModuleDeclaration, PropertyDeclaration, PropertySignature, SourceFile, TypeParameterDeclaration, VariableDeclaration, ParameterDeclaration, Decorator, GetAccessorDeclaration, SetAccessorDeclaration, ImportSpecifier, CommentRange, EnumDeclaration, EnumMember, TypeAliasDeclaration, FunctionExpression, ExpressionWithTypeArguments, ImportDeclaration, ImportEqualsDeclaration } from "ts-morph";
|
|
4
|
+
import * as Famix from "./model/famix";
|
|
5
|
+
import { TSMorphObjectType } from "../../../famix_functions/EntityDictionary";
|
|
4
6
|
/**
|
|
5
7
|
* This class is used to store all Famix elements
|
|
6
8
|
*/
|
|
@@ -14,9 +16,27 @@ export class FamixRepository {
|
|
|
14
16
|
private famixFunctions = new Set<FamixFunctionEntity>(); // All Famix functions
|
|
15
17
|
private famixFiles = new Set<ScriptEntity | Module>(); // All Famix files
|
|
16
18
|
private idCounter = 1; // Id counter
|
|
19
|
+
private absolutePath: string = "";
|
|
20
|
+
private fmxElementObjectMap = new Map<Famix.Entity,TSMorphObjectType>();
|
|
17
21
|
|
|
18
22
|
constructor() {
|
|
19
|
-
this.addElement(new SourceLanguage(
|
|
23
|
+
this.addElement(new SourceLanguage()); // add the source language entity (TypeScript)
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
public setFmxElementObjectMap(fmxElementObjectMap: Map<Famix.Entity,TSMorphObjectType>){
|
|
27
|
+
this.fmxElementObjectMap = fmxElementObjectMap;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
public getFmxElementObjectMap(){
|
|
31
|
+
return this.fmxElementObjectMap;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
public getAbsolutePath() : string {
|
|
35
|
+
return this.absolutePath;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
public setAbsolutePath( path: string ){
|
|
39
|
+
this.absolutePath = path;
|
|
20
40
|
}
|
|
21
41
|
|
|
22
42
|
/**
|
|
@@ -43,6 +63,8 @@ export class FamixRepository {
|
|
|
43
63
|
export(arg0: { format: string; }) {
|
|
44
64
|
if(arg0.format === "json") {
|
|
45
65
|
return this.getJSON();
|
|
66
|
+
} else {
|
|
67
|
+
throw new Error("Unsupported format");
|
|
46
68
|
}
|
|
47
69
|
}
|
|
48
70
|
|
|
@@ -63,7 +85,7 @@ export class FamixRepository {
|
|
|
63
85
|
* @returns All Famix entities of the given type
|
|
64
86
|
*/
|
|
65
87
|
public _getAllEntitiesWithType(theType: string): Set<FamixBaseElement> {
|
|
66
|
-
return new Set(Array.from(this.elements.values()).filter(e => (e as
|
|
88
|
+
return new Set(Array.from(this.elements.values()).filter(e => (e as FamixBaseElement).constructor.name === theType));
|
|
67
89
|
}
|
|
68
90
|
|
|
69
91
|
/**
|
|
@@ -71,8 +93,8 @@ export class FamixRepository {
|
|
|
71
93
|
* @param name A class name
|
|
72
94
|
* @returns The Famix class corresponding to the name or undefined if it doesn't exist
|
|
73
95
|
*/
|
|
74
|
-
public _getFamixClass(
|
|
75
|
-
return Array.from(this.famixClasses.values()).find(ns => ns.
|
|
96
|
+
public _getFamixClass(fullyQualifiedName: string): Class | undefined {
|
|
97
|
+
return Array.from(this.famixClasses.values()).find(ns => ns.getFullyQualifiedName() === fullyQualifiedName);
|
|
76
98
|
}
|
|
77
99
|
|
|
78
100
|
/**
|
|
@@ -80,8 +102,8 @@ export class FamixRepository {
|
|
|
80
102
|
* @param name An interface name
|
|
81
103
|
* @returns The Famix interface corresponding to the name or undefined if it doesn't exist
|
|
82
104
|
*/
|
|
83
|
-
public _getFamixInterface(
|
|
84
|
-
return Array.from(this.famixInterfaces.values()).find(ns => ns.
|
|
105
|
+
public _getFamixInterface(fullyQualifiedName: string): Interface | undefined {
|
|
106
|
+
return Array.from(this.famixInterfaces.values()).find(ns => ns.getFullyQualifiedName() === fullyQualifiedName);
|
|
85
107
|
}
|
|
86
108
|
|
|
87
109
|
/**
|
|
@@ -89,8 +111,8 @@ export class FamixRepository {
|
|
|
89
111
|
* @param name A method name
|
|
90
112
|
* @returns The Famix method corresponding to the name or undefined if it doesn't exist
|
|
91
113
|
*/
|
|
92
|
-
public _getFamixMethod(
|
|
93
|
-
return Array.from(this.famixMethods.values()).find(ns => ns.
|
|
114
|
+
public _getFamixMethod(fullyQualifiedName: string): Method | undefined {
|
|
115
|
+
return Array.from(this.famixMethods.values()).find(ns => ns.getFullyQualifiedName() === fullyQualifiedName);
|
|
94
116
|
}
|
|
95
117
|
|
|
96
118
|
/**
|
|
@@ -98,18 +120,18 @@ export class FamixRepository {
|
|
|
98
120
|
* @param name A function name
|
|
99
121
|
* @returns The Famix function corresponding to the name or undefined if it doesn't exist
|
|
100
122
|
*/
|
|
101
|
-
public _getFamixFunction(
|
|
102
|
-
return Array.from(this.famixFunctions.values()).find(ns => ns.
|
|
123
|
+
public _getFamixFunction(fullyQualifiedName: string): FamixFunctionEntity | undefined {
|
|
124
|
+
return Array.from(this.famixFunctions.values()).find(ns => ns.getFullyQualifiedName() === fullyQualifiedName);
|
|
103
125
|
}
|
|
104
126
|
|
|
105
127
|
|
|
106
|
-
/**
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
public _getFamixVariable(
|
|
112
|
-
return Array.from(this.famixVariables.values()).find(v => v.
|
|
128
|
+
/**
|
|
129
|
+
* Gets a Famix variable by name
|
|
130
|
+
* @param name A variable name
|
|
131
|
+
* @returns The Famix variable corresponding to the name or undefined if it doesn't exist
|
|
132
|
+
*/
|
|
133
|
+
public _getFamixVariable(fullyQualifiedName: string): Variable | undefined {
|
|
134
|
+
return Array.from(this.famixVariables.values()).find(v => v.getFullyQualifiedName() === fullyQualifiedName);
|
|
113
135
|
}
|
|
114
136
|
|
|
115
137
|
/**
|
|
@@ -117,8 +139,8 @@ export class FamixRepository {
|
|
|
117
139
|
* @param name A namespace name
|
|
118
140
|
* @returns The Famix namespace corresponding to the name or undefined if it doesn't exist
|
|
119
141
|
*/
|
|
120
|
-
public _getFamixNamespace(
|
|
121
|
-
return Array.from(this.famixNamespaces.values()).find(ns => ns.
|
|
142
|
+
public _getFamixNamespace(fullyQualifiedName: string): Namespace | undefined {
|
|
143
|
+
return Array.from(this.famixNamespaces.values()).find(ns => ns.getFullyQualifiedName() === fullyQualifiedName);
|
|
122
144
|
}
|
|
123
145
|
|
|
124
146
|
/**
|
|
@@ -134,8 +156,8 @@ export class FamixRepository {
|
|
|
134
156
|
* @param name A file name
|
|
135
157
|
* @returns The Famix file corresponding to the name or undefined if it doesn't exist
|
|
136
158
|
*/
|
|
137
|
-
public _getFamixFile(
|
|
138
|
-
return Array.from(this.famixFiles.values()).find(ns => ns.getName() ===
|
|
159
|
+
public _getFamixFile(fullyQualifiedName: string): ScriptEntity | Module | undefined {
|
|
160
|
+
return Array.from(this.famixFiles.values()).find(ns => ns.getName() === fullyQualifiedName);
|
|
139
161
|
}
|
|
140
162
|
|
|
141
163
|
/**
|
|
@@ -172,7 +194,7 @@ export class FamixRepository {
|
|
|
172
194
|
* @returns The map of Famix element ids and their Famix element from the JSON model
|
|
173
195
|
*/
|
|
174
196
|
public _initMapFromModel(model: string): Map<number, unknown> {
|
|
175
|
-
const parsedModel: Array<
|
|
197
|
+
const parsedModel: Array<FamixBaseElement> = JSON.parse(model);
|
|
176
198
|
const idToElementMap: Map<number, unknown> = new Map();
|
|
177
199
|
parsedModel.forEach(element => {
|
|
178
200
|
idToElementMap.set(element.id, element);
|
|
@@ -12,12 +12,10 @@ The above copyright notice and this permission notice shall be included in all c
|
|
|
12
12
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
13
13
|
*/
|
|
14
14
|
|
|
15
|
-
import { forEachChild, SyntaxKind, createSourceFile } from 'typescript';
|
|
15
|
+
import { forEachChild, isIdentifier, SyntaxKind, createSourceFile, ScriptTarget } from 'typescript';
|
|
16
16
|
import { isFunctionWithBody } from 'tsutils';
|
|
17
17
|
import { existsSync, readFileSync } from 'fs';
|
|
18
18
|
|
|
19
|
-
const { isIdentifier } = require('typescript');
|
|
20
|
-
|
|
21
19
|
const getNodeName = (node) => {
|
|
22
20
|
const { name, pos, end } = node;
|
|
23
21
|
const key = name !== undefined && isIdentifier(name) ? name.text : JSON.stringify({ pos, end });
|
|
@@ -80,6 +78,6 @@ export const calculate = (filePath) => {
|
|
|
80
78
|
throw new Error(`File "${filePath}" does not exists`);
|
|
81
79
|
}
|
|
82
80
|
const sourceText = readFileSync(filePath).toString();
|
|
83
|
-
const source = createSourceFile(filePath, sourceText,
|
|
81
|
+
const source = createSourceFile(filePath, sourceText, ScriptTarget.ES2015);
|
|
84
82
|
return calculateFromSource(source);
|
|
85
83
|
};
|
package/src/ts2famix-cli.ts
CHANGED
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ProcessAccesses = void 0;
|
|
4
|
-
const analyze_1 = require("../analyze");
|
|
5
|
-
/**
|
|
6
|
-
* This class is used to build a Famix model for the accesses
|
|
7
|
-
*/
|
|
8
|
-
class ProcessAccesses {
|
|
9
|
-
/**
|
|
10
|
-
* Initializes the ProcessAccesses object
|
|
11
|
-
* @param famixFunctions FamixFunctions object, it contains all the functions needed to create Famix entities
|
|
12
|
-
*/
|
|
13
|
-
constructor(famixFunctions) {
|
|
14
|
-
this.famixFunctions = famixFunctions;
|
|
15
|
-
}
|
|
16
|
-
/**
|
|
17
|
-
* Builds a Famix model for the accesses on the parameters, variables, properties and enum members of the source files
|
|
18
|
-
* @param accessMap A map of parameters, variables, properties and enum members with their id
|
|
19
|
-
*/
|
|
20
|
-
processAccesses(accessMap) {
|
|
21
|
-
analyze_1.logger.debug(`processAccesses: Creating accesses:`);
|
|
22
|
-
accessMap.forEach((v, id) => {
|
|
23
|
-
analyze_1.logger.debug(`processAccesses: Accesses to ${v.getName()}`);
|
|
24
|
-
try {
|
|
25
|
-
const temp_nodes = v.findReferencesAsNodes();
|
|
26
|
-
temp_nodes.forEach(node => this.processNodeForAccesses(node, id));
|
|
27
|
-
}
|
|
28
|
-
catch (error) {
|
|
29
|
-
analyze_1.logger.error(`> WARNING: got exception ${error}. Continuing...`);
|
|
30
|
-
}
|
|
31
|
-
});
|
|
32
|
-
}
|
|
33
|
-
/**
|
|
34
|
-
* Builds a Famix model for an access on a parameter, variable, property or enum member
|
|
35
|
-
* @param n A node
|
|
36
|
-
* @param id An id of a parameter, a variable, a property or an enum member
|
|
37
|
-
*/
|
|
38
|
-
processNodeForAccesses(n, id) {
|
|
39
|
-
try {
|
|
40
|
-
// sometimes node's first ancestor is a PropertyDeclaration, which is not an access
|
|
41
|
-
// see https://github.com/fuhrmanator/FamixTypeScriptImporter/issues/9
|
|
42
|
-
// check for a node whose first ancestor is a property declaration and bail?
|
|
43
|
-
// This may be a bug in ts-morph?
|
|
44
|
-
if (n.getFirstAncestorOrThrow().getKindName() === "PropertyDeclaration") {
|
|
45
|
-
analyze_1.logger.debug(`processNodeForAccesses: node kind: ${n.getKindName()}, ${n.getText()}, (${n.getType().getText()})'s first ancestor is a PropertyDeclaration. Skipping...`);
|
|
46
|
-
return;
|
|
47
|
-
}
|
|
48
|
-
this.famixFunctions.createFamixAccess(n, id);
|
|
49
|
-
analyze_1.logger.debug(`processNodeForAccesses: node kind: ${n.getKindName()}, ${n.getText()}, (${n.getType().getText()})`);
|
|
50
|
-
}
|
|
51
|
-
catch (error) {
|
|
52
|
-
analyze_1.logger.error(`> WARNING: got exception ${error}. ScopeDeclaration invalid for ${n.getSymbol().getFullyQualifiedName()}. Continuing...`);
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
exports.ProcessAccesses = ProcessAccesses;
|