ts2famix 2.1.0-beta.2 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc.json +24 -24
- package/LICENSE +24 -24
- package/README.md +78 -78
- package/dist/analyze.js +3 -3
- package/dist/analyze_functions/process_functions.js +92 -62
- package/dist/famix_functions/EntityDictionary.js +672 -597
- package/dist/famix_functions/helpers_creation.js +18 -12
- package/dist/fqn.js +351 -18
- 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 +14 -5
- 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 +2 -2
- 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/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 +619 -607
- package/doc-uml/famix-typescript-model.svg +1 -1
- package/eslint.config.mjs +28 -28
- package/jest.config.json +1 -1
- package/package.json +70 -70
- package/src/analyze.ts +120 -120
- package/src/analyze_functions/process_functions.ts +1069 -1040
- package/src/famix_functions/EntityDictionary.ts +2061 -2016
- package/src/famix_functions/helpers_creation.ts +143 -135
- package/src/fqn.ts +416 -50
- 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 +288 -278
- 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/tsconfig.check-tests.json +14 -14
- package/tsconfig.json +73 -72
- package/.vscode/settings.json +0 -4
- package/TODO +0 -1
- package/arwea-fix.json +0 -1
- package/bogus.ts +0 -3
- package/class-diagram.puml +0 -792
- package/debug.txt +0 -13332
- package/debuglog.txt +0 -12073
- package/dist/famix2puml.js +0 -126
- package/dist/getClasses-arrow-body.js +0 -43
- package/dist/lib/famix/src/famix_JSON_exporter.js +0 -55
- package/dist/lib/famix/src/famix_base_element.js +0 -18
- package/dist/lib/famix/src/famix_repository.js +0 -224
- package/dist/lib/famix/src/index.js +0 -31
- package/dist/lib/famix/src/model/famix/access.js +0 -40
- package/dist/lib/famix/src/model/famix/accessor.js +0 -17
- package/dist/lib/famix/src/model/famix/alias.js +0 -33
- package/dist/lib/famix/src/model/famix/arrowFunction.js +0 -17
- package/dist/lib/famix/src/model/famix/arrow_function.js +0 -17
- package/dist/lib/famix/src/model/famix/behavioral_entity.js +0 -79
- package/dist/lib/famix/src/model/famix/class.js +0 -71
- package/dist/lib/famix/src/model/famix/comment.js +0 -39
- package/dist/lib/famix/src/model/famix/concretisation.js +0 -31
- package/dist/lib/famix/src/model/famix/container_entity.js +0 -126
- package/dist/lib/famix/src/model/famix/decorator.js +0 -32
- package/dist/lib/famix/src/model/famix/entity.js +0 -17
- package/dist/lib/famix/src/model/famix/enum.js +0 -31
- package/dist/lib/famix/src/model/famix/enum_value.js +0 -25
- package/dist/lib/famix/src/model/famix/function.js +0 -17
- package/dist/lib/famix/src/model/famix/implicit_variable.js +0 -17
- package/dist/lib/famix/src/model/famix/import_clause.js +0 -41
- package/dist/lib/famix/src/model/famix/index.js +0 -86
- package/dist/lib/famix/src/model/famix/indexed_file_anchor.js +0 -38
- package/dist/lib/famix/src/model/famix/inheritance.js +0 -33
- package/dist/lib/famix/src/model/famix/interface.js +0 -64
- package/dist/lib/famix/src/model/famix/invocation.js +0 -54
- package/dist/lib/famix/src/model/famix/method.js +0 -67
- package/dist/lib/famix/src/model/famix/module.js +0 -60
- package/dist/lib/famix/src/model/famix/named_entity.js +0 -78
- package/dist/lib/famix/src/model/famix/parameter.js +0 -25
- package/dist/lib/famix/src/model/famix/parameterConcretisation.js +0 -44
- package/dist/lib/famix/src/model/famix/parameter_concretisation.js +0 -44
- package/dist/lib/famix/src/model/famix/parameter_type.js +0 -45
- package/dist/lib/famix/src/model/famix/parametricArrowFunction.js +0 -29
- package/dist/lib/famix/src/model/famix/parametric_arrow_function.js +0 -31
- package/dist/lib/famix/src/model/famix/parametric_class.js +0 -44
- package/dist/lib/famix/src/model/famix/parametric_function.js +0 -31
- package/dist/lib/famix/src/model/famix/parametric_interface.js +0 -44
- package/dist/lib/famix/src/model/famix/parametric_method.js +0 -31
- package/dist/lib/famix/src/model/famix/primitive_type.js +0 -17
- package/dist/lib/famix/src/model/famix/property.js +0 -73
- package/dist/lib/famix/src/model/famix/reference.js +0 -33
- package/dist/lib/famix/src/model/famix/scoping_entity.js +0 -36
- package/dist/lib/famix/src/model/famix/script_entity.js +0 -29
- package/dist/lib/famix/src/model/famix/source_anchor.js +0 -27
- package/dist/lib/famix/src/model/famix/source_language.js +0 -35
- package/dist/lib/famix/src/model/famix/sourced_entity.js +0 -60
- package/dist/lib/famix/src/model/famix/structural_entity.js +0 -39
- package/dist/lib/famix/src/model/famix/text_anchor.js +0 -38
- package/dist/lib/famix/src/model/famix/type.js +0 -73
- package/dist/lib/famix/src/model/famix/variable.js +0 -24
- package/fqn-model.json +0 -1
- package/iterateGenericTypes.ts +0 -69
- package/out/class-diagram/class-diagram.svg +0 -1
- package/sample.json +0 -1
- package/sample.ts +0 -1
- package/stats.txt +0 -3091
- package/tabby-debug-output.txt +0 -19433
- package/ts2famix.log +0 -22656
- package/validate-references.js +0 -103
package/src/fqn.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
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";
|
|
1
|
+
import { ArrowFunction, CallExpression, ClassDeclaration, ConstructorDeclaration, Decorator, EnumDeclaration, ExpressionWithTypeArguments, 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
4
|
import { TSMorphTypeDeclaration } from "./famix_functions/EntityDictionary";
|
|
@@ -10,26 +10,253 @@ function isFQNNode(node: Node): node is FQNNode {
|
|
|
10
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);
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
/**
|
|
14
|
+
* Builds a map of method positions to their property keys in object literals.
|
|
15
|
+
* Scans all variable declarations in a source file, targeting object literals with any keys
|
|
16
|
+
* (e.g., `3: { method() {} }` or `add: { compute() {} }`), and maps each method's start position to its key.
|
|
17
|
+
* Logs each step for debugging.
|
|
18
|
+
*
|
|
19
|
+
* @param sourceFile The TypeScript source file to analyze
|
|
20
|
+
* @returns A Map where keys are method start positions and values are their property keys (e.g., "3", "add")
|
|
21
|
+
*/
|
|
22
|
+
function buildStageMethodMap(sourceFile: SourceFile): Map<number, string> {
|
|
23
|
+
const stageMap = new Map<number, string>();
|
|
24
|
+
|
|
25
|
+
sourceFile.getVariableDeclarations().forEach(varDecl => {
|
|
26
|
+
// const varName = varDecl.getName();
|
|
27
|
+
const initializer = varDecl.getInitializer();
|
|
28
|
+
|
|
29
|
+
if (!initializer || !Node.isObjectLiteralExpression(initializer)) {
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
initializer.getProperties().forEach(prop => {
|
|
34
|
+
let key: string | undefined;
|
|
35
|
+
|
|
36
|
+
if (Node.isPropertyAssignment(prop)) {
|
|
37
|
+
const nameNode = prop.getNameNode();
|
|
38
|
+
|
|
39
|
+
if (Node.isIdentifier(nameNode)) {
|
|
40
|
+
key = nameNode.getText();
|
|
41
|
+
} else if (Node.isStringLiteral(nameNode)) {
|
|
42
|
+
key = nameNode.getText().replace(/^"(.+)"$/, '$1').replace(/^'(.+)'$/, '$1');
|
|
43
|
+
} else if (Node.isNumericLiteral(nameNode)) {
|
|
44
|
+
key = nameNode.getText();
|
|
45
|
+
} else if (Node.isComputedPropertyName(nameNode)) {
|
|
46
|
+
const expression = nameNode.getExpression();
|
|
47
|
+
if (Node.isIdentifier(expression)) {
|
|
48
|
+
// Resolve variable value if possible
|
|
49
|
+
const symbol = expression.getSymbol();
|
|
50
|
+
if (symbol) {
|
|
51
|
+
const decl = symbol.getDeclarations()[0];
|
|
52
|
+
if (Node.isVariableDeclaration(decl) && decl.getInitializer()) {
|
|
53
|
+
const init = decl.getInitializer()!;
|
|
54
|
+
if (Node.isStringLiteral(init) || Node.isNumericLiteral(init)) {
|
|
55
|
+
key = init.getText().replace(/^"(.+)"$/, '$1').replace(/^'(.+)'$/, '$1');
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
if (!key) {
|
|
60
|
+
key = expression.getText();
|
|
61
|
+
}
|
|
62
|
+
} else if (Node.isBinaryExpression(expression) && expression.getOperatorToken().getText() === '+') {
|
|
63
|
+
// Handle simple string concatenation (e.g., "A" + "B")
|
|
64
|
+
const left = expression.getLeft();
|
|
65
|
+
const right = expression.getRight();
|
|
66
|
+
if (Node.isStringLiteral(left) && Node.isStringLiteral(right)) {
|
|
67
|
+
key = left.getLiteralText() + right.getLiteralText();
|
|
68
|
+
}
|
|
69
|
+
} else if (Node.isTemplateExpression(expression)) {
|
|
70
|
+
// Handle template literals (e.g., `key-${1}`)
|
|
71
|
+
const head = expression.getHead().getLiteralText();
|
|
72
|
+
const spans = expression.getTemplateSpans();
|
|
73
|
+
if (spans.length === 1 && Node.isNumericLiteral(spans[0].getExpression())) {
|
|
74
|
+
const num = spans[0].getExpression().getText();
|
|
75
|
+
key = `${head}${num}`;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
if (!key) {
|
|
79
|
+
key = expression.getText(); // Fallback
|
|
80
|
+
}
|
|
81
|
+
} else {
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const propInitializer = prop.getInitializer();
|
|
86
|
+
if (propInitializer && Node.isObjectLiteralExpression(propInitializer)) {
|
|
87
|
+
propInitializer.getDescendantsOfKind(SyntaxKind.MethodDeclaration).forEach(method => {
|
|
88
|
+
// const methodName = method.getName();
|
|
89
|
+
const pos = method.getStart();
|
|
90
|
+
if (key) {
|
|
91
|
+
stageMap.set(pos, key);
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
return stageMap;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Builds a map of method positions to their index in class/interface/namespace declarations
|
|
104
|
+
* @param sourceFile The TypeScript source file to analyze
|
|
105
|
+
* @returns A Map where keys are method start positions and values are their positional index (1-based)
|
|
106
|
+
*/
|
|
107
|
+
function buildMethodPositionMap(sourceFile: SourceFile): Map<number, number> {
|
|
108
|
+
const positionMap = new Map<number, number>();
|
|
109
|
+
// console.log(`[buildMethodPositionMap] Starting analysis for file: ${sourceFile.getFilePath()}`);
|
|
110
|
+
|
|
111
|
+
// Helper function to process modules recursively
|
|
112
|
+
function processModule(moduleNode: ModuleDeclaration, modulePath: string) {
|
|
113
|
+
// console.log(`[buildMethodPositionMap] Processing module: ${modulePath}`);
|
|
114
|
+
|
|
115
|
+
// Handle functions directly in the module
|
|
116
|
+
const functions = moduleNode.getFunctions();
|
|
117
|
+
const functionCounts = new Map<string, number>();
|
|
118
|
+
|
|
119
|
+
functions.forEach(func => {
|
|
120
|
+
const funcName = func.getName() || `Unnamed_Function(${func.getStart()})`;
|
|
121
|
+
const count = (functionCounts.get(funcName) || 0) + 1;
|
|
122
|
+
functionCounts.set(funcName, count);
|
|
123
|
+
positionMap.set(func.getStart(), count);
|
|
124
|
+
// console.log(`[buildMethodPositionMap] Module function: ${funcName}, position: ${func.getStart()}, index: ${count}`);
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
// Handle classes within the module
|
|
128
|
+
const classes = moduleNode.getClasses();
|
|
129
|
+
classes.forEach(classNode => {
|
|
130
|
+
// console.log(`[buildMethodPositionMap] Processing class in module: ${classNode.getName() || 'Unnamed'}`);
|
|
131
|
+
const methods = classNode.getMethods();
|
|
132
|
+
const methodCounts = new Map<string, number>();
|
|
133
|
+
|
|
134
|
+
methods.forEach(method => {
|
|
135
|
+
const methodName = method.getName();
|
|
136
|
+
const count = (methodCounts.get(methodName) || 0) + 1;
|
|
137
|
+
methodCounts.set(methodName, count);
|
|
138
|
+
positionMap.set(method.getStart(), count);
|
|
139
|
+
// console.log(`[buildMethodPositionMap] Module class method: ${methodName}, position: ${method.getStart()}, index: ${count}`);
|
|
140
|
+
});
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
// Handle interfaces within the module
|
|
144
|
+
const interfaces = moduleNode.getInterfaces();
|
|
145
|
+
interfaces.forEach(interfaceNode => {
|
|
146
|
+
// console.log(`[buildMethodPositionMap] Processing interface in module: ${interfaceNode.getName() || 'Unnamed'}`);
|
|
147
|
+
const methods = interfaceNode.getMethods();
|
|
148
|
+
const methodCounts = new Map<string, number>();
|
|
149
|
+
|
|
150
|
+
methods.forEach(method => {
|
|
151
|
+
const methodName = method.getName();
|
|
152
|
+
const count = (methodCounts.get(methodName) || 0) + 1;
|
|
153
|
+
methodCounts.set(methodName, count);
|
|
154
|
+
positionMap.set(method.getStart(), count);
|
|
155
|
+
// console.log(`[buildMethodPositionMap] Module interface method: ${methodName}, position: ${method.getStart()}, index: ${count}`);
|
|
156
|
+
});
|
|
157
|
+
});
|
|
15
158
|
|
|
159
|
+
// Recursively process nested modules
|
|
160
|
+
const nestedModules = moduleNode.getModules();
|
|
161
|
+
nestedModules.forEach(nestedModule => {
|
|
162
|
+
if (Node.isModuleDeclaration(nestedModule)) {
|
|
163
|
+
const nestedModuleName = nestedModule.getName();
|
|
164
|
+
const newModulePath = `${modulePath}.${nestedModuleName}`;
|
|
165
|
+
processModule(nestedModule, newModulePath);
|
|
166
|
+
}
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
function trackArrowFunctions(container: Node) {
|
|
172
|
+
const arrows = container.getDescendantsOfKind(SyntaxKind.ArrowFunction);
|
|
173
|
+
arrows.forEach(arrow => {
|
|
174
|
+
const parent = arrow.getParent();
|
|
175
|
+
if (Node.isBlock(parent) || Node.isSourceFile(parent)) {
|
|
176
|
+
// Use negative numbers for arrow functions to distinguish from methods
|
|
177
|
+
positionMap.set(arrow.getStart(), -1 * (positionMap.size + 1));
|
|
178
|
+
// console.log(`[buildMethodPositionMap] Arrow function at ${arrow.getStart()}`);
|
|
179
|
+
}
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// Handle top-level classes
|
|
184
|
+
sourceFile.getClasses().forEach(classNode => {
|
|
185
|
+
// console.log(`[buildMethodPositionMap] Processing class: ${classNode.getName() || 'Unnamed'}`);
|
|
186
|
+
const methods = classNode.getMethods();
|
|
187
|
+
const methodCounts = new Map<string, number>();
|
|
188
|
+
|
|
189
|
+
methods.forEach(method => {
|
|
190
|
+
const methodName = method.getName();
|
|
191
|
+
const count = (methodCounts.get(methodName) || 0) + 1;
|
|
192
|
+
methodCounts.set(methodName, count);
|
|
193
|
+
positionMap.set(method.getStart(), count);
|
|
194
|
+
// console.log(`[buildMethodPositionMap] Class method: ${methodName}, position: ${method.getStart()}, index: ${count}`);
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
methods.forEach(method => trackArrowFunctions(method));
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
// Handle top-level interfaces
|
|
201
|
+
sourceFile.getInterfaces().forEach(interfaceNode => {
|
|
202
|
+
// console.log(`[buildMethodPositionMap] Processing interface: ${interfaceNode.getName() || 'Unnamed'}`);
|
|
203
|
+
const methods = interfaceNode.getMethods();
|
|
204
|
+
const methodCounts = new Map<string, number>();
|
|
205
|
+
|
|
206
|
+
methods.forEach(method => {
|
|
207
|
+
const methodName = method.getName();
|
|
208
|
+
const count = (methodCounts.get(methodName) || 0) + 1;
|
|
209
|
+
methodCounts.set(methodName, count);
|
|
210
|
+
positionMap.set(method.getStart(), count);
|
|
211
|
+
// console.log(`[buildMethodPositionMap] Interface method: ${methodName}, position: ${method.getStart()}, index: ${count}`);
|
|
212
|
+
});
|
|
213
|
+
methods.forEach(method => trackArrowFunctions(method));
|
|
214
|
+
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
// Handle top-level namespaces/modules
|
|
218
|
+
sourceFile.getModules().forEach(moduleNode => {
|
|
219
|
+
if (Node.isModuleDeclaration(moduleNode)) {
|
|
220
|
+
const moduleName = moduleNode.getName();
|
|
221
|
+
processModule(moduleNode, moduleName);
|
|
222
|
+
}
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
|
|
226
|
+
// console.log(`[buildMethodPositionMap] Final positionMap:`, Array.from(positionMap.entries()));
|
|
227
|
+
return positionMap;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* Generates a fully qualified name (FQN) for a given AST node.
|
|
232
|
+
* Constructs an FQN by traversing the node's ancestry, adding names and keys
|
|
233
|
+
* (numeric or string from object literals ...) as needed, prefixed with the file's relative path.
|
|
234
|
+
*
|
|
235
|
+
* @param node The AST node to generate an FQN for
|
|
236
|
+
* @returns A string representing the node's FQN (e.g., "{path}.operations.add.compute[MethodDeclaration]")
|
|
237
|
+
*/
|
|
238
|
+
export function getFQN(node: FQNNode | Node): string {
|
|
16
239
|
const sourceFile = node.getSourceFile();
|
|
240
|
+
const absolutePathProject = entityDictionary.famixRep.getAbsolutePath();
|
|
17
241
|
const parts: string[] = [];
|
|
18
242
|
let currentNode: Node | undefined = node;
|
|
19
243
|
|
|
244
|
+
const stageMap = buildStageMethodMap(sourceFile);
|
|
245
|
+
const methodPositionMap = buildMethodPositionMap(sourceFile);
|
|
246
|
+
|
|
20
247
|
while (currentNode && !Node.isSourceFile(currentNode)) {
|
|
21
248
|
const { line, column } = sourceFile.getLineAndColumnAtPos(currentNode.getStart());
|
|
22
249
|
const lc = `${line}:${column}`;
|
|
23
|
-
|
|
24
|
-
|
|
250
|
+
|
|
251
|
+
if (Node.isClassDeclaration(currentNode) ||
|
|
252
|
+
Node.isClassExpression(currentNode) ||
|
|
25
253
|
Node.isInterfaceDeclaration(currentNode) ||
|
|
26
|
-
Node.isFunctionDeclaration(currentNode) ||
|
|
27
|
-
Node.isMethodDeclaration(currentNode) ||
|
|
28
|
-
Node.isModuleDeclaration(currentNode) ||
|
|
29
|
-
Node.isVariableDeclaration(currentNode) ||
|
|
254
|
+
Node.isFunctionDeclaration(currentNode) ||
|
|
255
|
+
Node.isMethodDeclaration(currentNode) ||
|
|
256
|
+
Node.isModuleDeclaration(currentNode) ||
|
|
257
|
+
Node.isVariableDeclaration(currentNode) ||
|
|
30
258
|
Node.isGetAccessorDeclaration(currentNode) ||
|
|
31
259
|
Node.isSetAccessorDeclaration(currentNode) ||
|
|
32
|
-
Node.isTypeParameterDeclaration(currentNode) ||
|
|
33
260
|
Node.isPropertyDeclaration(currentNode) ||
|
|
34
261
|
Node.isParameterDeclaration(currentNode) ||
|
|
35
262
|
Node.isDecorator(currentNode) ||
|
|
@@ -41,44 +268,117 @@ export function getFQN(node: FQNNode | Node): string {
|
|
|
41
268
|
Node.isArrayLiteralExpression(currentNode) ||
|
|
42
269
|
Node.isImportSpecifier(currentNode) ||
|
|
43
270
|
Node.isIdentifier(currentNode)) {
|
|
44
|
-
|
|
45
|
-
|
|
271
|
+
let name: string;
|
|
272
|
+
if (Node.isImportSpecifier(currentNode)) {
|
|
273
|
+
const alias = currentNode.getAliasNode()?.getText();
|
|
274
|
+
if (alias) {
|
|
275
|
+
let importDecl: Node | undefined = currentNode;
|
|
276
|
+
while (importDecl && !Node.isImportDeclaration(importDecl)) {
|
|
277
|
+
importDecl = importDecl.getParent();
|
|
278
|
+
}
|
|
279
|
+
const moduleSpecifier = importDecl && Node.isImportDeclaration(importDecl)
|
|
280
|
+
? importDecl.getModuleSpecifier().getLiteralText()
|
|
281
|
+
: "unknown";
|
|
282
|
+
name = currentNode.getName();
|
|
283
|
+
name = `${name} as ${alias}[ImportSpecifier<${moduleSpecifier}>]`;
|
|
284
|
+
} else {
|
|
285
|
+
name = currentNode.getName();
|
|
286
|
+
}
|
|
287
|
+
} else {
|
|
288
|
+
// if constructor, use "constructor" as name
|
|
289
|
+
if (Node.isConstructorDeclaration(currentNode)) {
|
|
290
|
+
name = "constructor";
|
|
291
|
+
} else {
|
|
292
|
+
name = Node.isIdentifier(currentNode) ? currentNode.getText()
|
|
293
|
+
: 'getName' in currentNode && typeof currentNode['getName'] === 'function'
|
|
294
|
+
? ((currentNode as { getName(): string }).getName() +
|
|
295
|
+
((Node.isClassDeclaration(currentNode) ||
|
|
296
|
+
Node.isInterfaceDeclaration(currentNode) ||
|
|
297
|
+
Node.isMethodDeclaration(currentNode) ||
|
|
298
|
+
Node.isFunctionDeclaration(currentNode)) &&
|
|
299
|
+
'getTypeParameters' in currentNode &&
|
|
300
|
+
currentNode.getTypeParameters().length > 0
|
|
301
|
+
? getParameters(currentNode)
|
|
302
|
+
: ''))
|
|
303
|
+
: `Unnamed_${currentNode.getKindName()}(${lc})`;
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
if (Node.isMethodSignature(currentNode)) {
|
|
308
|
+
const method = currentNode as MethodSignature;
|
|
309
|
+
const params = method.getParameters().map(p => {
|
|
310
|
+
const typeText = p.getType().getText().replace(/\s+/g, "");
|
|
311
|
+
return typeText || "any"; // Fallback for untyped parameters
|
|
312
|
+
});
|
|
313
|
+
const returnType = method.getReturnType().getText().replace(/\s+/g, "") || "void";
|
|
314
|
+
name = `${name}(${params.join(",")}):${returnType}`;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
parts.unshift(name);
|
|
318
|
+
|
|
319
|
+
// Apply positional index for MethodDeclaration, MethodSignature, and FunctionDeclaration
|
|
320
|
+
if (Node.isMethodDeclaration(currentNode) ||
|
|
321
|
+
Node.isMethodSignature(currentNode) ||
|
|
322
|
+
Node.isFunctionDeclaration(currentNode)) {
|
|
323
|
+
const key = stageMap.get(currentNode.getStart());
|
|
324
|
+
if (key) {
|
|
325
|
+
parts.unshift(key);
|
|
326
|
+
// console.log(`[getFQN] Applied stageMap key: ${key} for ${currentNode.getKindName()} at position ${currentNode.getStart()}`);
|
|
327
|
+
} else {
|
|
328
|
+
const positionIndex = methodPositionMap.get(currentNode.getStart());
|
|
329
|
+
if (positionIndex && positionIndex > 1) {
|
|
330
|
+
parts.unshift(positionIndex.toString());
|
|
331
|
+
// console.log(`[getFQN] Applied positionIndex: ${positionIndex} for ${currentNode.getKindName()} at position ${currentNode.getStart()}`);
|
|
332
|
+
} else {
|
|
333
|
+
console.log(`[getFQN] No positionIndex applied for ${currentNode.getKindName()} at position ${currentNode.getStart()}, positionIndex: ${positionIndex || 'none'}`);
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
else if (Node.isArrowFunction(currentNode) ||
|
|
339
|
+
Node.isBlock(currentNode) ||
|
|
340
|
+
Node.isForInStatement(currentNode) ||
|
|
341
|
+
Node.isForOfStatement(currentNode) ||
|
|
342
|
+
Node.isForStatement(currentNode) ||
|
|
343
|
+
Node.isCatchClause(currentNode)) {
|
|
344
|
+
const name = `${currentNode.getKindName()}(${lc})`;
|
|
46
345
|
parts.unshift(name);
|
|
47
346
|
}
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
347
|
+
else if (Node.isTypeParameterDeclaration(currentNode)) {
|
|
348
|
+
const arrowParent = currentNode.getFirstAncestorByKind(SyntaxKind.ArrowFunction);
|
|
349
|
+
if (arrowParent) {
|
|
350
|
+
const arrowIndex = Math.abs(methodPositionMap.get(arrowParent.getStart()) || 0);
|
|
351
|
+
if (arrowIndex > 0) {
|
|
352
|
+
parts.unshift(arrowIndex.toString());
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
parts.unshift(currentNode.getName());
|
|
356
|
+
// Removed continue to allow ancestor processing
|
|
357
|
+
}
|
|
358
|
+
else if (Node.isConstructorDeclaration(currentNode)) {
|
|
359
|
+
const name = "constructor";
|
|
360
|
+
parts.unshift(name);
|
|
58
361
|
} else {
|
|
59
|
-
|
|
60
|
-
logger.debug(`Ignoring node kind: ${currentNode.getKindName()}`);
|
|
362
|
+
console.log(`[getFQN] Ignoring node kind: ${currentNode.getKindName()}`);
|
|
61
363
|
}
|
|
364
|
+
|
|
62
365
|
currentNode = currentNode.getParent();
|
|
63
366
|
}
|
|
64
367
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
// Prepend the relative path of the source file
|
|
68
368
|
let relativePath = entityDictionary.convertToRelativePath(
|
|
69
|
-
path.normalize(sourceFile.getFilePath()),
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
}
|
|
369
|
+
path.normalize(sourceFile.getFilePath()),
|
|
370
|
+
absolutePathProject
|
|
371
|
+
).replace(/\\/g, "/");
|
|
372
|
+
|
|
373
|
+
// if (relativePath.includes("..")) {
|
|
374
|
+
// }
|
|
75
375
|
if (relativePath.startsWith("/")) {
|
|
76
|
-
relativePath = relativePath.
|
|
376
|
+
relativePath = relativePath.slice(1);
|
|
77
377
|
}
|
|
78
378
|
parts.unshift(`{${relativePath}}`);
|
|
79
|
-
const fqn = parts.join(".") + `[${node.getKindName()}]`; // disambiguate
|
|
80
379
|
|
|
81
|
-
|
|
380
|
+
const fqn = parts.join(".") + `[${node.getKindName()}]`;
|
|
381
|
+
// console.log(`[getFQN] Final FQN: ${fqn}`);
|
|
82
382
|
return fqn;
|
|
83
383
|
}
|
|
84
384
|
|
|
@@ -121,14 +421,14 @@ export function getNameOfNode(a: Node): string {
|
|
|
121
421
|
let cKind: ClassDeclaration | undefined;
|
|
122
422
|
let iKind: InterfaceDeclaration | undefined;
|
|
123
423
|
let mKind: MethodDeclaration | undefined;
|
|
124
|
-
let fKind: FunctionDeclaration | undefined;
|
|
424
|
+
let fKind: FunctionDeclaration | undefined;
|
|
125
425
|
let alias: TSMorphTypeDeclaration | undefined;
|
|
126
426
|
switch (a.getKind()) {
|
|
127
427
|
case SyntaxKind.SourceFile:
|
|
128
428
|
return a.asKind(SyntaxKind.SourceFile)!.getBaseName();
|
|
129
429
|
|
|
130
430
|
case SyntaxKind.ModuleDeclaration:
|
|
131
|
-
return a.asKind(SyntaxKind.ModuleDeclaration)!.getName();
|
|
431
|
+
return a.asKind(SyntaxKind.ModuleDeclaration)!.getName();
|
|
132
432
|
|
|
133
433
|
case SyntaxKind.ClassDeclaration:
|
|
134
434
|
cKind = a.asKind(SyntaxKind.ClassDeclaration);
|
|
@@ -145,13 +445,13 @@ export function getNameOfNode(a: Node): string {
|
|
|
145
445
|
} else {
|
|
146
446
|
return iKind?.getName() || "";
|
|
147
447
|
}
|
|
148
|
-
|
|
448
|
+
|
|
149
449
|
case SyntaxKind.PropertyDeclaration:
|
|
150
|
-
return a.asKind(SyntaxKind.PropertyDeclaration)!.getName();
|
|
450
|
+
return a.asKind(SyntaxKind.PropertyDeclaration)!.getName();
|
|
151
451
|
|
|
152
452
|
case SyntaxKind.PropertySignature:
|
|
153
|
-
return a.asKind(SyntaxKind.PropertySignature)!.getName();
|
|
154
|
-
|
|
453
|
+
return a.asKind(SyntaxKind.PropertySignature)!.getName();
|
|
454
|
+
|
|
155
455
|
case SyntaxKind.MethodDeclaration:
|
|
156
456
|
mKind = a.asKind(SyntaxKind.MethodDeclaration);
|
|
157
457
|
if (mKind && mKind.getTypeParameters().length > 0) {
|
|
@@ -161,14 +461,14 @@ export function getNameOfNode(a: Node): string {
|
|
|
161
461
|
}
|
|
162
462
|
|
|
163
463
|
case SyntaxKind.MethodSignature:
|
|
164
|
-
return a.asKind(SyntaxKind.MethodSignature)!.getName();
|
|
464
|
+
return a.asKind(SyntaxKind.MethodSignature)!.getName();
|
|
165
465
|
|
|
166
466
|
case SyntaxKind.GetAccessor:
|
|
167
467
|
return a.asKind(SyntaxKind.GetAccessor)!.getName();
|
|
168
468
|
|
|
169
469
|
case SyntaxKind.SetAccessor:
|
|
170
470
|
return a.asKind(SyntaxKind.SetAccessor)!.getName();
|
|
171
|
-
|
|
471
|
+
|
|
172
472
|
case SyntaxKind.FunctionDeclaration:
|
|
173
473
|
fKind = a.asKind(SyntaxKind.FunctionDeclaration);
|
|
174
474
|
if (fKind && fKind.getTypeParameters().length > 0) {
|
|
@@ -179,15 +479,15 @@ export function getNameOfNode(a: Node): string {
|
|
|
179
479
|
|
|
180
480
|
case SyntaxKind.FunctionExpression:
|
|
181
481
|
return a.asKind(SyntaxKind.FunctionExpression)?.getName() || "anonymous";
|
|
182
|
-
|
|
482
|
+
|
|
183
483
|
case SyntaxKind.Parameter:
|
|
184
484
|
return a.asKind(SyntaxKind.Parameter)!.getName();
|
|
185
|
-
|
|
485
|
+
|
|
186
486
|
case SyntaxKind.VariableDeclaration:
|
|
187
487
|
return a.asKind(SyntaxKind.VariableDeclaration)!.getName();
|
|
188
488
|
|
|
189
489
|
case SyntaxKind.Decorator:
|
|
190
|
-
return "@" + a.asKind(SyntaxKind.Decorator)!.getName();
|
|
490
|
+
return "@" + a.asKind(SyntaxKind.Decorator)!.getName();
|
|
191
491
|
|
|
192
492
|
case SyntaxKind.TypeParameter:
|
|
193
493
|
return a.asKind(SyntaxKind.TypeParameter)!.getName();
|
|
@@ -207,13 +507,13 @@ export function getNameOfNode(a: Node): string {
|
|
|
207
507
|
return a.asKind(SyntaxKind.TypeAliasDeclaration)!.getName();
|
|
208
508
|
|
|
209
509
|
case SyntaxKind.Constructor:
|
|
210
|
-
return "constructor";
|
|
211
|
-
|
|
510
|
+
return "constructor";
|
|
511
|
+
|
|
212
512
|
default:
|
|
213
513
|
// throw new Error(`getNameOfNode called on a node that doesn't have a name: ${a.getKindName()}`);
|
|
214
514
|
// ancestor hasn't got a useful name
|
|
215
515
|
return "";
|
|
216
|
-
|
|
516
|
+
}
|
|
217
517
|
}
|
|
218
518
|
|
|
219
519
|
/**
|
|
@@ -241,3 +541,69 @@ export function getParameters(a: Node): string {
|
|
|
241
541
|
}
|
|
242
542
|
return paramString;
|
|
243
543
|
}
|
|
544
|
+
|
|
545
|
+
/**
|
|
546
|
+
* Gets the FQN of an unresolved interface that is being implemented or extended
|
|
547
|
+
* @param unresolvedInheritedClassOrInterface The expression with type arguments representing the interface
|
|
548
|
+
* @returns The FQN of the unresolved interface
|
|
549
|
+
*/
|
|
550
|
+
export function getFQNUnresolvedInheritedClassOrInterface(unresolvedInheritedClassOrInterface: ExpressionWithTypeArguments): string {
|
|
551
|
+
// Check for either ClassDeclaration or InterfaceDeclaration ancestor
|
|
552
|
+
const classAncestor = unresolvedInheritedClassOrInterface.getFirstAncestorByKind(SyntaxKind.ClassDeclaration);
|
|
553
|
+
const interfaceAncestor = unresolvedInheritedClassOrInterface.getFirstAncestorByKind(SyntaxKind.InterfaceDeclaration);
|
|
554
|
+
|
|
555
|
+
// Validate the context
|
|
556
|
+
if (!classAncestor && !interfaceAncestor) {
|
|
557
|
+
throw new Error("getFQNUnresolvedClassOrInterface called on a node that is not in an implements or extends context");
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
// Check if it's a valid implements/extends context
|
|
561
|
+
let isValidContext = false;
|
|
562
|
+
|
|
563
|
+
let classExtendsClass = false;
|
|
564
|
+
|
|
565
|
+
if (classAncestor) {
|
|
566
|
+
// check if the class is extending or implementing an interface
|
|
567
|
+
const extendsClause = classAncestor.getExtends();
|
|
568
|
+
const implementsClause = classAncestor.getImplements();
|
|
569
|
+
isValidContext = (extendsClause !== undefined) || (implementsClause && implementsClause.length > 0);
|
|
570
|
+
classExtendsClass = extendsClause !== undefined;
|
|
571
|
+
} else if (interfaceAncestor) {
|
|
572
|
+
// Check extends clause for interfaces
|
|
573
|
+
const extendsClause = interfaceAncestor.getExtends();
|
|
574
|
+
isValidContext = extendsClause && extendsClause.length > 0;
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
if (!isValidContext) {
|
|
578
|
+
throw new Error("getFQNUnresolvedInterface called on a node that is not in a valid implements or extends context");
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
// get the name of the interface
|
|
582
|
+
const name = unresolvedInheritedClassOrInterface.getExpression().getText();
|
|
583
|
+
|
|
584
|
+
// Find where it's imported - search the entire source file
|
|
585
|
+
const sourceFile = unresolvedInheritedClassOrInterface.getSourceFile();
|
|
586
|
+
const importDecls = sourceFile.getImportDeclarations();
|
|
587
|
+
|
|
588
|
+
for (const importDecl of importDecls) {
|
|
589
|
+
const moduleSpecifier = importDecl.getModuleSpecifierValue();
|
|
590
|
+
const importClause = importDecl.getImportClause();
|
|
591
|
+
|
|
592
|
+
if (importClause) {
|
|
593
|
+
const namedImports = importClause.getNamedImports();
|
|
594
|
+
// declarationName is ClassDeclaration if "class extends class"
|
|
595
|
+
const declarationName = classExtendsClass ? "ClassDeclaration" : "InterfaceDeclaration";
|
|
596
|
+
|
|
597
|
+
for (const namedImport of namedImports) {
|
|
598
|
+
if (namedImport.getName() === name) {
|
|
599
|
+
logger.debug(`Found import for ${name} in ${moduleSpecifier}`);
|
|
600
|
+
return `{module:${moduleSpecifier}}.${name}[${declarationName}]`;
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
}
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
// If not found, return a default FQN format
|
|
607
|
+
return `{unknown-module}.${name}[InterfaceDeclaration]`;
|
|
608
|
+
}
|
|
609
|
+
|
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.
|