ts2famix 1.4.1 → 2.0.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 (210) hide show
  1. package/LICENSE +1 -0
  2. package/README.md +30 -61
  3. package/dist/analyze.js +4 -2
  4. package/dist/analyze_functions/process_functions.js +285 -131
  5. package/dist/famix_functions/EntityDictionary.js +864 -231
  6. package/dist/famix_functions/helpers_creation.js +61 -10
  7. package/dist/fqn.js +160 -111
  8. package/dist/lib/famix/famix_JSON_exporter.js +55 -0
  9. package/dist/lib/famix/famix_base_element.js +18 -0
  10. package/dist/lib/famix/famix_repository.js +224 -0
  11. package/dist/lib/famix/{src/index.js → index.js} +1 -0
  12. package/dist/lib/famix/model/famix/access.js +40 -0
  13. package/dist/lib/famix/model/famix/accessor.js +17 -0
  14. package/dist/lib/famix/model/famix/alias.js +33 -0
  15. package/dist/lib/famix/model/famix/arrow_function.js +17 -0
  16. package/dist/lib/famix/model/famix/behavioral_entity.js +79 -0
  17. package/dist/lib/famix/model/famix/class.js +71 -0
  18. package/dist/lib/famix/model/famix/comment.js +39 -0
  19. package/dist/lib/famix/model/famix/concretisation.js +31 -0
  20. package/dist/lib/famix/model/famix/container_entity.js +126 -0
  21. package/dist/lib/famix/model/famix/decorator.js +32 -0
  22. package/dist/lib/famix/model/famix/entity.js +17 -0
  23. package/dist/lib/famix/model/famix/enum.js +31 -0
  24. package/dist/lib/famix/model/famix/enum_value.js +25 -0
  25. package/dist/lib/famix/model/famix/function.js +17 -0
  26. package/dist/lib/famix/model/famix/import_clause.js +41 -0
  27. package/dist/lib/famix/model/famix/index.js +86 -0
  28. package/dist/lib/famix/model/famix/indexed_file_anchor.js +38 -0
  29. package/dist/lib/famix/model/famix/inheritance.js +33 -0
  30. package/dist/lib/famix/model/famix/interface.js +64 -0
  31. package/dist/lib/famix/model/famix/invocation.js +54 -0
  32. package/dist/lib/famix/model/famix/method.js +67 -0
  33. package/dist/lib/famix/model/famix/module.js +60 -0
  34. package/dist/lib/famix/model/famix/named_entity.js +78 -0
  35. package/dist/lib/famix/model/famix/parameter.js +25 -0
  36. package/dist/lib/famix/model/famix/parameter_concretisation.js +44 -0
  37. package/dist/lib/famix/model/famix/parameter_type.js +45 -0
  38. package/dist/lib/famix/model/famix/parametric_arrow_function.js +31 -0
  39. package/dist/lib/famix/model/famix/parametric_class.js +44 -0
  40. package/dist/lib/famix/model/famix/parametric_function.js +31 -0
  41. package/dist/lib/famix/model/famix/parametric_interface.js +44 -0
  42. package/dist/lib/famix/model/famix/parametric_method.js +31 -0
  43. package/dist/lib/famix/model/famix/primitive_type.js +17 -0
  44. package/dist/lib/famix/model/famix/property.js +73 -0
  45. package/dist/lib/famix/model/famix/reference.js +33 -0
  46. package/dist/lib/famix/model/famix/scoping_entity.js +36 -0
  47. package/dist/lib/famix/model/famix/script_entity.js +29 -0
  48. package/dist/lib/famix/model/famix/source_anchor.js +27 -0
  49. package/dist/lib/famix/model/famix/source_language.js +35 -0
  50. package/dist/lib/famix/model/famix/sourced_entity.js +60 -0
  51. package/dist/lib/famix/model/famix/structural_entity.js +39 -0
  52. package/dist/lib/famix/model/famix/type.js +73 -0
  53. package/dist/lib/famix/model/famix/variable.js +24 -0
  54. package/dist/lib/ts-complex/cyclomatic-service.js +3 -3
  55. package/dist/refactorer/refactor-getter-setter.js +142 -0
  56. package/dist/ts2famix-cli-wrapper.js +42 -0
  57. package/dist/ts2famix-cli.js +8 -1
  58. package/dist/ts2famix-tsconfig.js +1 -0
  59. package/doc-uml/famix-typescript-model.puml +608 -0
  60. package/doc-uml/famix-typescript-model.svg +1 -0
  61. package/jest.config.json +2 -1
  62. package/package.json +13 -12
  63. package/src/analyze.ts +24 -23
  64. package/src/analyze_functions/process_functions.ts +310 -129
  65. package/src/famix_functions/EntityDictionary.ts +949 -271
  66. package/src/famix_functions/helpers_creation.ts +64 -6
  67. package/src/fqn.ts +169 -96
  68. package/{dist/lib/famix/src/famix_JSON_exporter.js → src/lib/famix/famix_JSON_exporter.ts} +16 -14
  69. package/src/lib/famix/famix_base_element.ts +22 -0
  70. package/{dist/lib/famix/src/famix_repository.js → src/lib/famix/famix_repository.ts} +96 -75
  71. package/src/lib/famix/model/famix/access.ts +50 -0
  72. package/src/lib/famix/model/famix/alias.ts +39 -0
  73. package/src/lib/famix/{src/model/famix/implicit_variable.ts → model/famix/arrow_function.ts} +3 -3
  74. package/src/lib/famix/model/famix/behavioral_entity.ts +97 -0
  75. package/src/lib/famix/model/famix/class.ts +85 -0
  76. package/src/lib/famix/model/famix/comment.ts +47 -0
  77. package/src/lib/famix/model/famix/concretisation.ts +40 -0
  78. package/src/lib/famix/model/famix/container_entity.ts +160 -0
  79. package/src/lib/famix/model/famix/decorator.ts +37 -0
  80. package/src/lib/famix/model/famix/enum.ts +30 -0
  81. package/src/lib/famix/model/famix/enum_value.ts +28 -0
  82. package/src/lib/famix/model/famix/import_clause.ts +51 -0
  83. package/src/lib/famix/{src/model → model}/famix/index.ts +8 -7
  84. package/src/lib/famix/model/famix/indexed_file_anchor.ts +46 -0
  85. package/src/lib/famix/model/famix/inheritance.ts +40 -0
  86. package/src/lib/famix/model/famix/interface.ts +75 -0
  87. package/src/lib/famix/model/famix/invocation.ts +65 -0
  88. package/src/lib/famix/model/famix/method.ts +89 -0
  89. package/src/lib/famix/model/famix/module.ts +71 -0
  90. package/src/lib/famix/model/famix/named_entity.ts +95 -0
  91. package/src/lib/famix/{src/model → model}/famix/parameter.ts +11 -12
  92. package/src/lib/famix/model/famix/parameter_concretisation.ts +51 -0
  93. package/src/lib/famix/model/famix/parameter_type.ts +58 -0
  94. package/src/lib/famix/model/famix/parametric_arrow_function.ts +32 -0
  95. package/src/lib/famix/model/famix/parametric_class.ts +49 -0
  96. package/src/lib/famix/model/famix/parametric_function.ts +32 -0
  97. package/src/lib/famix/model/famix/parametric_interface.ts +49 -0
  98. package/src/lib/famix/model/famix/parametric_method.ts +32 -0
  99. package/src/lib/famix/model/famix/primitive_type.ts +15 -0
  100. package/src/lib/famix/model/famix/property.ts +94 -0
  101. package/src/lib/famix/model/famix/reference.ts +40 -0
  102. package/src/lib/famix/model/famix/scoping_entity.ts +35 -0
  103. package/src/lib/famix/model/famix/script_entity.ts +34 -0
  104. package/src/lib/famix/model/famix/source_anchor.ts +30 -0
  105. package/src/lib/famix/model/famix/source_language.ts +35 -0
  106. package/src/lib/famix/model/famix/sourced_entity.ts +70 -0
  107. package/src/lib/famix/model/famix/structural_entity.ts +43 -0
  108. package/src/lib/famix/model/famix/type.ts +87 -0
  109. package/src/lib/famix/model/famix/variable.ts +27 -0
  110. package/src/lib/famix/package.json +1 -1
  111. package/src/lib/ts-complex/cyclomatic-service.ts +10 -10
  112. package/src/refactorer/refactor-getter-setter.ts +140 -0
  113. package/src/ts2famix-cli-wrapper.ts +21 -0
  114. package/src/ts2famix-cli.ts +8 -2
  115. package/tsconfig.check-tests.json +14 -0
  116. package/tsconfig.json +71 -69
  117. package/dist/famix2puml.js +0 -125
  118. package/dist/lib/famix/src/famix_base_element.js +0 -17
  119. package/dist/lib/famix/src/model/famix/access.js +0 -39
  120. package/dist/lib/famix/src/model/famix/accessor.js +0 -16
  121. package/dist/lib/famix/src/model/famix/alias.js +0 -32
  122. package/dist/lib/famix/src/model/famix/association.js +0 -36
  123. package/dist/lib/famix/src/model/famix/behavioral_entity.js +0 -81
  124. package/dist/lib/famix/src/model/famix/class.js +0 -70
  125. package/dist/lib/famix/src/model/famix/comment.js +0 -38
  126. package/dist/lib/famix/src/model/famix/container_entity.js +0 -125
  127. package/dist/lib/famix/src/model/famix/decorator.js +0 -31
  128. package/dist/lib/famix/src/model/famix/entity.js +0 -16
  129. package/dist/lib/famix/src/model/famix/enum.js +0 -30
  130. package/dist/lib/famix/src/model/famix/enum_value.js +0 -24
  131. package/dist/lib/famix/src/model/famix/function.js +0 -16
  132. package/dist/lib/famix/src/model/famix/implicit_variable.js +0 -16
  133. package/dist/lib/famix/src/model/famix/import_clause.js +0 -39
  134. package/dist/lib/famix/src/model/famix/index.js +0 -83
  135. package/dist/lib/famix/src/model/famix/indexed_file_anchor.js +0 -51
  136. package/dist/lib/famix/src/model/famix/inheritance.js +0 -32
  137. package/dist/lib/famix/src/model/famix/interface.js +0 -63
  138. package/dist/lib/famix/src/model/famix/invocation.js +0 -53
  139. package/dist/lib/famix/src/model/famix/method.js +0 -66
  140. package/dist/lib/famix/src/model/famix/module.js +0 -31
  141. package/dist/lib/famix/src/model/famix/named_entity.js +0 -77
  142. package/dist/lib/famix/src/model/famix/namespace.js +0 -24
  143. package/dist/lib/famix/src/model/famix/parameter.js +0 -24
  144. package/dist/lib/famix/src/model/famix/parameter_type.js +0 -24
  145. package/dist/lib/famix/src/model/famix/parameterizable_class.js +0 -30
  146. package/dist/lib/famix/src/model/famix/parameterizable_interface.js +0 -30
  147. package/dist/lib/famix/src/model/famix/parameterized_type.js +0 -36
  148. package/dist/lib/famix/src/model/famix/primitive_type.js +0 -16
  149. package/dist/lib/famix/src/model/famix/property.js +0 -44
  150. package/dist/lib/famix/src/model/famix/reference.js +0 -32
  151. package/dist/lib/famix/src/model/famix/scoping_entity.js +0 -35
  152. package/dist/lib/famix/src/model/famix/script_entity.js +0 -30
  153. package/dist/lib/famix/src/model/famix/source_anchor.js +0 -26
  154. package/dist/lib/famix/src/model/famix/source_language.js +0 -35
  155. package/dist/lib/famix/src/model/famix/sourced_entity.js +0 -59
  156. package/dist/lib/famix/src/model/famix/structural_entity.js +0 -38
  157. package/dist/lib/famix/src/model/famix/text_anchor.js +0 -37
  158. package/dist/lib/famix/src/model/famix/type.js +0 -71
  159. package/dist/lib/famix/src/model/famix/variable.js +0 -23
  160. package/doc-uml/metamodel-full.svg +0 -1
  161. package/doc-uml/metamodel.svg +0 -1
  162. package/jest.config-old.ts +0 -199
  163. package/plantuml.jar +0 -0
  164. package/src/famix2puml.ts +0 -119
  165. package/src/lib/famix/package-lock.json +0 -301
  166. package/src/lib/famix/readme.md +0 -5
  167. package/src/lib/famix/src/famix_JSON_exporter.ts +0 -56
  168. package/src/lib/famix/src/famix_base_element.ts +0 -22
  169. package/src/lib/famix/src/famix_repository.ts +0 -243
  170. package/src/lib/famix/src/model/famix/access.ts +0 -53
  171. package/src/lib/famix/src/model/famix/alias.ts +0 -41
  172. package/src/lib/famix/src/model/famix/association.ts +0 -44
  173. package/src/lib/famix/src/model/famix/behavioral_entity.ts +0 -107
  174. package/src/lib/famix/src/model/famix/class.ts +0 -86
  175. package/src/lib/famix/src/model/famix/comment.ts +0 -50
  176. package/src/lib/famix/src/model/famix/container_entity.ts +0 -165
  177. package/src/lib/famix/src/model/famix/decorator.ts +0 -39
  178. package/src/lib/famix/src/model/famix/enum.ts +0 -31
  179. package/src/lib/famix/src/model/famix/enum_value.ts +0 -29
  180. package/src/lib/famix/src/model/famix/import_clause.ts +0 -53
  181. package/src/lib/famix/src/model/famix/indexed_file_anchor.ts +0 -71
  182. package/src/lib/famix/src/model/famix/inheritance.ts +0 -42
  183. package/src/lib/famix/src/model/famix/interface.ts +0 -75
  184. package/src/lib/famix/src/model/famix/invocation.ts +0 -68
  185. package/src/lib/famix/src/model/famix/method.ts +0 -96
  186. package/src/lib/famix/src/model/famix/module.ts +0 -31
  187. package/src/lib/famix/src/model/famix/named_entity.ts +0 -98
  188. package/src/lib/famix/src/model/famix/namespace.ts +0 -28
  189. package/src/lib/famix/src/model/famix/parameter_type.ts +0 -33
  190. package/src/lib/famix/src/model/famix/parameterizable_class.ts +0 -31
  191. package/src/lib/famix/src/model/famix/parameterizable_interface.ts +0 -31
  192. package/src/lib/famix/src/model/famix/parameterized_type.ts +0 -40
  193. package/src/lib/famix/src/model/famix/primitive_type.ts +0 -15
  194. package/src/lib/famix/src/model/famix/property.ts +0 -54
  195. package/src/lib/famix/src/model/famix/reference.ts +0 -42
  196. package/src/lib/famix/src/model/famix/scoping_entity.ts +0 -35
  197. package/src/lib/famix/src/model/famix/script_entity.ts +0 -38
  198. package/src/lib/famix/src/model/famix/source_anchor.ts +0 -31
  199. package/src/lib/famix/src/model/famix/source_language.ts +0 -37
  200. package/src/lib/famix/src/model/famix/sourced_entity.ts +0 -73
  201. package/src/lib/famix/src/model/famix/structural_entity.ts +0 -44
  202. package/src/lib/famix/src/model/famix/text_anchor.ts +0 -49
  203. package/src/lib/famix/src/model/famix/type.ts +0 -88
  204. package/src/lib/famix/src/model/famix/variable.ts +0 -28
  205. package/src/lib/famix/tsconfig.json +0 -27
  206. package/src/lib/famix/tslint.json +0 -15
  207. /package/src/lib/famix/{src/index.ts → index.ts} +0 -0
  208. /package/src/lib/famix/{src/model → model}/famix/accessor.ts +0 -0
  209. /package/src/lib/famix/{src/model → model}/famix/entity.ts +0 -0
  210. /package/src/lib/famix/{src/model → model}/famix/function.ts +0 -0
@@ -1,6 +1,7 @@
1
- import * as Famix from "../lib/famix/src/model/famix";
1
+ import * as Famix from "../lib/famix/model/famix";
2
2
  import { logger } from "../analyze";
3
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";
4
5
 
5
6
  interface SearchParameters {
6
7
  searchArray: string[];
@@ -44,7 +45,7 @@ export function getSubTypeName(fmxNamedEntity: Famix.NamedEntity) {
44
45
  fmxNamedEntity instanceof Famix.Parameter ? 'Parameter' :
45
46
  fmxNamedEntity instanceof Famix.Property ? 'Property' :
46
47
  'NamedEntity';
47
- logger.debug(`${fmxNamedEntity.getName()} is of type ${name}`);
48
+ logger.debug(`${fmxNamedEntity.name} is of type ${name}`);
48
49
  return name;
49
50
  }
50
51
 
@@ -64,7 +65,21 @@ export function computeSignature(text: string): string {
64
65
  * @returns The ancestor of the node
65
66
  */
66
67
  export function findAncestor(node: Identifier): Node {
67
- return node.getAncestors().find(a => a.getKind() === SyntaxKind.MethodDeclaration || a.getKind() === SyntaxKind.Constructor || a.getKind() === SyntaxKind.FunctionDeclaration || a.getKind() === SyntaxKind.FunctionExpression || a.getKind() === SyntaxKind.ModuleDeclaration || a.getKind() === SyntaxKind.SourceFile || a.getKindName() === "GetAccessor" || a.getKindName() === "SetAccessor" || a.getKind() === SyntaxKind.ClassDeclaration);
68
+ 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
68
83
  }
69
84
 
70
85
  /**
@@ -72,6 +87,49 @@ export function findAncestor(node: Identifier): Node {
72
87
  * @param element A ts-morph element
73
88
  * @returns The ancestor of the ts-morph element
74
89
  */
75
- export function findTypeAncestor(element: TypeAliasDeclaration | PropertyDeclaration | PropertySignature | MethodDeclaration | ConstructorDeclaration | MethodSignature | GetAccessorDeclaration | SetAccessorDeclaration | FunctionDeclaration | FunctionExpression | ParameterDeclaration | VariableDeclaration | EnumMember): Node {
76
- return element.getAncestors().find(a => a.getKind() === SyntaxKind.MethodDeclaration || a.getKind() === SyntaxKind.Constructor || a.getKind() === SyntaxKind.MethodSignature || a.getKind() === SyntaxKind.FunctionDeclaration || a.getKind() === SyntaxKind.FunctionExpression || a.getKind() === SyntaxKind.ModuleDeclaration || a.getKind() === SyntaxKind.SourceFile || a.getKindName() === "GetAccessor" || a.getKindName() === "SetAccessor" || a.getKind() === SyntaxKind.ClassDeclaration || a.getKind() === SyntaxKind.InterfaceDeclaration);
77
- }
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
+ }
package/src/fqn.ts CHANGED
@@ -1,65 +1,92 @@
1
- import * as ts from "ts-morph";
2
- import { entityDictionary } from "./analyze";
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";
2
+ import { entityDictionary, logger } from "./analyze";
3
3
  import path from "path";
4
+ import { TypeDeclaration } from "./famix_functions/EntityDictionary";
4
5
 
5
- /**
6
- * Gets the fully qualified name of a node, if it has one
7
- * @param node A node
8
- * @returns The fully qualified name of the node, or undefined if it doesn't have one
9
- */
10
- export function getFQN(node: ts.Node): string {
11
- const absolutePathProject = entityDictionary.famixRep.getAbsolutePath();
12
-
13
- if (node instanceof ts.SourceFile) {
14
- return entityDictionary.convertToRelativePath(path.normalize(node.getFilePath()),
15
- absolutePathProject).replace(/\\/sg, "/");
16
- }
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;
17
7
 
18
- const symbol = node.getSymbol();
19
- if (!symbol) {
20
- return undefined;
21
- }
8
+ function isFQNNode(node: Node): node is FQNNode {
9
+ 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);
22
10
 
23
- const declarations = symbol.getDeclarations();
24
- if (!declarations) {
25
- return undefined;
26
- }
11
+ }
12
+
13
+ export function getFQN(node: FQNNode | Node): string {
14
+ const absolutePathProject = entityDictionary.famixRep.getAbsolutePath();
27
15
 
28
- const sourceFile = declarations[0].getSourceFile();
29
- if (!sourceFile) {
30
- return undefined;
16
+ const sourceFile = node.getSourceFile();
17
+ let parts: string[] = [];
18
+ let currentNode: Node | undefined = node;
19
+
20
+ while (currentNode && !Node.isSourceFile(currentNode)) {
21
+ const { line, column } = sourceFile.getLineAndColumnAtPos(currentNode.getStart());
22
+ const lc = `${line}:${column}`;
23
+ if (Node.isClassDeclaration(currentNode) ||
24
+ Node.isClassExpression(currentNode) ||
25
+ Node.isInterfaceDeclaration(currentNode) ||
26
+ Node.isFunctionDeclaration(currentNode) ||
27
+ Node.isMethodDeclaration(currentNode) ||
28
+ Node.isModuleDeclaration(currentNode) ||
29
+ Node.isVariableDeclaration(currentNode) ||
30
+ Node.isGetAccessorDeclaration(currentNode) ||
31
+ Node.isSetAccessorDeclaration(currentNode) ||
32
+ Node.isIdentifier(currentNode)) {
33
+ let name = Node.isIdentifier(currentNode) ? currentNode.getText()
34
+ : getNameOfNode(currentNode) /* currentNode.getName() */ || 'Unnamed_' + currentNode.getKindName() + `(${lc})`;
35
+ parts.unshift(name);
36
+ } else if (Node.isArrowFunction(currentNode) ||
37
+ Node.isBlock(currentNode) ||
38
+ Node.isForInStatement(currentNode) ||
39
+ Node.isForOfStatement(currentNode) ||
40
+ Node.isForStatement(currentNode) ||
41
+ Node.isCatchClause(currentNode)) {
42
+ parts.unshift(`${currentNode.getKindName()}(${lc})`);
43
+ } else if (Node.isConstructorDeclaration(currentNode)) {
44
+ parts.unshift(`constructor`);
45
+ } else {
46
+ // For other kinds, you might want to handle them specifically or ignore
47
+ //console.log(`Ignoring node kind: ${currentNode.getKindName()}`);
48
+ }
49
+ currentNode = currentNode.getParent();
31
50
  }
32
51
 
33
- const absolutePath = path.normalize(sourceFile.getFilePath());
34
- const positionNodeModules = absolutePath.indexOf('node_modules');
35
- let pathInProject: string = "";
36
52
 
37
- if (positionNodeModules !== -1) {
38
- const pathFromNodeModules = absolutePath.substring(positionNodeModules);
39
- pathInProject = pathFromNodeModules;
40
- } else {
41
- pathInProject = entityDictionary.convertToRelativePath(absolutePath, absolutePathProject).replace(/\\/g, "/");
42
- }
43
53
 
44
- const qualifiedNameParts: Array<string> = [];
54
+ // Prepend the relative path of the source file
55
+ const relativePath = entityDictionary.convertToRelativePath(
56
+ path.normalize(sourceFile.getFilePath()),
57
+ absolutePathProject).replace(/\\/sg, "/");
58
+ parts.unshift(`{${relativePath}}`);
59
+ const fqn = parts.join(".") + `[${node.getKindName()}]`; // disambiguate
45
60
 
46
- const nodeName = this.getNameOfNode(node);
47
- if (nodeName) qualifiedNameParts.push(nodeName);
61
+ logger.debug(fqn);
62
+ return fqn;
63
+ }
48
64
 
49
- const ancestors = node.getAncestors();
50
- ancestors.forEach(a => {
51
- const partName = this.getNameOfNode(a);
52
- if (partName) qualifiedNameParts.push(partName);
53
- });
54
65
 
55
- qualifiedNameParts.pop();
66
+ export function getUniqueFQN(node: Node): string | undefined {
67
+ const absolutePathProject = entityDictionary.famixRep.getAbsolutePath();
68
+ let parts: string[] = [];
56
69
 
57
- if (qualifiedNameParts.length > 0) {
58
- return `{${pathInProject}}.${qualifiedNameParts.reverse().join(".")}`;
59
- }
60
- else {
61
- return undefined;
70
+ if (node instanceof SourceFile) {
71
+ return entityDictionary.convertToRelativePath(path.normalize(node.getFilePath()), absolutePathProject).replace(/\\/g, "/");
62
72
  }
73
+
74
+ let currentNode: Node | undefined = node;
75
+ while (currentNode) {
76
+ if (Node.isSourceFile(currentNode)) {
77
+ const relativePath = entityDictionary.convertToRelativePath(path.normalize(currentNode.getFilePath()), absolutePathProject).replace(/\\/g, "/");
78
+ parts.unshift(relativePath); // Add file path at the start
79
+ break;
80
+ } else if (currentNode.getSymbol()) {
81
+ const name = currentNode.getSymbol()!.getName();
82
+ // For anonymous nodes, use kind and position as unique identifiers
83
+ const identifier = name !== "__computed" ? name : `${currentNode.getKindName()}_${currentNode.getStartLinePos()}`;
84
+ parts.unshift(identifier);
85
+ }
86
+ currentNode = currentNode.getParent();
87
+ }
88
+
89
+ return parts.join("::");
63
90
  }
64
91
 
65
92
  /**
@@ -67,70 +94,116 @@ export function getFQN(node: ts.Node): string {
67
94
  * @param a A node
68
95
  * @returns The name of the node, or an empty string if it doesn't have one
69
96
  */
70
- export function getNameOfNode(a: ts.Node<ts.ts.Node>): string {
97
+ export function getNameOfNode(a: Node): string {
71
98
  switch (a.getKind()) {
72
- case ts.SyntaxKind.SourceFile:
73
- return a.asKind(ts.SyntaxKind.SourceFile)?.getBaseName();
74
-
75
- case ts.SyntaxKind.ModuleDeclaration:
76
- return a.asKind(ts.SyntaxKind.ModuleDeclaration)?.getName();
77
-
78
- case ts.SyntaxKind.ClassDeclaration:
79
- return a.asKind(ts.SyntaxKind.ClassDeclaration)?.getName();
80
-
81
- case ts.SyntaxKind.InterfaceDeclaration:
82
- return a.asKind(ts.SyntaxKind.InterfaceDeclaration)?.getName();
99
+ case SyntaxKind.SourceFile:
100
+ return a.asKind(SyntaxKind.SourceFile)!.getBaseName();
101
+
102
+ case SyntaxKind.ModuleDeclaration:
103
+ return a.asKind(SyntaxKind.ModuleDeclaration)!.getName();
104
+
105
+ case SyntaxKind.ClassDeclaration:
106
+ const cKind = a.asKind(SyntaxKind.ClassDeclaration);
107
+ if (cKind && cKind.getTypeParameters().length > 0) {
108
+ return cKind.getName() + getParameters(a);
109
+ } else {
110
+ return cKind?.getName() || "";
111
+ }
112
+
113
+ case SyntaxKind.InterfaceDeclaration:
114
+ const iKind = a.asKind(SyntaxKind.InterfaceDeclaration);
115
+ if (iKind && iKind.getTypeParameters().length > 0) {
116
+ return iKind.getName() + getParameters(a);
117
+ } else {
118
+ return iKind?.getName() || "";
119
+ }
83
120
 
84
- case ts.SyntaxKind.PropertyDeclaration:
85
- return a.asKind(ts.SyntaxKind.PropertyDeclaration)?.getName();
121
+ case SyntaxKind.PropertyDeclaration:
122
+ return a.asKind(SyntaxKind.PropertyDeclaration)!.getName();
86
123
 
87
- case ts.SyntaxKind.PropertySignature:
88
- return a.asKind(ts.SyntaxKind.PropertySignature)?.getName();
124
+ case SyntaxKind.PropertySignature:
125
+ return a.asKind(SyntaxKind.PropertySignature)!.getName();
89
126
 
90
- case ts.SyntaxKind.MethodDeclaration:
91
- return a.asKind(ts.SyntaxKind.MethodDeclaration)?.getName();
92
-
93
- case ts.SyntaxKind.MethodSignature:
94
- return a.asKind(ts.SyntaxKind.MethodSignature)?.getName();
95
-
96
- case ts.SyntaxKind.GetAccessor:
97
- return a.asKind(ts.SyntaxKind.GetAccessor)?.getName();
98
-
99
- case ts.SyntaxKind.SetAccessor:
100
- return a.asKind(ts.SyntaxKind.SetAccessor)?.getName();
127
+ case SyntaxKind.MethodDeclaration:
128
+ const mKind = a.asKind(SyntaxKind.MethodDeclaration);
129
+ if (mKind && mKind.getTypeParameters().length > 0) {
130
+ return mKind.getName() + getParameters(a);
131
+ } else {
132
+ return mKind?.getName() || "";
133
+ }
134
+
135
+ case SyntaxKind.MethodSignature:
136
+ return a.asKind(SyntaxKind.MethodSignature)!.getName();
137
+
138
+ case SyntaxKind.GetAccessor:
139
+ return a.asKind(SyntaxKind.GetAccessor)!.getName();
140
+
141
+ case SyntaxKind.SetAccessor:
142
+ return a.asKind(SyntaxKind.SetAccessor)!.getName();
101
143
 
102
- case ts.SyntaxKind.FunctionDeclaration:
103
- return a.asKind(ts.SyntaxKind.FunctionDeclaration)?.getName();
104
-
105
- case ts.SyntaxKind.FunctionExpression:
106
- return (a.asKind(ts.SyntaxKind.FunctionExpression)?.getName()) ? a.asKind(ts.SyntaxKind.FunctionExpression)?.getName() : "anonymous";
144
+ case SyntaxKind.FunctionDeclaration:
145
+ const fKind = a.asKind(SyntaxKind.FunctionDeclaration);
146
+ if (fKind && fKind.getTypeParameters().length > 0) {
147
+ return fKind.getName() + getParameters(a);
148
+ } else {
149
+ return fKind?.getName() || "";
150
+ }
151
+
152
+ case SyntaxKind.FunctionExpression:
153
+ return a.asKind(SyntaxKind.FunctionExpression)?.getName() || "anonymous";
107
154
 
108
- case ts.SyntaxKind.Parameter:
109
- return a.asKind(ts.SyntaxKind.Parameter)?.getName();
155
+ case SyntaxKind.Parameter:
156
+ return a.asKind(SyntaxKind.Parameter)!.getName();
110
157
 
111
- case ts.SyntaxKind.VariableDeclaration:
112
- return a.asKind(ts.SyntaxKind.VariableDeclaration)?.getName();
158
+ case SyntaxKind.VariableDeclaration:
159
+ return a.asKind(SyntaxKind.VariableDeclaration)!.getName();
113
160
 
114
- case ts.SyntaxKind.Decorator:
115
- return "@" + a.asKind(ts.SyntaxKind.Decorator)?.getName();
161
+ case SyntaxKind.Decorator:
162
+ return "@" + a.asKind(SyntaxKind.Decorator)!.getName();
116
163
 
117
- case ts.SyntaxKind.TypeParameter:
118
- return a.asKind(ts.SyntaxKind.TypeParameter)?.getName();
164
+ case SyntaxKind.TypeParameter:
165
+ return a.asKind(SyntaxKind.TypeParameter)!.getName();
119
166
 
120
- case ts.SyntaxKind.EnumDeclaration:
121
- return a.asKind(ts.SyntaxKind.EnumDeclaration)?.getName();
167
+ case SyntaxKind.EnumDeclaration:
168
+ return a.asKind(SyntaxKind.EnumDeclaration)!.getName();
122
169
 
123
- case ts.SyntaxKind.EnumMember:
124
- return a.asKind(ts.SyntaxKind.EnumMember)?.getName();
170
+ case SyntaxKind.EnumMember:
171
+ return a.asKind(SyntaxKind.EnumMember)!.getName();
125
172
 
126
- case ts.SyntaxKind.TypeAliasDeclaration:
127
- return a.asKind(ts.SyntaxKind.TypeAliasDeclaration)?.getName();
173
+ case SyntaxKind.TypeAliasDeclaration:
174
+ return a.asKind(SyntaxKind.TypeAliasDeclaration)!.getName();
128
175
 
129
- case ts.SyntaxKind.Constructor:
176
+ case SyntaxKind.Constructor:
130
177
  return "constructor";
131
178
 
132
179
  default:
133
180
  // ancestor hasn't got a useful name
134
181
  return "";
135
182
  }
136
- }
183
+ }
184
+
185
+ /**
186
+ * Gets the name of a node, if it has one
187
+ * @param a A node
188
+ * @returns The name of the node, or an empty string if it doesn't have one
189
+ */
190
+ export function getParameters(a: Node): string {
191
+ let paramString = "";
192
+ switch (a.getKind()) {
193
+ case SyntaxKind.ClassDeclaration:
194
+ paramString = "<" + a.asKind(SyntaxKind.ClassDeclaration)?.getTypeParameters().map(tp => tp.getName()).join(", ") + ">";
195
+ break;
196
+ case SyntaxKind.InterfaceDeclaration:
197
+ paramString = "<" + a.asKind(SyntaxKind.InterfaceDeclaration)?.getTypeParameters().map(tp => tp.getName()).join(", ") + ">";
198
+ break;
199
+ case SyntaxKind.MethodDeclaration:
200
+ paramString = "<" + a.asKind(SyntaxKind.MethodDeclaration)?.getTypeParameters().map(tp => tp.getName()).join(", ") + ">";
201
+ break;
202
+ case SyntaxKind.FunctionDeclaration:
203
+ paramString = "<" + a.asKind(SyntaxKind.FunctionDeclaration)?.getTypeParameters().map(tp => tp.getName()).join(", ") + ">";
204
+ break;
205
+ default:
206
+ throw new Error(`getParameters called on a node that doesn't have parameters: ${a.getKindName()}`);
207
+ }
208
+ return paramString;
209
+ }
@@ -1,33 +1,35 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.FamixJSONExporter = void 0;
4
- const famix_base_element_1 = require("./famix_base_element");
1
+ import { FamixBaseElement } from "./famix_base_element";
2
+
5
3
  /**
6
4
  * This class is used to export Famix elements to JSON
7
5
  */
8
- class FamixJSONExporter {
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
+
9
12
  /**
10
13
  * Constructor of the FamixJSONExporter class
11
14
  * @param packageClass Name of a Famix class
12
15
  * @param element A Famix element to export, this element is an instance of the class named "packageClass"
13
16
  */
14
- constructor(packageClass, element) {
15
- this.bufferArray = {}; // A buffer to store the properties of the Famix element
16
- this.FamixPrefix = "FamixTypeScript"; // Prefix of the Famix element
17
+ constructor(packageClass: string, element: FamixBaseElement) {
17
18
  this.element = element;
18
19
  this.bufferArray["FM3"] = this.FamixPrefix + "." + packageClass;
19
20
  this.bufferArray["id"] = this.element.id;
20
21
  }
22
+
21
23
  /**
22
24
  * Adds a property to the Famix element
23
25
  * @param name Name of the property
24
26
  * @param prop A property
25
27
  */
26
- addProperty(name, prop) {
28
+ public addProperty(name: string, prop: unknown): void {
27
29
  if (prop instanceof Set) {
28
- const valueArray = [];
30
+ const valueArray: Array<unknown> = [];
29
31
  for (const value of Array.from(prop.values())) {
30
- if (value instanceof famix_base_element_1.FamixBaseElement) {
32
+ if (value instanceof FamixBaseElement) {
31
33
  valueArray.push({ "ref": value.id });
32
34
  }
33
35
  else {
@@ -36,19 +38,19 @@ class FamixJSONExporter {
36
38
  }
37
39
  this.bufferArray[name] = valueArray;
38
40
  }
39
- else if (prop instanceof famix_base_element_1.FamixBaseElement) {
41
+ else if (prop instanceof FamixBaseElement) {
40
42
  this.bufferArray[name] = { "ref": prop.id };
41
43
  }
42
44
  else if (prop !== undefined && !(prop instanceof Set)) {
43
45
  this.bufferArray[name] = prop;
44
46
  }
45
47
  }
48
+
46
49
  /**
47
50
  * Gets a JSON representation of the Famix element
48
51
  * @returns A JSON representation of the Famix element
49
52
  */
50
- getJSON() {
53
+ public getJSON(): string {
51
54
  return JSON.stringify(this.bufferArray);
52
55
  }
53
56
  }
54
- exports.FamixJSONExporter = FamixJSONExporter;
@@ -0,0 +1,22 @@
1
+ import { logger } from "../../analyze";
2
+ import { FamixJSONExporter } from "./famix_JSON_exporter";
3
+ // import { FamixRepository } from "./famix_repository";
4
+
5
+ export abstract class FamixBaseElement {
6
+
7
+ public id!: number;
8
+
9
+ // constructor(repo: FamixRepository) {
10
+ // repo.addElement(this);
11
+ // }
12
+
13
+ constructor() {
14
+ }
15
+
16
+ public abstract getJSON(): string;
17
+
18
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
19
+ public addPropertiesToExporter(exporter: FamixJSONExporter): void {
20
+ logger.debug("addPropertiesToExporter not implemented for " + this.constructor.name + `(${exporter})`);
21
+ }
22
+ }