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.
Files changed (190) hide show
  1. package/.eslintrc.json +24 -24
  2. package/.vscode/settings.json +4 -0
  3. package/LICENSE +24 -24
  4. package/README.md +78 -78
  5. package/TODO +1 -0
  6. package/arwea-fix.json +1 -0
  7. package/bogus.ts +3 -0
  8. package/class-diagram.puml +792 -0
  9. package/debug.txt +13332 -0
  10. package/debuglog.txt +12073 -0
  11. package/dist/analyze.js +2 -2
  12. package/dist/analyze_functions/process_functions.js +84 -64
  13. package/dist/famix2puml.js +126 -0
  14. package/dist/famix_functions/EntityDictionary.js +865 -503
  15. package/dist/famix_functions/helpers_creation.js +1 -1
  16. package/dist/fqn.js +44 -11
  17. package/dist/getClasses-arrow-body.js +43 -0
  18. package/dist/lib/famix/famix_JSON_exporter.js +1 -1
  19. package/dist/lib/famix/famix_base_element.js +1 -1
  20. package/dist/lib/famix/famix_repository.js +57 -2
  21. package/dist/lib/famix/index.js +1 -1
  22. package/dist/lib/famix/model/famix/access.js +1 -1
  23. package/dist/lib/famix/model/famix/accessor.js +1 -1
  24. package/dist/lib/famix/model/famix/alias.js +1 -1
  25. package/dist/lib/famix/model/famix/arrow_function.js +1 -1
  26. package/dist/lib/famix/model/famix/behavioral_entity.js +1 -1
  27. package/dist/lib/famix/model/famix/class.js +1 -1
  28. package/dist/lib/famix/model/famix/comment.js +1 -1
  29. package/dist/lib/famix/model/famix/concretisation.js +1 -1
  30. package/dist/lib/famix/model/famix/container_entity.js +1 -1
  31. package/dist/lib/famix/model/famix/decorator.js +1 -1
  32. package/dist/lib/famix/model/famix/entity.js +1 -1
  33. package/dist/lib/famix/model/famix/enum.js +1 -1
  34. package/dist/lib/famix/model/famix/enum_value.js +1 -1
  35. package/dist/lib/famix/model/famix/function.js +1 -1
  36. package/dist/lib/famix/model/famix/import_clause.js +1 -1
  37. package/dist/lib/famix/model/famix/index.js +1 -1
  38. package/dist/lib/famix/model/famix/indexed_file_anchor.js +1 -1
  39. package/dist/lib/famix/model/famix/inheritance.js +1 -1
  40. package/dist/lib/famix/model/famix/interface.js +1 -1
  41. package/dist/lib/famix/model/famix/invocation.js +1 -1
  42. package/dist/lib/famix/model/famix/method.js +1 -1
  43. package/dist/lib/famix/model/famix/module.js +1 -1
  44. package/dist/lib/famix/model/famix/named_entity.js +1 -1
  45. package/dist/lib/famix/model/famix/parameter.js +1 -1
  46. package/dist/lib/famix/model/famix/parameter_concretisation.js +1 -1
  47. package/dist/lib/famix/model/famix/parameter_type.js +1 -1
  48. package/dist/lib/famix/model/famix/parametric_arrow_function.js +1 -1
  49. package/dist/lib/famix/model/famix/parametric_class.js +1 -1
  50. package/dist/lib/famix/model/famix/parametric_function.js +1 -1
  51. package/dist/lib/famix/model/famix/parametric_interface.js +1 -1
  52. package/dist/lib/famix/model/famix/parametric_method.js +1 -1
  53. package/dist/lib/famix/model/famix/primitive_type.js +1 -1
  54. package/dist/lib/famix/model/famix/property.js +1 -1
  55. package/dist/lib/famix/model/famix/reference.js +1 -1
  56. package/dist/lib/famix/model/famix/scoping_entity.js +1 -1
  57. package/dist/lib/famix/model/famix/script_entity.js +1 -1
  58. package/dist/lib/famix/model/famix/source_anchor.js +1 -1
  59. package/dist/lib/famix/model/famix/source_language.js +1 -1
  60. package/dist/lib/famix/model/famix/sourced_entity.js +1 -1
  61. package/dist/lib/famix/model/famix/structural_entity.js +1 -1
  62. package/dist/lib/famix/model/famix/type.js +1 -1
  63. package/dist/lib/famix/model/famix/variable.js +1 -1
  64. package/dist/lib/famix/src/famix_JSON_exporter.js +55 -0
  65. package/dist/lib/famix/src/famix_base_element.js +18 -0
  66. package/dist/lib/famix/src/famix_repository.js +224 -0
  67. package/dist/lib/famix/src/index.js +31 -0
  68. package/dist/lib/famix/src/model/famix/access.js +40 -0
  69. package/dist/lib/famix/src/model/famix/accessor.js +17 -0
  70. package/dist/lib/famix/src/model/famix/alias.js +33 -0
  71. package/dist/lib/famix/src/model/famix/arrowFunction.js +17 -0
  72. package/dist/lib/famix/src/model/famix/arrow_function.js +17 -0
  73. package/dist/lib/famix/src/model/famix/behavioral_entity.js +79 -0
  74. package/dist/lib/famix/src/model/famix/class.js +71 -0
  75. package/dist/lib/famix/src/model/famix/comment.js +39 -0
  76. package/dist/lib/famix/src/model/famix/concretisation.js +31 -0
  77. package/dist/lib/famix/src/model/famix/container_entity.js +126 -0
  78. package/dist/lib/famix/src/model/famix/decorator.js +32 -0
  79. package/dist/lib/famix/src/model/famix/entity.js +17 -0
  80. package/dist/lib/famix/src/model/famix/enum.js +31 -0
  81. package/dist/lib/famix/src/model/famix/enum_value.js +25 -0
  82. package/dist/lib/famix/src/model/famix/function.js +17 -0
  83. package/dist/lib/famix/src/model/famix/implicit_variable.js +17 -0
  84. package/dist/lib/famix/src/model/famix/import_clause.js +41 -0
  85. package/dist/lib/famix/src/model/famix/index.js +86 -0
  86. package/dist/lib/famix/src/model/famix/indexed_file_anchor.js +38 -0
  87. package/dist/lib/famix/src/model/famix/inheritance.js +33 -0
  88. package/dist/lib/famix/src/model/famix/interface.js +64 -0
  89. package/dist/lib/famix/src/model/famix/invocation.js +54 -0
  90. package/dist/lib/famix/src/model/famix/method.js +67 -0
  91. package/dist/lib/famix/src/model/famix/module.js +60 -0
  92. package/dist/lib/famix/src/model/famix/named_entity.js +78 -0
  93. package/dist/lib/famix/src/model/famix/parameter.js +25 -0
  94. package/dist/lib/famix/src/model/famix/parameterConcretisation.js +44 -0
  95. package/dist/lib/famix/src/model/famix/parameter_concretisation.js +44 -0
  96. package/dist/lib/famix/src/model/famix/parameter_type.js +45 -0
  97. package/dist/lib/famix/src/model/famix/parametricArrowFunction.js +29 -0
  98. package/dist/lib/famix/src/model/famix/parametric_arrow_function.js +31 -0
  99. package/dist/lib/famix/src/model/famix/parametric_class.js +44 -0
  100. package/dist/lib/famix/src/model/famix/parametric_function.js +31 -0
  101. package/dist/lib/famix/src/model/famix/parametric_interface.js +44 -0
  102. package/dist/lib/famix/src/model/famix/parametric_method.js +31 -0
  103. package/dist/lib/famix/src/model/famix/primitive_type.js +17 -0
  104. package/dist/lib/famix/src/model/famix/property.js +73 -0
  105. package/dist/lib/famix/src/model/famix/reference.js +33 -0
  106. package/dist/lib/famix/src/model/famix/scoping_entity.js +36 -0
  107. package/dist/lib/famix/src/model/famix/script_entity.js +29 -0
  108. package/dist/lib/famix/src/model/famix/source_anchor.js +27 -0
  109. package/dist/lib/famix/src/model/famix/source_language.js +35 -0
  110. package/dist/lib/famix/src/model/famix/sourced_entity.js +60 -0
  111. package/dist/lib/famix/src/model/famix/structural_entity.js +39 -0
  112. package/dist/lib/famix/src/model/famix/text_anchor.js +38 -0
  113. package/dist/lib/famix/src/model/famix/type.js +73 -0
  114. package/dist/lib/famix/src/model/famix/variable.js +24 -0
  115. package/dist/lib/ts-complex/cyclomatic-service.js +1 -1
  116. package/dist/refactorer/refactor-getter-setter.js +1 -1
  117. package/dist/ts2famix-cli-wrapper.js +1 -1
  118. package/dist/ts2famix-cli.js +1 -1
  119. package/doc-uml/famix-typescript-model.puml +607 -607
  120. package/eslint.config.mjs +28 -0
  121. package/fqn-model.json +1 -0
  122. package/iterateGenericTypes.ts +69 -0
  123. package/out/class-diagram/class-diagram.svg +1 -0
  124. package/package.json +70 -50
  125. package/sample.json +1 -0
  126. package/sample.ts +1 -0
  127. package/src/analyze.ts +120 -120
  128. package/src/analyze_functions/process_functions.ts +1040 -1019
  129. package/src/famix_functions/EntityDictionary.ts +2016 -1593
  130. package/src/famix_functions/helpers_creation.ts +135 -135
  131. package/src/fqn.ts +50 -16
  132. package/src/generate_uml.sh +20 -20
  133. package/src/lib/famix/License.md +22 -22
  134. package/src/lib/famix/famix_JSON_exporter.ts +56 -56
  135. package/src/lib/famix/famix_base_element.ts +22 -22
  136. package/src/lib/famix/famix_repository.ts +278 -243
  137. package/src/lib/famix/index.ts +8 -8
  138. package/src/lib/famix/model/famix/access.ts +50 -50
  139. package/src/lib/famix/model/famix/accessor.ts +15 -15
  140. package/src/lib/famix/model/famix/alias.ts +39 -39
  141. package/src/lib/famix/model/famix/arrow_function.ts +15 -15
  142. package/src/lib/famix/model/famix/behavioral_entity.ts +97 -97
  143. package/src/lib/famix/model/famix/class.ts +85 -85
  144. package/src/lib/famix/model/famix/comment.ts +47 -47
  145. package/src/lib/famix/model/famix/concretisation.ts +40 -40
  146. package/src/lib/famix/model/famix/container_entity.ts +160 -160
  147. package/src/lib/famix/model/famix/decorator.ts +37 -37
  148. package/src/lib/famix/model/famix/entity.ts +15 -15
  149. package/src/lib/famix/model/famix/enum.ts +30 -30
  150. package/src/lib/famix/model/famix/enum_value.ts +28 -28
  151. package/src/lib/famix/model/famix/function.ts +15 -15
  152. package/src/lib/famix/model/famix/import_clause.ts +51 -51
  153. package/src/lib/famix/model/famix/index.ts +41 -41
  154. package/src/lib/famix/model/famix/indexed_file_anchor.ts +46 -46
  155. package/src/lib/famix/model/famix/inheritance.ts +40 -40
  156. package/src/lib/famix/model/famix/interface.ts +75 -75
  157. package/src/lib/famix/model/famix/invocation.ts +65 -65
  158. package/src/lib/famix/model/famix/method.ts +89 -89
  159. package/src/lib/famix/model/famix/module.ts +71 -71
  160. package/src/lib/famix/model/famix/named_entity.ts +95 -95
  161. package/src/lib/famix/model/famix/parameter.ts +28 -28
  162. package/src/lib/famix/model/famix/parameter_concretisation.ts +51 -51
  163. package/src/lib/famix/model/famix/parameter_type.ts +58 -58
  164. package/src/lib/famix/model/famix/parametric_arrow_function.ts +32 -32
  165. package/src/lib/famix/model/famix/parametric_class.ts +49 -49
  166. package/src/lib/famix/model/famix/parametric_function.ts +32 -32
  167. package/src/lib/famix/model/famix/parametric_interface.ts +49 -49
  168. package/src/lib/famix/model/famix/parametric_method.ts +32 -32
  169. package/src/lib/famix/model/famix/primitive_type.ts +15 -15
  170. package/src/lib/famix/model/famix/property.ts +94 -94
  171. package/src/lib/famix/model/famix/reference.ts +40 -40
  172. package/src/lib/famix/model/famix/scoping_entity.ts +35 -35
  173. package/src/lib/famix/model/famix/script_entity.ts +34 -34
  174. package/src/lib/famix/model/famix/source_anchor.ts +30 -30
  175. package/src/lib/famix/model/famix/source_language.ts +35 -35
  176. package/src/lib/famix/model/famix/sourced_entity.ts +70 -70
  177. package/src/lib/famix/model/famix/structural_entity.ts +43 -43
  178. package/src/lib/famix/model/famix/type.ts +87 -87
  179. package/src/lib/famix/model/famix/variable.ts +27 -27
  180. package/src/lib/famix/package.json +28 -28
  181. package/src/lib/ts-complex/cyclomatic-service.ts +83 -83
  182. package/src/refactorer/refactor-getter-setter.ts +140 -140
  183. package/src/ts2famix-cli-wrapper.ts +21 -21
  184. package/src/ts2famix-cli.ts +60 -60
  185. package/stats.txt +3091 -0
  186. package/tabby-debug-output.txt +19433 -0
  187. package/ts2famix.log +22656 -0
  188. package/tsconfig.check-tests.json +14 -14
  189. package/tsconfig.json +72 -72
  190. 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 { TypeDeclaration } 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: TypeDeclaration): 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
- }
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, ClassExpression, 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, 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 { TypeDeclaration } from "./famix_functions/EntityDictionary";
4
+ import { TSMorphTypeDeclaration } from "./famix_functions/EntityDictionary";
5
5
 
6
- type FQNNode = SourceFile | VariableDeclaration | ArrowFunction | Identifier | MethodDeclaration | MethodSignature | FunctionDeclaration | FunctionExpression | PropertyDeclaration | TypeDeclaration | EnumDeclaration | ImportDeclaration | ImportEqualsDeclaration | CallExpression | GetAccessorDeclaration | SetAccessorDeclaration | ConstructorDeclaration | TypeParameterDeclaration | ClassDeclaration | InterfaceDeclaration | Decorator | ModuleDeclaration;
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
- let parts: string[] = [];
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
- let name = Node.isIdentifier(currentNode) ? currentNode.getText()
44
+ const name = Node.isIdentifier(currentNode) ? currentNode.getText()
34
45
  : getNameOfNode(currentNode) /* currentNode.getName() */ || 'Unnamed_' + currentNode.getKindName() + `(${lc})`;
35
46
  parts.unshift(name);
36
- } else if (Node.isArrowFunction(currentNode) ||
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
- //console.log(`Ignoring node kind: ${currentNode.getKindName()}`);
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
- const relativePath = entityDictionary.convertToRelativePath(
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
- let parts: string[] = [];
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
- const cKind = a.asKind(SyntaxKind.ClassDeclaration);
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
- const iKind = a.asKind(SyntaxKind.InterfaceDeclaration);
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
- const mKind = a.asKind(SyntaxKind.MethodDeclaration);
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
- const fKind = a.asKind(SyntaxKind.FunctionDeclaration);
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
  }
@@ -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
@@ -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
+ }