ts2famix 2.0.1 → 2.1.0-beta.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/.eslintrc.json +24 -24
- package/.vscode/settings.json +4 -0
- package/LICENSE +24 -24
- package/README.md +78 -78
- package/TODO +1 -0
- package/arwea-fix.json +1 -0
- package/bogus.ts +3 -0
- package/class-diagram.puml +792 -0
- package/debug.txt +13332 -0
- package/debuglog.txt +12073 -0
- package/dist/analyze.js +2 -2
- package/dist/analyze_functions/process_functions.js +84 -64
- package/dist/famix2puml.js +126 -0
- package/dist/famix_functions/EntityDictionary.js +865 -503
- package/dist/famix_functions/helpers_creation.js +1 -1
- package/dist/fqn.js +44 -11
- package/dist/getClasses-arrow-body.js +43 -0
- package/dist/lib/famix/famix_JSON_exporter.js +1 -1
- package/dist/lib/famix/famix_base_element.js +1 -1
- package/dist/lib/famix/famix_repository.js +57 -2
- package/dist/lib/famix/index.js +1 -1
- package/dist/lib/famix/model/famix/access.js +1 -1
- package/dist/lib/famix/model/famix/accessor.js +1 -1
- package/dist/lib/famix/model/famix/alias.js +1 -1
- package/dist/lib/famix/model/famix/arrow_function.js +1 -1
- package/dist/lib/famix/model/famix/behavioral_entity.js +1 -1
- package/dist/lib/famix/model/famix/class.js +1 -1
- package/dist/lib/famix/model/famix/comment.js +1 -1
- package/dist/lib/famix/model/famix/concretisation.js +1 -1
- package/dist/lib/famix/model/famix/container_entity.js +1 -1
- package/dist/lib/famix/model/famix/decorator.js +1 -1
- package/dist/lib/famix/model/famix/entity.js +1 -1
- package/dist/lib/famix/model/famix/enum.js +1 -1
- package/dist/lib/famix/model/famix/enum_value.js +1 -1
- package/dist/lib/famix/model/famix/function.js +1 -1
- package/dist/lib/famix/model/famix/import_clause.js +1 -1
- package/dist/lib/famix/model/famix/index.js +1 -1
- package/dist/lib/famix/model/famix/indexed_file_anchor.js +1 -1
- package/dist/lib/famix/model/famix/inheritance.js +1 -1
- package/dist/lib/famix/model/famix/interface.js +1 -1
- package/dist/lib/famix/model/famix/invocation.js +1 -1
- package/dist/lib/famix/model/famix/method.js +1 -1
- package/dist/lib/famix/model/famix/module.js +1 -1
- package/dist/lib/famix/model/famix/named_entity.js +1 -1
- package/dist/lib/famix/model/famix/parameter.js +1 -1
- package/dist/lib/famix/model/famix/parameter_concretisation.js +1 -1
- package/dist/lib/famix/model/famix/parameter_type.js +1 -1
- package/dist/lib/famix/model/famix/parametric_arrow_function.js +1 -1
- package/dist/lib/famix/model/famix/parametric_class.js +1 -1
- package/dist/lib/famix/model/famix/parametric_function.js +1 -1
- package/dist/lib/famix/model/famix/parametric_interface.js +1 -1
- package/dist/lib/famix/model/famix/parametric_method.js +1 -1
- package/dist/lib/famix/model/famix/primitive_type.js +1 -1
- package/dist/lib/famix/model/famix/property.js +1 -1
- package/dist/lib/famix/model/famix/reference.js +1 -1
- package/dist/lib/famix/model/famix/scoping_entity.js +1 -1
- package/dist/lib/famix/model/famix/script_entity.js +1 -1
- package/dist/lib/famix/model/famix/source_anchor.js +1 -1
- package/dist/lib/famix/model/famix/source_language.js +1 -1
- package/dist/lib/famix/model/famix/sourced_entity.js +1 -1
- package/dist/lib/famix/model/famix/structural_entity.js +1 -1
- package/dist/lib/famix/model/famix/type.js +1 -1
- package/dist/lib/famix/model/famix/variable.js +1 -1
- package/dist/lib/famix/src/famix_JSON_exporter.js +55 -0
- package/dist/lib/famix/src/famix_base_element.js +18 -0
- package/dist/lib/famix/src/famix_repository.js +224 -0
- package/dist/lib/famix/src/index.js +31 -0
- package/dist/lib/famix/src/model/famix/access.js +40 -0
- package/dist/lib/famix/src/model/famix/accessor.js +17 -0
- package/dist/lib/famix/src/model/famix/alias.js +33 -0
- package/dist/lib/famix/src/model/famix/arrowFunction.js +17 -0
- package/dist/lib/famix/src/model/famix/arrow_function.js +17 -0
- package/dist/lib/famix/src/model/famix/behavioral_entity.js +79 -0
- package/dist/lib/famix/src/model/famix/class.js +71 -0
- package/dist/lib/famix/src/model/famix/comment.js +39 -0
- package/dist/lib/famix/src/model/famix/concretisation.js +31 -0
- package/dist/lib/famix/src/model/famix/container_entity.js +126 -0
- package/dist/lib/famix/src/model/famix/decorator.js +32 -0
- package/dist/lib/famix/src/model/famix/entity.js +17 -0
- package/dist/lib/famix/src/model/famix/enum.js +31 -0
- package/dist/lib/famix/src/model/famix/enum_value.js +25 -0
- package/dist/lib/famix/src/model/famix/function.js +17 -0
- package/dist/lib/famix/src/model/famix/implicit_variable.js +17 -0
- package/dist/lib/famix/src/model/famix/import_clause.js +41 -0
- package/dist/lib/famix/src/model/famix/index.js +86 -0
- package/dist/lib/famix/src/model/famix/indexed_file_anchor.js +38 -0
- package/dist/lib/famix/src/model/famix/inheritance.js +33 -0
- package/dist/lib/famix/src/model/famix/interface.js +64 -0
- package/dist/lib/famix/src/model/famix/invocation.js +54 -0
- package/dist/lib/famix/src/model/famix/method.js +67 -0
- package/dist/lib/famix/src/model/famix/module.js +60 -0
- package/dist/lib/famix/src/model/famix/named_entity.js +78 -0
- package/dist/lib/famix/src/model/famix/parameter.js +25 -0
- package/dist/lib/famix/src/model/famix/parameterConcretisation.js +44 -0
- package/dist/lib/famix/src/model/famix/parameter_concretisation.js +44 -0
- package/dist/lib/famix/src/model/famix/parameter_type.js +45 -0
- package/dist/lib/famix/src/model/famix/parametricArrowFunction.js +29 -0
- 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 +17 -0
- package/dist/lib/famix/src/model/famix/property.js +73 -0
- package/dist/lib/famix/src/model/famix/reference.js +33 -0
- package/dist/lib/famix/src/model/famix/scoping_entity.js +36 -0
- package/dist/lib/famix/src/model/famix/script_entity.js +29 -0
- package/dist/lib/famix/src/model/famix/source_anchor.js +27 -0
- package/dist/lib/famix/src/model/famix/source_language.js +35 -0
- package/dist/lib/famix/src/model/famix/sourced_entity.js +60 -0
- package/dist/lib/famix/src/model/famix/structural_entity.js +39 -0
- package/dist/lib/famix/src/model/famix/text_anchor.js +38 -0
- package/dist/lib/famix/src/model/famix/type.js +73 -0
- package/dist/lib/famix/src/model/famix/variable.js +24 -0
- package/dist/lib/ts-complex/cyclomatic-service.js +1 -1
- package/dist/refactorer/refactor-getter-setter.js +1 -1
- package/dist/ts2famix-cli-wrapper.js +1 -1
- package/dist/ts2famix-cli.js +1 -1
- package/doc-uml/famix-typescript-model.puml +607 -607
- package/eslint.config.mjs +28 -0
- package/fqn-model.json +1 -0
- package/iterateGenericTypes.ts +69 -0
- package/out/class-diagram/class-diagram.svg +1 -0
- package/package.json +70 -50
- package/sample.json +1 -0
- package/sample.ts +1 -0
- package/src/analyze.ts +120 -120
- package/src/analyze_functions/process_functions.ts +1040 -1019
- package/src/famix_functions/EntityDictionary.ts +2016 -1593
- package/src/famix_functions/helpers_creation.ts +135 -135
- package/src/fqn.ts +50 -16
- package/src/generate_uml.sh +20 -20
- package/src/lib/famix/License.md +22 -22
- package/src/lib/famix/famix_JSON_exporter.ts +56 -56
- package/src/lib/famix/famix_base_element.ts +22 -22
- package/src/lib/famix/famix_repository.ts +278 -243
- package/src/lib/famix/index.ts +8 -8
- package/src/lib/famix/model/famix/access.ts +50 -50
- package/src/lib/famix/model/famix/accessor.ts +15 -15
- package/src/lib/famix/model/famix/alias.ts +39 -39
- package/src/lib/famix/model/famix/arrow_function.ts +15 -15
- package/src/lib/famix/model/famix/behavioral_entity.ts +97 -97
- package/src/lib/famix/model/famix/class.ts +85 -85
- package/src/lib/famix/model/famix/comment.ts +47 -47
- package/src/lib/famix/model/famix/concretisation.ts +40 -40
- package/src/lib/famix/model/famix/container_entity.ts +160 -160
- package/src/lib/famix/model/famix/decorator.ts +37 -37
- package/src/lib/famix/model/famix/entity.ts +15 -15
- package/src/lib/famix/model/famix/enum.ts +30 -30
- package/src/lib/famix/model/famix/enum_value.ts +28 -28
- package/src/lib/famix/model/famix/function.ts +15 -15
- package/src/lib/famix/model/famix/import_clause.ts +51 -51
- package/src/lib/famix/model/famix/index.ts +41 -41
- package/src/lib/famix/model/famix/indexed_file_anchor.ts +46 -46
- package/src/lib/famix/model/famix/inheritance.ts +40 -40
- package/src/lib/famix/model/famix/interface.ts +75 -75
- package/src/lib/famix/model/famix/invocation.ts +65 -65
- package/src/lib/famix/model/famix/method.ts +89 -89
- package/src/lib/famix/model/famix/module.ts +71 -71
- package/src/lib/famix/model/famix/named_entity.ts +95 -95
- package/src/lib/famix/model/famix/parameter.ts +28 -28
- package/src/lib/famix/model/famix/parameter_concretisation.ts +51 -51
- package/src/lib/famix/model/famix/parameter_type.ts +58 -58
- package/src/lib/famix/model/famix/parametric_arrow_function.ts +32 -32
- package/src/lib/famix/model/famix/parametric_class.ts +49 -49
- package/src/lib/famix/model/famix/parametric_function.ts +32 -32
- package/src/lib/famix/model/famix/parametric_interface.ts +49 -49
- package/src/lib/famix/model/famix/parametric_method.ts +32 -32
- package/src/lib/famix/model/famix/primitive_type.ts +15 -15
- package/src/lib/famix/model/famix/property.ts +94 -94
- package/src/lib/famix/model/famix/reference.ts +40 -40
- package/src/lib/famix/model/famix/scoping_entity.ts +35 -35
- package/src/lib/famix/model/famix/script_entity.ts +34 -34
- package/src/lib/famix/model/famix/source_anchor.ts +30 -30
- package/src/lib/famix/model/famix/source_language.ts +35 -35
- package/src/lib/famix/model/famix/sourced_entity.ts +70 -70
- package/src/lib/famix/model/famix/structural_entity.ts +43 -43
- package/src/lib/famix/model/famix/type.ts +87 -87
- package/src/lib/famix/model/famix/variable.ts +27 -27
- package/src/lib/famix/package.json +28 -28
- package/src/lib/ts-complex/cyclomatic-service.ts +83 -83
- package/src/refactorer/refactor-getter-setter.ts +140 -140
- package/src/ts2famix-cli-wrapper.ts +21 -21
- package/src/ts2famix-cli.ts +60 -60
- package/stats.txt +3091 -0
- package/tabby-debug-output.txt +19433 -0
- package/ts2famix.log +22656 -0
- package/tsconfig.check-tests.json +14 -14
- package/tsconfig.json +72 -72
- package/validate-references.js +103 -0
|
@@ -1,135 +1,135 @@
|
|
|
1
|
-
import * as Famix from "../lib/famix/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
|
-
import {
|
|
5
|
-
|
|
6
|
-
interface SearchParameters {
|
|
7
|
-
searchArray: string[];
|
|
8
|
-
targetArray: string[];
|
|
9
|
-
start?: number;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* This function works like indexOf, but it works with arrays of grapheme clusters.
|
|
14
|
-
* @param targetArray
|
|
15
|
-
*/
|
|
16
|
-
export function indexOfSplitArray(params: SearchParameters): number {
|
|
17
|
-
const {searchArray, targetArray, start = 0} = params;
|
|
18
|
-
for (let i = start; i <= searchArray.length - targetArray.length; i++) {
|
|
19
|
-
let found = true;
|
|
20
|
-
for (let j = 0; j < targetArray.length; j++) {
|
|
21
|
-
if (searchArray[i + j] !== targetArray[j]) {
|
|
22
|
-
found = false;
|
|
23
|
-
break;
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
if (found) {
|
|
27
|
-
return i; // Return the index where the target array was found
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
return -1; // Return -1 if the target array was not found in the search array
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
export function getSubTypeName(fmxNamedEntity: Famix.NamedEntity) {
|
|
34
|
-
const name = fmxNamedEntity instanceof Famix.Class ? 'Class' :
|
|
35
|
-
fmxNamedEntity instanceof Famix.Interface ? 'Interface' :
|
|
36
|
-
fmxNamedEntity instanceof Famix.Function ? 'Function' :
|
|
37
|
-
fmxNamedEntity instanceof Famix.Enum ? 'Enum' :
|
|
38
|
-
fmxNamedEntity instanceof Famix.EnumValue ? 'EnumValue' :
|
|
39
|
-
fmxNamedEntity instanceof Famix.Alias ? 'Alias' :
|
|
40
|
-
fmxNamedEntity instanceof Famix.Variable ? 'Variable' :
|
|
41
|
-
fmxNamedEntity instanceof Famix.Type ? 'Type' :
|
|
42
|
-
fmxNamedEntity instanceof Famix.Method ? 'Method' :
|
|
43
|
-
fmxNamedEntity instanceof Famix.Decorator ? 'Decorator' :
|
|
44
|
-
fmxNamedEntity instanceof Famix.Accessor ? 'Accessor' :
|
|
45
|
-
fmxNamedEntity instanceof Famix.Parameter ? 'Parameter' :
|
|
46
|
-
fmxNamedEntity instanceof Famix.Property ? 'Property' :
|
|
47
|
-
'NamedEntity';
|
|
48
|
-
logger.debug(`${fmxNamedEntity.name} is of type ${name}`);
|
|
49
|
-
return name;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* Gets the signature of a method or a function
|
|
54
|
-
* @param text A method or a function source code
|
|
55
|
-
* @returns The signature of the method or the function
|
|
56
|
-
*/
|
|
57
|
-
export function computeSignature(text: string): string {
|
|
58
|
-
const endSignatureText = text.indexOf("{");
|
|
59
|
-
return text.substring(0, endSignatureText).trim();
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
* Finds the ancestor of a node
|
|
64
|
-
* @param node A node
|
|
65
|
-
* @returns The ancestor of the node
|
|
66
|
-
*/
|
|
67
|
-
export function findAncestor(node: Identifier): Node {
|
|
68
|
-
let ancestor: Node | undefined;
|
|
69
|
-
ancestor = node.getAncestors().find(a =>
|
|
70
|
-
a.getKind() === SyntaxKind.MethodDeclaration ||
|
|
71
|
-
a.getKind() === SyntaxKind.Constructor ||
|
|
72
|
-
a.getKind() === SyntaxKind.FunctionDeclaration ||
|
|
73
|
-
a.getKind() === SyntaxKind.FunctionExpression ||
|
|
74
|
-
a.getKind() === SyntaxKind.ModuleDeclaration ||
|
|
75
|
-
a.getKind() === SyntaxKind.SourceFile ||
|
|
76
|
-
a.getKindName() === "GetAccessor" ||
|
|
77
|
-
a.getKindName() === "SetAccessor" ||
|
|
78
|
-
a.getKind() === SyntaxKind.ClassDeclaration);
|
|
79
|
-
if (!ancestor) {
|
|
80
|
-
throw new Error(`Ancestor not found for ${node.getText()}`);
|
|
81
|
-
}
|
|
82
|
-
return ancestor
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* Finds the ancestor of a ts-morph element
|
|
87
|
-
* @param element A ts-morph element
|
|
88
|
-
* @returns The ancestor of the ts-morph element
|
|
89
|
-
*/
|
|
90
|
-
export function findTypeAncestor(element:
|
|
91
|
-
let ancestor: Node | undefined;
|
|
92
|
-
ancestor = element.getAncestors().find(a =>
|
|
93
|
-
a.getKind() === SyntaxKind.MethodDeclaration ||
|
|
94
|
-
a.getKind() === SyntaxKind.Constructor ||
|
|
95
|
-
a.getKind() === SyntaxKind.MethodSignature ||
|
|
96
|
-
a.getKind() === SyntaxKind.FunctionDeclaration ||
|
|
97
|
-
a.getKind() === SyntaxKind.FunctionExpression ||
|
|
98
|
-
a.getKind() === SyntaxKind.ModuleDeclaration ||
|
|
99
|
-
a.getKind() === SyntaxKind.SourceFile ||
|
|
100
|
-
a.getKindName() === "GetAccessor" ||
|
|
101
|
-
a.getKindName() === "SetAccessor" ||
|
|
102
|
-
a.getKind() === SyntaxKind.ClassDeclaration ||
|
|
103
|
-
a.getKind() === SyntaxKind.InterfaceDeclaration);
|
|
104
|
-
if (!ancestor) {
|
|
105
|
-
throw new Error(`Type ancestor not found for ${element.getKindName()}`);
|
|
106
|
-
}
|
|
107
|
-
return ancestor;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
export function arraysAreEqual(array1: string[], array2: string[]): boolean {
|
|
111
|
-
if (array1 && array2 ) {
|
|
112
|
-
return array1.length === array2.length && array1.every((value, index) => value === array2[index]);
|
|
113
|
-
} else {
|
|
114
|
-
return false;
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
export function replaceLastBetweenTags(input: string, replacement: string): string {
|
|
119
|
-
const lastTagIndex = input.lastIndexOf('<');
|
|
120
|
-
|
|
121
|
-
if (lastTagIndex === -1) {
|
|
122
|
-
return input; // Return the original string if no tags are found
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
const closingTagIndex = input.indexOf('>', lastTagIndex);
|
|
126
|
-
|
|
127
|
-
if (closingTagIndex === -1) {
|
|
128
|
-
return input; // Return the original string if no closing tag is found
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
const beforeTag = input.substring(0, lastTagIndex + 1); // Include '<'
|
|
132
|
-
const afterTag = input.substring(closingTagIndex); // Include '>'
|
|
133
|
-
|
|
134
|
-
return beforeTag + replacement + afterTag;
|
|
135
|
-
}
|
|
1
|
+
import * as Famix from "../lib/famix/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
|
+
import { TSMorphTypeDeclaration } from "./EntityDictionary";
|
|
5
|
+
|
|
6
|
+
interface SearchParameters {
|
|
7
|
+
searchArray: string[];
|
|
8
|
+
targetArray: string[];
|
|
9
|
+
start?: number;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* This function works like indexOf, but it works with arrays of grapheme clusters.
|
|
14
|
+
* @param targetArray
|
|
15
|
+
*/
|
|
16
|
+
export function indexOfSplitArray(params: SearchParameters): number {
|
|
17
|
+
const {searchArray, targetArray, start = 0} = params;
|
|
18
|
+
for (let i = start; i <= searchArray.length - targetArray.length; i++) {
|
|
19
|
+
let found = true;
|
|
20
|
+
for (let j = 0; j < targetArray.length; j++) {
|
|
21
|
+
if (searchArray[i + j] !== targetArray[j]) {
|
|
22
|
+
found = false;
|
|
23
|
+
break;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
if (found) {
|
|
27
|
+
return i; // Return the index where the target array was found
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return -1; // Return -1 if the target array was not found in the search array
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export function getSubTypeName(fmxNamedEntity: Famix.NamedEntity) {
|
|
34
|
+
const name = fmxNamedEntity instanceof Famix.Class ? 'Class' :
|
|
35
|
+
fmxNamedEntity instanceof Famix.Interface ? 'Interface' :
|
|
36
|
+
fmxNamedEntity instanceof Famix.Function ? 'Function' :
|
|
37
|
+
fmxNamedEntity instanceof Famix.Enum ? 'Enum' :
|
|
38
|
+
fmxNamedEntity instanceof Famix.EnumValue ? 'EnumValue' :
|
|
39
|
+
fmxNamedEntity instanceof Famix.Alias ? 'Alias' :
|
|
40
|
+
fmxNamedEntity instanceof Famix.Variable ? 'Variable' :
|
|
41
|
+
fmxNamedEntity instanceof Famix.Type ? 'Type' :
|
|
42
|
+
fmxNamedEntity instanceof Famix.Method ? 'Method' :
|
|
43
|
+
fmxNamedEntity instanceof Famix.Decorator ? 'Decorator' :
|
|
44
|
+
fmxNamedEntity instanceof Famix.Accessor ? 'Accessor' :
|
|
45
|
+
fmxNamedEntity instanceof Famix.Parameter ? 'Parameter' :
|
|
46
|
+
fmxNamedEntity instanceof Famix.Property ? 'Property' :
|
|
47
|
+
'NamedEntity';
|
|
48
|
+
logger.debug(`${fmxNamedEntity.name} is of type ${name}`);
|
|
49
|
+
return name;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Gets the signature of a method or a function
|
|
54
|
+
* @param text A method or a function source code
|
|
55
|
+
* @returns The signature of the method or the function
|
|
56
|
+
*/
|
|
57
|
+
export function computeSignature(text: string): string {
|
|
58
|
+
const endSignatureText = text.indexOf("{");
|
|
59
|
+
return text.substring(0, endSignatureText).trim();
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Finds the ancestor of a node
|
|
64
|
+
* @param node A node
|
|
65
|
+
* @returns The ancestor of the node
|
|
66
|
+
*/
|
|
67
|
+
export function findAncestor(node: Identifier): Node {
|
|
68
|
+
let ancestor: Node | undefined;
|
|
69
|
+
ancestor = node.getAncestors().find(a =>
|
|
70
|
+
a.getKind() === SyntaxKind.MethodDeclaration ||
|
|
71
|
+
a.getKind() === SyntaxKind.Constructor ||
|
|
72
|
+
a.getKind() === SyntaxKind.FunctionDeclaration ||
|
|
73
|
+
a.getKind() === SyntaxKind.FunctionExpression ||
|
|
74
|
+
a.getKind() === SyntaxKind.ModuleDeclaration ||
|
|
75
|
+
a.getKind() === SyntaxKind.SourceFile ||
|
|
76
|
+
a.getKindName() === "GetAccessor" ||
|
|
77
|
+
a.getKindName() === "SetAccessor" ||
|
|
78
|
+
a.getKind() === SyntaxKind.ClassDeclaration);
|
|
79
|
+
if (!ancestor) {
|
|
80
|
+
throw new Error(`Ancestor not found for ${node.getText()}`);
|
|
81
|
+
}
|
|
82
|
+
return ancestor
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Finds the ancestor of a ts-morph element
|
|
87
|
+
* @param element A ts-morph element
|
|
88
|
+
* @returns The ancestor of the ts-morph element
|
|
89
|
+
*/
|
|
90
|
+
export function findTypeAncestor(element: TSMorphTypeDeclaration): Node {
|
|
91
|
+
let ancestor: Node | undefined;
|
|
92
|
+
ancestor = element.getAncestors().find(a =>
|
|
93
|
+
a.getKind() === SyntaxKind.MethodDeclaration ||
|
|
94
|
+
a.getKind() === SyntaxKind.Constructor ||
|
|
95
|
+
a.getKind() === SyntaxKind.MethodSignature ||
|
|
96
|
+
a.getKind() === SyntaxKind.FunctionDeclaration ||
|
|
97
|
+
a.getKind() === SyntaxKind.FunctionExpression ||
|
|
98
|
+
a.getKind() === SyntaxKind.ModuleDeclaration ||
|
|
99
|
+
a.getKind() === SyntaxKind.SourceFile ||
|
|
100
|
+
a.getKindName() === "GetAccessor" ||
|
|
101
|
+
a.getKindName() === "SetAccessor" ||
|
|
102
|
+
a.getKind() === SyntaxKind.ClassDeclaration ||
|
|
103
|
+
a.getKind() === SyntaxKind.InterfaceDeclaration);
|
|
104
|
+
if (!ancestor) {
|
|
105
|
+
throw new Error(`Type ancestor not found for ${element.getKindName()}`);
|
|
106
|
+
}
|
|
107
|
+
return ancestor;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
export function arraysAreEqual(array1: string[], array2: string[]): boolean {
|
|
111
|
+
if (array1 && array2 ) {
|
|
112
|
+
return array1.length === array2.length && array1.every((value, index) => value === array2[index]);
|
|
113
|
+
} else {
|
|
114
|
+
return false;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export function replaceLastBetweenTags(input: string, replacement: string): string {
|
|
119
|
+
const lastTagIndex = input.lastIndexOf('<');
|
|
120
|
+
|
|
121
|
+
if (lastTagIndex === -1) {
|
|
122
|
+
return input; // Return the original string if no tags are found
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
const closingTagIndex = input.indexOf('>', lastTagIndex);
|
|
126
|
+
|
|
127
|
+
if (closingTagIndex === -1) {
|
|
128
|
+
return input; // Return the original string if no closing tag is found
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
const beforeTag = input.substring(0, lastTagIndex + 1); // Include '<'
|
|
132
|
+
const afterTag = input.substring(closingTagIndex); // Include '>'
|
|
133
|
+
|
|
134
|
+
return beforeTag + replacement + afterTag;
|
|
135
|
+
}
|
package/src/fqn.ts
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
import { ArrowFunction, CallExpression, ClassDeclaration,
|
|
1
|
+
import { ArrowFunction, CallExpression, ClassDeclaration, ConstructorDeclaration, Decorator, EnumDeclaration, FunctionDeclaration, FunctionExpression, GetAccessorDeclaration, Identifier, ImportDeclaration, ImportEqualsDeclaration, InterfaceDeclaration, MethodDeclaration, MethodSignature, ModuleDeclaration, Node, PropertyDeclaration, SetAccessorDeclaration, SourceFile, SyntaxKind, TypeParameterDeclaration, VariableDeclaration } from "ts-morph";
|
|
2
2
|
import { entityDictionary, logger } from "./analyze";
|
|
3
3
|
import path from "path";
|
|
4
|
-
import {
|
|
4
|
+
import { TSMorphTypeDeclaration } from "./famix_functions/EntityDictionary";
|
|
5
5
|
|
|
6
|
-
type FQNNode = SourceFile | VariableDeclaration | ArrowFunction | Identifier | MethodDeclaration | MethodSignature | FunctionDeclaration | FunctionExpression | PropertyDeclaration |
|
|
6
|
+
type FQNNode = SourceFile | VariableDeclaration | ArrowFunction | Identifier | MethodDeclaration | MethodSignature | FunctionDeclaration | FunctionExpression | PropertyDeclaration | TSMorphTypeDeclaration | EnumDeclaration | ImportDeclaration | ImportEqualsDeclaration | CallExpression | GetAccessorDeclaration | SetAccessorDeclaration | ConstructorDeclaration | TypeParameterDeclaration | ClassDeclaration | InterfaceDeclaration | Decorator | ModuleDeclaration;
|
|
7
7
|
|
|
8
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
8
9
|
function isFQNNode(node: Node): node is FQNNode {
|
|
9
10
|
return Node.isVariableDeclaration(node) || Node.isArrowFunction(node) || Node.isIdentifier(node) || Node.isMethodDeclaration(node) || Node.isClassDeclaration(node) || Node.isClassExpression(node) || Node.isDecorator(node) || Node.isModuleDeclaration(node) || Node.isCallExpression(node);
|
|
10
|
-
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
export function getFQN(node: FQNNode | Node): string {
|
|
14
14
|
const absolutePathProject = entityDictionary.famixRep.getAbsolutePath();
|
|
15
15
|
|
|
16
16
|
const sourceFile = node.getSourceFile();
|
|
17
|
-
|
|
17
|
+
const parts: string[] = [];
|
|
18
18
|
let currentNode: Node | undefined = node;
|
|
19
19
|
|
|
20
20
|
while (currentNode && !Node.isSourceFile(currentNode)) {
|
|
@@ -29,11 +29,24 @@ export function getFQN(node: FQNNode | Node): string {
|
|
|
29
29
|
Node.isVariableDeclaration(currentNode) ||
|
|
30
30
|
Node.isGetAccessorDeclaration(currentNode) ||
|
|
31
31
|
Node.isSetAccessorDeclaration(currentNode) ||
|
|
32
|
+
Node.isTypeParameterDeclaration(currentNode) ||
|
|
33
|
+
Node.isPropertyDeclaration(currentNode) ||
|
|
34
|
+
Node.isParameterDeclaration(currentNode) ||
|
|
35
|
+
Node.isDecorator(currentNode) ||
|
|
36
|
+
Node.isTypeAliasDeclaration(currentNode) ||
|
|
37
|
+
Node.isEnumDeclaration(currentNode) ||
|
|
38
|
+
Node.isEnumMember(currentNode) ||
|
|
39
|
+
Node.isParametered(currentNode) ||
|
|
40
|
+
Node.isPropertySignature(currentNode) ||
|
|
41
|
+
Node.isArrayLiteralExpression(currentNode) ||
|
|
42
|
+
Node.isImportSpecifier(currentNode) ||
|
|
32
43
|
Node.isIdentifier(currentNode)) {
|
|
33
|
-
|
|
44
|
+
const name = Node.isIdentifier(currentNode) ? currentNode.getText()
|
|
34
45
|
: getNameOfNode(currentNode) /* currentNode.getName() */ || 'Unnamed_' + currentNode.getKindName() + `(${lc})`;
|
|
35
46
|
parts.unshift(name);
|
|
36
|
-
}
|
|
47
|
+
}
|
|
48
|
+
// unnamed nodes
|
|
49
|
+
else if (Node.isArrowFunction(currentNode) ||
|
|
37
50
|
Node.isBlock(currentNode) ||
|
|
38
51
|
Node.isForInStatement(currentNode) ||
|
|
39
52
|
Node.isForOfStatement(currentNode) ||
|
|
@@ -44,7 +57,7 @@ export function getFQN(node: FQNNode | Node): string {
|
|
|
44
57
|
parts.unshift(`constructor`);
|
|
45
58
|
} else {
|
|
46
59
|
// For other kinds, you might want to handle them specifically or ignore
|
|
47
|
-
|
|
60
|
+
logger.debug(`Ignoring node kind: ${currentNode.getKindName()}`);
|
|
48
61
|
}
|
|
49
62
|
currentNode = currentNode.getParent();
|
|
50
63
|
}
|
|
@@ -52,20 +65,27 @@ export function getFQN(node: FQNNode | Node): string {
|
|
|
52
65
|
|
|
53
66
|
|
|
54
67
|
// Prepend the relative path of the source file
|
|
55
|
-
|
|
68
|
+
let relativePath = entityDictionary.convertToRelativePath(
|
|
56
69
|
path.normalize(sourceFile.getFilePath()),
|
|
57
70
|
absolutePathProject).replace(/\\/sg, "/");
|
|
71
|
+
|
|
72
|
+
if (relativePath.includes("..")) {
|
|
73
|
+
logger.error(`Relative path contains ../: ${relativePath}`);
|
|
74
|
+
}
|
|
75
|
+
if (relativePath.startsWith("/")) {
|
|
76
|
+
relativePath = relativePath.substring(1);
|
|
77
|
+
}
|
|
58
78
|
parts.unshift(`{${relativePath}}`);
|
|
59
79
|
const fqn = parts.join(".") + `[${node.getKindName()}]`; // disambiguate
|
|
60
80
|
|
|
61
|
-
logger.debug(fqn);
|
|
81
|
+
logger.debug(`Generated FQN: ${fqn} for node: ${node.getKindName()}`);
|
|
62
82
|
return fqn;
|
|
63
83
|
}
|
|
64
84
|
|
|
65
85
|
|
|
66
86
|
export function getUniqueFQN(node: Node): string | undefined {
|
|
67
87
|
const absolutePathProject = entityDictionary.famixRep.getAbsolutePath();
|
|
68
|
-
|
|
88
|
+
const parts: string[] = [];
|
|
69
89
|
|
|
70
90
|
if (node instanceof SourceFile) {
|
|
71
91
|
return entityDictionary.convertToRelativePath(path.normalize(node.getFilePath()), absolutePathProject).replace(/\\/g, "/");
|
|
@@ -75,6 +95,9 @@ export function getUniqueFQN(node: Node): string | undefined {
|
|
|
75
95
|
while (currentNode) {
|
|
76
96
|
if (Node.isSourceFile(currentNode)) {
|
|
77
97
|
const relativePath = entityDictionary.convertToRelativePath(path.normalize(currentNode.getFilePath()), absolutePathProject).replace(/\\/g, "/");
|
|
98
|
+
if (relativePath.includes("..")) {
|
|
99
|
+
logger.error(`Relative path contains ../: ${relativePath}`);
|
|
100
|
+
}
|
|
78
101
|
parts.unshift(relativePath); // Add file path at the start
|
|
79
102
|
break;
|
|
80
103
|
} else if (currentNode.getSymbol()) {
|
|
@@ -95,6 +118,11 @@ export function getUniqueFQN(node: Node): string | undefined {
|
|
|
95
118
|
* @returns The name of the node, or an empty string if it doesn't have one
|
|
96
119
|
*/
|
|
97
120
|
export function getNameOfNode(a: Node): string {
|
|
121
|
+
let cKind: ClassDeclaration | undefined;
|
|
122
|
+
let iKind: InterfaceDeclaration | undefined;
|
|
123
|
+
let mKind: MethodDeclaration | undefined;
|
|
124
|
+
let fKind: FunctionDeclaration | undefined;
|
|
125
|
+
let alias: TSMorphTypeDeclaration | undefined;
|
|
98
126
|
switch (a.getKind()) {
|
|
99
127
|
case SyntaxKind.SourceFile:
|
|
100
128
|
return a.asKind(SyntaxKind.SourceFile)!.getBaseName();
|
|
@@ -103,7 +131,7 @@ export function getNameOfNode(a: Node): string {
|
|
|
103
131
|
return a.asKind(SyntaxKind.ModuleDeclaration)!.getName();
|
|
104
132
|
|
|
105
133
|
case SyntaxKind.ClassDeclaration:
|
|
106
|
-
|
|
134
|
+
cKind = a.asKind(SyntaxKind.ClassDeclaration);
|
|
107
135
|
if (cKind && cKind.getTypeParameters().length > 0) {
|
|
108
136
|
return cKind.getName() + getParameters(a);
|
|
109
137
|
} else {
|
|
@@ -111,7 +139,7 @@ export function getNameOfNode(a: Node): string {
|
|
|
111
139
|
}
|
|
112
140
|
|
|
113
141
|
case SyntaxKind.InterfaceDeclaration:
|
|
114
|
-
|
|
142
|
+
iKind = a.asKind(SyntaxKind.InterfaceDeclaration);
|
|
115
143
|
if (iKind && iKind.getTypeParameters().length > 0) {
|
|
116
144
|
return iKind.getName() + getParameters(a);
|
|
117
145
|
} else {
|
|
@@ -125,7 +153,7 @@ export function getNameOfNode(a: Node): string {
|
|
|
125
153
|
return a.asKind(SyntaxKind.PropertySignature)!.getName();
|
|
126
154
|
|
|
127
155
|
case SyntaxKind.MethodDeclaration:
|
|
128
|
-
|
|
156
|
+
mKind = a.asKind(SyntaxKind.MethodDeclaration);
|
|
129
157
|
if (mKind && mKind.getTypeParameters().length > 0) {
|
|
130
158
|
return mKind.getName() + getParameters(a);
|
|
131
159
|
} else {
|
|
@@ -142,7 +170,7 @@ export function getNameOfNode(a: Node): string {
|
|
|
142
170
|
return a.asKind(SyntaxKind.SetAccessor)!.getName();
|
|
143
171
|
|
|
144
172
|
case SyntaxKind.FunctionDeclaration:
|
|
145
|
-
|
|
173
|
+
fKind = a.asKind(SyntaxKind.FunctionDeclaration);
|
|
146
174
|
if (fKind && fKind.getTypeParameters().length > 0) {
|
|
147
175
|
return fKind.getName() + getParameters(a);
|
|
148
176
|
} else {
|
|
@@ -171,12 +199,18 @@ export function getNameOfNode(a: Node): string {
|
|
|
171
199
|
return a.asKind(SyntaxKind.EnumMember)!.getName();
|
|
172
200
|
|
|
173
201
|
case SyntaxKind.TypeAliasDeclaration:
|
|
202
|
+
// special case for parameterized types
|
|
203
|
+
alias = a.asKind(SyntaxKind.TypeAliasDeclaration);
|
|
204
|
+
if (alias && alias.getTypeParameters().length > 0) {
|
|
205
|
+
return alias.getName() + "<" + alias.getTypeParameters().map(tp => tp.getName()).join(", ") + ">";
|
|
206
|
+
}
|
|
174
207
|
return a.asKind(SyntaxKind.TypeAliasDeclaration)!.getName();
|
|
175
208
|
|
|
176
209
|
case SyntaxKind.Constructor:
|
|
177
210
|
return "constructor";
|
|
178
|
-
|
|
211
|
+
|
|
179
212
|
default:
|
|
213
|
+
// throw new Error(`getNameOfNode called on a node that doesn't have a name: ${a.getKindName()}`);
|
|
180
214
|
// ancestor hasn't got a useful name
|
|
181
215
|
return "";
|
|
182
216
|
}
|
package/src/generate_uml.sh
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
# Gets latest plantuml
|
|
3
|
-
rm -f plantuml.jar
|
|
4
|
-
wget --no-verbose https://downloads.sourceforge.net/project/plantuml/plantuml.jar
|
|
5
|
-
# echo the version
|
|
6
|
-
echo "PlantUML version: $(java -jar plantuml.jar -version)"
|
|
7
|
-
echo "tplant version: $(npx tplant --version)"
|
|
8
|
-
# Builds metamodel plantuml from TypeScript sources
|
|
9
|
-
npx tplant -i src/lib/famix/**/*.ts -o doc-metamodel/famix-typescript-model.puml
|
|
10
|
-
sed -i 's/@startuml/& metamodel/' doc-metamodel/famix-typescript-model.puml
|
|
11
|
-
# Converts plantuml source to SVG image
|
|
12
|
-
java -jar plantuml.jar -v -tsvg doc-metamodel/famix-typescript-model.puml
|
|
13
|
-
mv doc-metamodel/metamodel.svg doc-metamodel/metamodel-full.svg
|
|
14
|
-
# Inserts include line to customize the file
|
|
15
|
-
sed -i '/@startuml metamodel/a !include skins.include.puml' doc-metamodel/famix-typescript-model.puml
|
|
16
|
-
# Converts plantuml source to SVG image
|
|
17
|
-
java -jar plantuml.jar -v -tsvg doc-metamodel/famix-typescript-model.puml
|
|
18
|
-
# Moves artifacts
|
|
19
|
-
rm -f doc-uml/*
|
|
20
|
-
mv doc-metamodel/*.svg doc-uml
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Gets latest plantuml
|
|
3
|
+
rm -f plantuml.jar
|
|
4
|
+
wget --no-verbose https://downloads.sourceforge.net/project/plantuml/plantuml.jar
|
|
5
|
+
# echo the version
|
|
6
|
+
echo "PlantUML version: $(java -jar plantuml.jar -version)"
|
|
7
|
+
echo "tplant version: $(npx tplant --version)"
|
|
8
|
+
# Builds metamodel plantuml from TypeScript sources
|
|
9
|
+
npx tplant -i src/lib/famix/**/*.ts -o doc-metamodel/famix-typescript-model.puml
|
|
10
|
+
sed -i 's/@startuml/& metamodel/' doc-metamodel/famix-typescript-model.puml
|
|
11
|
+
# Converts plantuml source to SVG image
|
|
12
|
+
java -jar plantuml.jar -v -tsvg doc-metamodel/famix-typescript-model.puml
|
|
13
|
+
mv doc-metamodel/metamodel.svg doc-metamodel/metamodel-full.svg
|
|
14
|
+
# Inserts include line to customize the file
|
|
15
|
+
sed -i '/@startuml metamodel/a !include skins.include.puml' doc-metamodel/famix-typescript-model.puml
|
|
16
|
+
# Converts plantuml source to SVG image
|
|
17
|
+
java -jar plantuml.jar -v -tsvg doc-metamodel/famix-typescript-model.puml
|
|
18
|
+
# Moves artifacts
|
|
19
|
+
rm -f doc-uml/*
|
|
20
|
+
mv doc-metamodel/*.svg doc-uml
|
package/src/lib/famix/License.md
CHANGED
|
@@ -1,23 +1,23 @@
|
|
|
1
|
-
Portions of the code in the famix directory:
|
|
2
|
-
|
|
3
|
-
MIT License
|
|
4
|
-
|
|
5
|
-
Copyright (c) 2019 Pascal Erni
|
|
6
|
-
|
|
7
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
8
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
9
|
-
in the Software without restriction, including without limitation the rights
|
|
10
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
11
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
12
|
-
furnished to do so, subject to the following conditions:
|
|
13
|
-
|
|
14
|
-
The above copyright notice and this permission notice shall be included in all
|
|
15
|
-
copies or substantial portions of the Software.
|
|
16
|
-
|
|
17
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
18
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
19
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
20
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
21
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
22
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
1
|
+
Portions of the code in the famix directory:
|
|
2
|
+
|
|
3
|
+
MIT License
|
|
4
|
+
|
|
5
|
+
Copyright (c) 2019 Pascal Erni
|
|
6
|
+
|
|
7
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
8
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
9
|
+
in the Software without restriction, including without limitation the rights
|
|
10
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
11
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
12
|
+
furnished to do so, subject to the following conditions:
|
|
13
|
+
|
|
14
|
+
The above copyright notice and this permission notice shall be included in all
|
|
15
|
+
copies or substantial portions of the Software.
|
|
16
|
+
|
|
17
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
18
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
19
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
20
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
21
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
22
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
23
23
|
SOFTWARE.
|
|
@@ -1,56 +1,56 @@
|
|
|
1
|
-
import { FamixBaseElement } from "./famix_base_element";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* This class is used to export Famix elements to JSON
|
|
5
|
-
*/
|
|
6
|
-
export class FamixJSONExporter {
|
|
7
|
-
|
|
8
|
-
private element: FamixBaseElement; // A Famix element to export
|
|
9
|
-
private bufferArray: any = {}; // A buffer to store the properties of the Famix element
|
|
10
|
-
private FamixPrefix = "FamixTypeScript"; // Prefix of the Famix element
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Constructor of the FamixJSONExporter class
|
|
14
|
-
* @param packageClass Name of a Famix class
|
|
15
|
-
* @param element A Famix element to export, this element is an instance of the class named "packageClass"
|
|
16
|
-
*/
|
|
17
|
-
constructor(packageClass: string, element: FamixBaseElement) {
|
|
18
|
-
this.element = element;
|
|
19
|
-
this.bufferArray["FM3"] = this.FamixPrefix + "." + packageClass;
|
|
20
|
-
this.bufferArray["id"] = this.element.id;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* Adds a property to the Famix element
|
|
25
|
-
* @param name Name of the property
|
|
26
|
-
* @param prop A property
|
|
27
|
-
*/
|
|
28
|
-
public addProperty(name: string, prop: unknown): void {
|
|
29
|
-
if (prop instanceof Set) {
|
|
30
|
-
const valueArray: Array<unknown> = [];
|
|
31
|
-
for (const value of Array.from(prop.values())) {
|
|
32
|
-
if (value instanceof FamixBaseElement) {
|
|
33
|
-
valueArray.push({ "ref": value.id });
|
|
34
|
-
}
|
|
35
|
-
else {
|
|
36
|
-
valueArray.push(value);
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
this.bufferArray[name] = valueArray;
|
|
40
|
-
}
|
|
41
|
-
else if (prop instanceof FamixBaseElement) {
|
|
42
|
-
this.bufferArray[name] = { "ref": prop.id };
|
|
43
|
-
}
|
|
44
|
-
else if (prop !== undefined && !(prop instanceof Set)) {
|
|
45
|
-
this.bufferArray[name] = prop;
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* Gets a JSON representation of the Famix element
|
|
51
|
-
* @returns A JSON representation of the Famix element
|
|
52
|
-
*/
|
|
53
|
-
public getJSON(): string {
|
|
54
|
-
return JSON.stringify(this.bufferArray);
|
|
55
|
-
}
|
|
56
|
-
}
|
|
1
|
+
import { FamixBaseElement } from "./famix_base_element";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* This class is used to export Famix elements to JSON
|
|
5
|
+
*/
|
|
6
|
+
export class FamixJSONExporter {
|
|
7
|
+
|
|
8
|
+
private element: FamixBaseElement; // A Famix element to export
|
|
9
|
+
private bufferArray: any = {}; // A buffer to store the properties of the Famix element
|
|
10
|
+
private FamixPrefix = "FamixTypeScript"; // Prefix of the Famix element
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Constructor of the FamixJSONExporter class
|
|
14
|
+
* @param packageClass Name of a Famix class
|
|
15
|
+
* @param element A Famix element to export, this element is an instance of the class named "packageClass"
|
|
16
|
+
*/
|
|
17
|
+
constructor(packageClass: string, element: FamixBaseElement) {
|
|
18
|
+
this.element = element;
|
|
19
|
+
this.bufferArray["FM3"] = this.FamixPrefix + "." + packageClass;
|
|
20
|
+
this.bufferArray["id"] = this.element.id;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Adds a property to the Famix element
|
|
25
|
+
* @param name Name of the property
|
|
26
|
+
* @param prop A property
|
|
27
|
+
*/
|
|
28
|
+
public addProperty(name: string, prop: unknown): void {
|
|
29
|
+
if (prop instanceof Set) {
|
|
30
|
+
const valueArray: Array<unknown> = [];
|
|
31
|
+
for (const value of Array.from(prop.values())) {
|
|
32
|
+
if (value instanceof FamixBaseElement) {
|
|
33
|
+
valueArray.push({ "ref": value.id });
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
valueArray.push(value);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
this.bufferArray[name] = valueArray;
|
|
40
|
+
}
|
|
41
|
+
else if (prop instanceof FamixBaseElement) {
|
|
42
|
+
this.bufferArray[name] = { "ref": prop.id };
|
|
43
|
+
}
|
|
44
|
+
else if (prop !== undefined && !(prop instanceof Set)) {
|
|
45
|
+
this.bufferArray[name] = prop;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Gets a JSON representation of the Famix element
|
|
51
|
+
* @returns A JSON representation of the Famix element
|
|
52
|
+
*/
|
|
53
|
+
public getJSON(): string {
|
|
54
|
+
return JSON.stringify(this.bufferArray);
|
|
55
|
+
}
|
|
56
|
+
}
|