ts2famix 2.0.0 → 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 (212) hide show
  1. package/LICENSE +1 -0
  2. package/README.md +29 -60
  3. package/dist/analyze.js +1 -1
  4. package/dist/analyze_functions/process_functions.js +49 -43
  5. package/dist/famix_functions/EntityDictionary.js +309 -182
  6. package/dist/famix_functions/helpers_creation.js +36 -5
  7. package/dist/fqn.js +76 -114
  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 -1
  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/{src/model → model}/famix/index.js +6 -10
  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 +2 -2
  55. package/dist/refactorer/refactor-getter-setter.js +142 -0
  56. package/dist/ts2famix-cli-wrapper.js +29 -3
  57. package/dist/ts2famix-cli.js +1 -1
  58. package/doc-uml/famix-typescript-model.puml +390 -341
  59. package/doc-uml/famix-typescript-model.svg +1 -1
  60. package/package.json +8 -7
  61. package/src/analyze.ts +2 -2
  62. package/src/analyze_functions/process_functions.ts +49 -44
  63. package/src/famix_functions/EntityDictionary.ts +345 -216
  64. package/src/famix_functions/helpers_creation.ts +36 -4
  65. package/src/fqn.ts +76 -125
  66. package/src/lib/famix/famix_JSON_exporter.ts +56 -0
  67. package/src/lib/famix/famix_base_element.ts +22 -0
  68. package/src/lib/famix/famix_repository.ts +243 -0
  69. package/src/lib/famix/model/famix/access.ts +50 -0
  70. package/src/lib/famix/model/famix/alias.ts +39 -0
  71. package/src/lib/famix/model/famix/behavioral_entity.ts +97 -0
  72. package/src/lib/famix/model/famix/class.ts +85 -0
  73. package/src/lib/famix/model/famix/comment.ts +47 -0
  74. package/src/lib/famix/model/famix/concretisation.ts +40 -0
  75. package/src/lib/famix/model/famix/container_entity.ts +160 -0
  76. package/src/lib/famix/model/famix/decorator.ts +37 -0
  77. package/src/lib/famix/model/famix/enum.ts +30 -0
  78. package/src/lib/famix/model/famix/enum_value.ts +28 -0
  79. package/src/lib/famix/model/famix/import_clause.ts +51 -0
  80. package/src/lib/famix/{src/model → model}/famix/index.ts +2 -4
  81. package/src/lib/famix/model/famix/indexed_file_anchor.ts +46 -0
  82. package/src/lib/famix/model/famix/inheritance.ts +40 -0
  83. package/src/lib/famix/model/famix/interface.ts +75 -0
  84. package/src/lib/famix/model/famix/invocation.ts +65 -0
  85. package/src/lib/famix/model/famix/method.ts +89 -0
  86. package/src/lib/famix/model/famix/module.ts +71 -0
  87. package/src/lib/famix/model/famix/named_entity.ts +95 -0
  88. package/src/lib/famix/{src/model → model}/famix/parameter.ts +11 -12
  89. package/src/lib/famix/model/famix/parameter_concretisation.ts +51 -0
  90. package/src/lib/famix/model/famix/parameter_type.ts +58 -0
  91. package/src/lib/famix/model/famix/parametric_arrow_function.ts +32 -0
  92. package/src/lib/famix/model/famix/parametric_class.ts +49 -0
  93. package/src/lib/famix/model/famix/parametric_function.ts +32 -0
  94. package/src/lib/famix/model/famix/parametric_interface.ts +49 -0
  95. package/src/lib/famix/model/famix/parametric_method.ts +32 -0
  96. package/src/lib/famix/model/famix/primitive_type.ts +15 -0
  97. package/src/lib/famix/model/famix/property.ts +94 -0
  98. package/src/lib/famix/model/famix/reference.ts +40 -0
  99. package/src/lib/famix/model/famix/scoping_entity.ts +35 -0
  100. package/src/lib/famix/model/famix/script_entity.ts +34 -0
  101. package/src/lib/famix/model/famix/source_anchor.ts +30 -0
  102. package/src/lib/famix/model/famix/source_language.ts +35 -0
  103. package/src/lib/famix/model/famix/sourced_entity.ts +70 -0
  104. package/src/lib/famix/model/famix/structural_entity.ts +43 -0
  105. package/src/lib/famix/model/famix/type.ts +87 -0
  106. package/src/lib/famix/model/famix/variable.ts +27 -0
  107. package/src/lib/famix/package.json +1 -1
  108. package/src/lib/ts-complex/cyclomatic-service.ts +10 -10
  109. package/src/refactorer/refactor-getter-setter.ts +140 -0
  110. package/src/ts2famix-cli-wrapper.ts +6 -2
  111. package/src/ts2famix-cli.ts +1 -1
  112. package/tsconfig.check-tests.json +14 -0
  113. package/tsconfig.json +70 -68
  114. package/dist/famix2puml.js +0 -126
  115. package/dist/lib/famix/src/famix_JSON_exporter.js +0 -55
  116. package/dist/lib/famix/src/famix_base_element.js +0 -18
  117. package/dist/lib/famix/src/famix_repository.js +0 -223
  118. package/dist/lib/famix/src/model/famix/access.js +0 -40
  119. package/dist/lib/famix/src/model/famix/accessor.js +0 -17
  120. package/dist/lib/famix/src/model/famix/alias.js +0 -33
  121. package/dist/lib/famix/src/model/famix/arrowFunction.js +0 -17
  122. package/dist/lib/famix/src/model/famix/behavioral_entity.js +0 -79
  123. package/dist/lib/famix/src/model/famix/class.js +0 -71
  124. package/dist/lib/famix/src/model/famix/comment.js +0 -39
  125. package/dist/lib/famix/src/model/famix/concretisation.js +0 -31
  126. package/dist/lib/famix/src/model/famix/container_entity.js +0 -126
  127. package/dist/lib/famix/src/model/famix/decorator.js +0 -32
  128. package/dist/lib/famix/src/model/famix/entity.js +0 -17
  129. package/dist/lib/famix/src/model/famix/enum.js +0 -31
  130. package/dist/lib/famix/src/model/famix/enum_value.js +0 -25
  131. package/dist/lib/famix/src/model/famix/function.js +0 -17
  132. package/dist/lib/famix/src/model/famix/implicit_variable.js +0 -17
  133. package/dist/lib/famix/src/model/famix/import_clause.js +0 -41
  134. package/dist/lib/famix/src/model/famix/indexed_file_anchor.js +0 -52
  135. package/dist/lib/famix/src/model/famix/inheritance.js +0 -33
  136. package/dist/lib/famix/src/model/famix/interface.js +0 -64
  137. package/dist/lib/famix/src/model/famix/invocation.js +0 -54
  138. package/dist/lib/famix/src/model/famix/method.js +0 -67
  139. package/dist/lib/famix/src/model/famix/module.js +0 -84
  140. package/dist/lib/famix/src/model/famix/named_entity.js +0 -78
  141. package/dist/lib/famix/src/model/famix/parameter.js +0 -25
  142. package/dist/lib/famix/src/model/famix/parameterConcretisation.js +0 -44
  143. package/dist/lib/famix/src/model/famix/parameter_type.js +0 -45
  144. package/dist/lib/famix/src/model/famix/parametric_arrow_function.js +0 -31
  145. package/dist/lib/famix/src/model/famix/parametric_class.js +0 -44
  146. package/dist/lib/famix/src/model/famix/parametric_function.js +0 -31
  147. package/dist/lib/famix/src/model/famix/parametric_interface.js +0 -44
  148. package/dist/lib/famix/src/model/famix/parametric_method.js +0 -31
  149. package/dist/lib/famix/src/model/famix/primitive_type.js +0 -17
  150. package/dist/lib/famix/src/model/famix/property.js +0 -126
  151. package/dist/lib/famix/src/model/famix/reference.js +0 -33
  152. package/dist/lib/famix/src/model/famix/scoping_entity.js +0 -37
  153. package/dist/lib/famix/src/model/famix/script_entity.js +0 -29
  154. package/dist/lib/famix/src/model/famix/source_anchor.js +0 -27
  155. package/dist/lib/famix/src/model/famix/source_language.js +0 -35
  156. package/dist/lib/famix/src/model/famix/sourced_entity.js +0 -60
  157. package/dist/lib/famix/src/model/famix/structural_entity.js +0 -39
  158. package/dist/lib/famix/src/model/famix/text_anchor.js +0 -38
  159. package/dist/lib/famix/src/model/famix/type.js +0 -73
  160. package/dist/lib/famix/src/model/famix/variable.js +0 -24
  161. package/jest.config-old.ts +0 -199
  162. package/src/famix2puml.ts +0 -119
  163. package/src/lib/famix/package-lock.json +0 -301
  164. package/src/lib/famix/readme.md +0 -5
  165. package/src/lib/famix/src/famix_JSON_exporter.ts +0 -56
  166. package/src/lib/famix/src/famix_base_element.ts +0 -22
  167. package/src/lib/famix/src/famix_repository.ts +0 -243
  168. package/src/lib/famix/src/model/famix/access.ts +0 -53
  169. package/src/lib/famix/src/model/famix/alias.ts +0 -41
  170. package/src/lib/famix/src/model/famix/behavioral_entity.ts +0 -100
  171. package/src/lib/famix/src/model/famix/class.ts +0 -86
  172. package/src/lib/famix/src/model/famix/comment.ts +0 -50
  173. package/src/lib/famix/src/model/famix/concretisation.ts +0 -42
  174. package/src/lib/famix/src/model/famix/container_entity.ts +0 -165
  175. package/src/lib/famix/src/model/famix/decorator.ts +0 -39
  176. package/src/lib/famix/src/model/famix/enum.ts +0 -31
  177. package/src/lib/famix/src/model/famix/enum_value.ts +0 -29
  178. package/src/lib/famix/src/model/famix/implicit_variable.ts +0 -15
  179. package/src/lib/famix/src/model/famix/import_clause.ts +0 -54
  180. package/src/lib/famix/src/model/famix/indexed_file_anchor.ts +0 -71
  181. package/src/lib/famix/src/model/famix/inheritance.ts +0 -41
  182. package/src/lib/famix/src/model/famix/interface.ts +0 -75
  183. package/src/lib/famix/src/model/famix/invocation.ts +0 -68
  184. package/src/lib/famix/src/model/famix/method.ts +0 -96
  185. package/src/lib/famix/src/model/famix/module.ts +0 -97
  186. package/src/lib/famix/src/model/famix/named_entity.ts +0 -98
  187. package/src/lib/famix/src/model/famix/parameterConcretisation.ts +0 -54
  188. package/src/lib/famix/src/model/famix/parameter_type.ts +0 -60
  189. package/src/lib/famix/src/model/famix/parametric_arrow_function.ts +0 -32
  190. package/src/lib/famix/src/model/famix/parametric_class.ts +0 -49
  191. package/src/lib/famix/src/model/famix/parametric_function.ts +0 -32
  192. package/src/lib/famix/src/model/famix/parametric_interface.ts +0 -49
  193. package/src/lib/famix/src/model/famix/parametric_method.ts +0 -32
  194. package/src/lib/famix/src/model/famix/primitive_type.ts +0 -15
  195. package/src/lib/famix/src/model/famix/property.ts +0 -152
  196. package/src/lib/famix/src/model/famix/reference.ts +0 -42
  197. package/src/lib/famix/src/model/famix/scoping_entity.ts +0 -36
  198. package/src/lib/famix/src/model/famix/script_entity.ts +0 -36
  199. package/src/lib/famix/src/model/famix/source_anchor.ts +0 -31
  200. package/src/lib/famix/src/model/famix/source_language.ts +0 -36
  201. package/src/lib/famix/src/model/famix/sourced_entity.ts +0 -73
  202. package/src/lib/famix/src/model/famix/structural_entity.ts +0 -44
  203. package/src/lib/famix/src/model/famix/text_anchor.ts +0 -49
  204. package/src/lib/famix/src/model/famix/type.ts +0 -89
  205. package/src/lib/famix/src/model/famix/variable.ts +0 -28
  206. package/src/lib/famix/tsconfig.json +0 -27
  207. package/src/lib/famix/tslint.json +0 -15
  208. /package/src/lib/famix/{src/index.ts → index.ts} +0 -0
  209. /package/src/lib/famix/{src/model → model}/famix/accessor.ts +0 -0
  210. /package/src/lib/famix/{src/model/famix/arrowFunction.ts → model/famix/arrow_function.ts} +0 -0
  211. /package/src/lib/famix/{src/model → model}/famix/entity.ts +0 -0
  212. /package/src/lib/famix/{src/model → model}/famix/function.ts +0 -0
@@ -1,4 +1,4 @@
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
4
  import { TypeDeclaration } from "./EntityDictionary";
@@ -45,7 +45,7 @@ export function getSubTypeName(fmxNamedEntity: Famix.NamedEntity) {
45
45
  fmxNamedEntity instanceof Famix.Parameter ? 'Parameter' :
46
46
  fmxNamedEntity instanceof Famix.Property ? 'Property' :
47
47
  'NamedEntity';
48
- logger.debug(`${fmxNamedEntity.getName()} is of type ${name}`);
48
+ logger.debug(`${fmxNamedEntity.name} is of type ${name}`);
49
49
  return name;
50
50
  }
51
51
 
@@ -65,7 +65,21 @@ export function computeSignature(text: string): string {
65
65
  * @returns The ancestor of the node
66
66
  */
67
67
  export function findAncestor(node: Identifier): Node {
68
- 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
69
83
  }
70
84
 
71
85
  /**
@@ -74,12 +88,30 @@ export function findAncestor(node: Identifier): Node {
74
88
  * @returns The ancestor of the ts-morph element
75
89
  */
76
90
  export function findTypeAncestor(element: TypeDeclaration): Node {
77
- 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);
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;
78
108
  }
79
109
 
80
110
  export function arraysAreEqual(array1: string[], array2: string[]): boolean {
81
111
  if (array1 && array2 ) {
82
112
  return array1.length === array2.length && array1.every((value, index) => value === array2[index]);
113
+ } else {
114
+ return false;
83
115
  }
84
116
  }
85
117
 
package/src/fqn.ts CHANGED
@@ -1,9 +1,8 @@
1
- import { ArrowFunction, CallExpression, ClassDeclaration, ClassExpression, ConstructorDeclaration, Decorator, EnumDeclaration, FunctionDeclaration, FunctionExpression, GetAccessorDeclaration, Identifier, ImportDeclaration, ImportEqualsDeclaration, InterfaceDeclaration, MethodDeclaration, MethodSignature, ModuleDeclaration, Node, PropertyDeclaration, SetAccessorDeclaration, SourceFile, ts, TypeParameterDeclaration, VariableDeclaration } from "ts-morph";
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
2
  import { entityDictionary, logger } from "./analyze";
3
3
  import path from "path";
4
4
  import { TypeDeclaration } from "./famix_functions/EntityDictionary";
5
5
 
6
-
7
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;
8
7
 
9
8
  function isFQNNode(node: Node): node is FQNNode {
@@ -72,84 +71,24 @@ export function getUniqueFQN(node: Node): string | undefined {
72
71
  return entityDictionary.convertToRelativePath(path.normalize(node.getFilePath()), absolutePathProject).replace(/\\/g, "/");
73
72
  }
74
73
 
75
- while (node) {
76
- if (Node.isSourceFile(node)) {
77
- const relativePath = entityDictionary.convertToRelativePath(path.normalize(node.getFilePath()), absolutePathProject).replace(/\\/g, "/");
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
78
  parts.unshift(relativePath); // Add file path at the start
79
79
  break;
80
- } else if (node.getSymbol()) {
81
- const name = node.getSymbol()!.getName();
80
+ } else if (currentNode.getSymbol()) {
81
+ const name = currentNode.getSymbol()!.getName();
82
82
  // For anonymous nodes, use kind and position as unique identifiers
83
- const identifier = name !== "__computed" ? name : `${node.getKindName()}_${node.getStartLinePos()}`;
83
+ const identifier = name !== "__computed" ? name : `${currentNode.getKindName()}_${currentNode.getStartLinePos()}`;
84
84
  parts.unshift(identifier);
85
85
  }
86
- node = node.getParent();
86
+ currentNode = currentNode.getParent();
87
87
  }
88
88
 
89
89
  return parts.join("::");
90
90
  }
91
91
 
92
-
93
- /**
94
- * Gets the fully qualified name of a node, if it has one
95
- * @param node A node
96
- * @returns The fully qualified name of the node, or undefined if it doesn't have one
97
- */
98
- export function oldGetFQN(node: Node): string {
99
- const absolutePathProject = entityDictionary.famixRep.getAbsolutePath();
100
-
101
- if (node instanceof SourceFile) {
102
- return entityDictionary.convertToRelativePath(path.normalize(node.getFilePath()),
103
- absolutePathProject).replace(/\\/sg, "/");
104
- }
105
-
106
- const symbol = node.getSymbol();
107
- if (!symbol) {
108
- return undefined;
109
- }
110
-
111
- const declarations = symbol.getDeclarations();
112
- if (!declarations) {
113
- return undefined;
114
- }
115
-
116
- const sourceFile = declarations[0].getSourceFile();
117
- if (!sourceFile) {
118
- return undefined;
119
- }
120
-
121
- const absolutePath = path.normalize(sourceFile.getFilePath());
122
- const positionNodeModules = absolutePath.indexOf('node_modules');
123
- let pathInProject: string = "";
124
-
125
- if (positionNodeModules !== -1) {
126
- const pathFromNodeModules = absolutePath.substring(positionNodeModules);
127
- pathInProject = pathFromNodeModules;
128
- } else {
129
- pathInProject = entityDictionary.convertToRelativePath(absolutePath, absolutePathProject).replace(/\\/g, "/");
130
- }
131
-
132
- const qualifiedNameParts: Array<string> = [];
133
-
134
- const nodeName = this.getNameOfNode(node);
135
- if (nodeName) qualifiedNameParts.push(nodeName);
136
-
137
- const ancestors = node.getAncestors();
138
- ancestors.forEach(a => {
139
- const partName = this.getNameOfNode(a);
140
- if (partName) qualifiedNameParts.push(partName);
141
- });
142
-
143
- qualifiedNameParts.pop();
144
-
145
- if (qualifiedNameParts.length > 0) {
146
- return `{${pathInProject}}.${qualifiedNameParts.reverse().join(".")}`;
147
- }
148
- else {
149
- return undefined;
150
- }
151
- }
152
-
153
92
  /**
154
93
  * Gets the name of a node, if it has one
155
94
  * @param a A node
@@ -157,80 +96,84 @@ export function oldGetFQN(node: Node): string {
157
96
  */
158
97
  export function getNameOfNode(a: Node): string {
159
98
  switch (a.getKind()) {
160
- case ts.SyntaxKind.SourceFile:
161
- return a.asKind(ts.SyntaxKind.SourceFile)?.getBaseName();
99
+ case SyntaxKind.SourceFile:
100
+ return a.asKind(SyntaxKind.SourceFile)!.getBaseName();
162
101
 
163
- case ts.SyntaxKind.ModuleDeclaration:
164
- return a.asKind(ts.SyntaxKind.ModuleDeclaration)?.getName();
102
+ case SyntaxKind.ModuleDeclaration:
103
+ return a.asKind(SyntaxKind.ModuleDeclaration)!.getName();
165
104
 
166
- case ts.SyntaxKind.ClassDeclaration:
167
- if (a.asKind(ts.SyntaxKind.ClassDeclaration).getTypeParameters().length>0){
168
- return a.asKind(ts.SyntaxKind.ClassDeclaration)?.getName()+getParameters(a);
105
+ case SyntaxKind.ClassDeclaration:
106
+ const cKind = a.asKind(SyntaxKind.ClassDeclaration);
107
+ if (cKind && cKind.getTypeParameters().length > 0) {
108
+ return cKind.getName() + getParameters(a);
169
109
  } else {
170
- return a.asKind(ts.SyntaxKind.ClassDeclaration)?.getName();
110
+ return cKind?.getName() || "";
171
111
  }
172
112
 
173
- case ts.SyntaxKind.InterfaceDeclaration:
174
- if (a.asKind(ts.SyntaxKind.InterfaceDeclaration).getTypeParameters().length>0){
175
- return a.asKind(ts.SyntaxKind.InterfaceDeclaration)?.getName()+getParameters(a);
113
+ case SyntaxKind.InterfaceDeclaration:
114
+ const iKind = a.asKind(SyntaxKind.InterfaceDeclaration);
115
+ if (iKind && iKind.getTypeParameters().length > 0) {
116
+ return iKind.getName() + getParameters(a);
176
117
  } else {
177
- return a.asKind(ts.SyntaxKind.InterfaceDeclaration)?.getName();
118
+ return iKind?.getName() || "";
178
119
  }
179
120
 
180
- case ts.SyntaxKind.PropertyDeclaration:
181
- return a.asKind(ts.SyntaxKind.PropertyDeclaration)?.getName();
121
+ case SyntaxKind.PropertyDeclaration:
122
+ return a.asKind(SyntaxKind.PropertyDeclaration)!.getName();
182
123
 
183
- case ts.SyntaxKind.PropertySignature:
184
- return a.asKind(ts.SyntaxKind.PropertySignature)?.getName();
124
+ case SyntaxKind.PropertySignature:
125
+ return a.asKind(SyntaxKind.PropertySignature)!.getName();
185
126
 
186
- case ts.SyntaxKind.MethodDeclaration:
187
- if (a.asKind(ts.SyntaxKind.MethodDeclaration).getTypeParameters().length>0){
188
- return a.asKind(ts.SyntaxKind.MethodDeclaration)?.getName()+getParameters(a);
127
+ case SyntaxKind.MethodDeclaration:
128
+ const mKind = a.asKind(SyntaxKind.MethodDeclaration);
129
+ if (mKind && mKind.getTypeParameters().length > 0) {
130
+ return mKind.getName() + getParameters(a);
189
131
  } else {
190
- return a.asKind(ts.SyntaxKind.MethodDeclaration)?.getName();
132
+ return mKind?.getName() || "";
191
133
  }
192
134
 
193
- case ts.SyntaxKind.MethodSignature:
194
- return a.asKind(ts.SyntaxKind.MethodSignature)?.getName();
135
+ case SyntaxKind.MethodSignature:
136
+ return a.asKind(SyntaxKind.MethodSignature)!.getName();
195
137
 
196
- case ts.SyntaxKind.GetAccessor:
197
- return a.asKind(ts.SyntaxKind.GetAccessor)?.getName();
138
+ case SyntaxKind.GetAccessor:
139
+ return a.asKind(SyntaxKind.GetAccessor)!.getName();
198
140
 
199
- case ts.SyntaxKind.SetAccessor:
200
- return a.asKind(ts.SyntaxKind.SetAccessor)?.getName();
141
+ case SyntaxKind.SetAccessor:
142
+ return a.asKind(SyntaxKind.SetAccessor)!.getName();
201
143
 
202
- case ts.SyntaxKind.FunctionDeclaration:
203
- if (a.asKind(ts.SyntaxKind.FunctionDeclaration).getTypeParameters().length>0){
204
- return a.asKind(ts.SyntaxKind.FunctionDeclaration)?.getName()+getParameters(a);
144
+ case SyntaxKind.FunctionDeclaration:
145
+ const fKind = a.asKind(SyntaxKind.FunctionDeclaration);
146
+ if (fKind && fKind.getTypeParameters().length > 0) {
147
+ return fKind.getName() + getParameters(a);
205
148
  } else {
206
- return a.asKind(ts.SyntaxKind.FunctionDeclaration)?.getName();
149
+ return fKind?.getName() || "";
207
150
  }
208
151
 
209
- case ts.SyntaxKind.FunctionExpression:
210
- return (a.asKind(ts.SyntaxKind.FunctionExpression)?.getName()) ? a.asKind(ts.SyntaxKind.FunctionExpression)?.getName() : "anonymous";
152
+ case SyntaxKind.FunctionExpression:
153
+ return a.asKind(SyntaxKind.FunctionExpression)?.getName() || "anonymous";
211
154
 
212
- case ts.SyntaxKind.Parameter:
213
- return a.asKind(ts.SyntaxKind.Parameter)?.getName();
155
+ case SyntaxKind.Parameter:
156
+ return a.asKind(SyntaxKind.Parameter)!.getName();
214
157
 
215
- case ts.SyntaxKind.VariableDeclaration:
216
- return a.asKind(ts.SyntaxKind.VariableDeclaration)?.getName();
158
+ case SyntaxKind.VariableDeclaration:
159
+ return a.asKind(SyntaxKind.VariableDeclaration)!.getName();
217
160
 
218
- case ts.SyntaxKind.Decorator:
219
- return "@" + a.asKind(ts.SyntaxKind.Decorator)?.getName();
161
+ case SyntaxKind.Decorator:
162
+ return "@" + a.asKind(SyntaxKind.Decorator)!.getName();
220
163
 
221
- case ts.SyntaxKind.TypeParameter:
222
- return a.asKind(ts.SyntaxKind.TypeParameter)?.getName();
164
+ case SyntaxKind.TypeParameter:
165
+ return a.asKind(SyntaxKind.TypeParameter)!.getName();
223
166
 
224
- case ts.SyntaxKind.EnumDeclaration:
225
- return a.asKind(ts.SyntaxKind.EnumDeclaration)?.getName();
167
+ case SyntaxKind.EnumDeclaration:
168
+ return a.asKind(SyntaxKind.EnumDeclaration)!.getName();
226
169
 
227
- case ts.SyntaxKind.EnumMember:
228
- return a.asKind(ts.SyntaxKind.EnumMember)?.getName();
170
+ case SyntaxKind.EnumMember:
171
+ return a.asKind(SyntaxKind.EnumMember)!.getName();
229
172
 
230
- case ts.SyntaxKind.TypeAliasDeclaration:
231
- return a.asKind(ts.SyntaxKind.TypeAliasDeclaration)?.getName();
173
+ case SyntaxKind.TypeAliasDeclaration:
174
+ return a.asKind(SyntaxKind.TypeAliasDeclaration)!.getName();
232
175
 
233
- case ts.SyntaxKind.Constructor:
176
+ case SyntaxKind.Constructor:
234
177
  return "constructor";
235
178
 
236
179
  default:
@@ -245,14 +188,22 @@ export function getNameOfNode(a: Node): string {
245
188
  * @returns The name of the node, or an empty string if it doesn't have one
246
189
  */
247
190
  export function getParameters(a: Node): string {
191
+ let paramString = "";
248
192
  switch (a.getKind()) {
249
- case ts.SyntaxKind.ClassDeclaration:
250
- return "<" + a.asKind(ts.SyntaxKind.ClassDeclaration)?.getTypeParameters().map(tp => tp.getName()).join(", ") + ">";
251
- case ts.SyntaxKind.InterfaceDeclaration:
252
- return "<" + a.asKind(ts.SyntaxKind.InterfaceDeclaration)?.getTypeParameters().map(tp => tp.getName()).join(", ") + ">";
253
- case ts.SyntaxKind.MethodDeclaration:
254
- return "<" + a.asKind(ts.SyntaxKind.MethodDeclaration)?.getTypeParameters().map(tp => tp.getName()).join(", ") + ">";
255
- case ts.SyntaxKind.FunctionDeclaration:
256
- return "<" + a.asKind(ts.SyntaxKind.FunctionDeclaration)?.getTypeParameters().map(tp => tp.getName()).join(", ") + ">";
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()}`);
257
207
  }
208
+ return paramString;
258
209
  }
@@ -0,0 +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
+ }
@@ -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
+ }
@@ -0,0 +1,243 @@
1
+ import { FamixBaseElement } from "./famix_base_element";
2
+ import { Class, Interface, Variable, Method, ArrowFunction, Function as FamixFunctionEntity, Type, NamedEntity, ScriptEntity, Module, SourceLanguage } from "./model/famix";
3
+ import * as Famix from "./model/famix";
4
+ import { TSMorphObjectType } from "../../famix_functions/EntityDictionary";
5
+ /**
6
+ * This class is used to store all Famix elements
7
+ */
8
+ export class FamixRepository {
9
+ private elements = new Set<FamixBaseElement>(); // All Famix elements
10
+ private famixClasses = new Set<Class>(); // All Famix classes
11
+ private famixInterfaces = new Set<Interface>(); // All Famix interfaces
12
+ private famixModules = new Set<Module>(); // All Famix namespaces
13
+ private famixMethods = new Set<Method>(); // All Famix methods
14
+ private famixVariables = new Set<Variable>(); // All Famix variables
15
+ private famixFunctions = new Set<FamixFunctionEntity>(); // All Famix functions
16
+ private famixFiles = new Set<ScriptEntity | Module>(); // All Famix files
17
+ private idCounter = 1; // Id counter
18
+ private absolutePath: string = "";
19
+ private fmxElementObjectMap = new Map<Famix.Entity, TSMorphObjectType>();
20
+ private tsMorphObjectMap = new Map<TSMorphObjectType, Famix.Entity>(); // TODO: add this map to have two-way mapping between Famix and TS Morph objects
21
+
22
+ constructor() {
23
+ this.addElement(new SourceLanguage()); // add the source language entity (TypeScript)
24
+ }
25
+
26
+ public setFmxElementObjectMap(fmxElementObjectMap: Map<Famix.Entity, TSMorphObjectType>) {
27
+ this.fmxElementObjectMap = fmxElementObjectMap;
28
+ }
29
+
30
+ public getFmxElementObjectMap() {
31
+ return this.fmxElementObjectMap;
32
+ }
33
+
34
+ public getAbsolutePath(): string {
35
+ return this.absolutePath;
36
+ }
37
+
38
+ public setAbsolutePath(path: string) {
39
+ this.absolutePath = path;
40
+ }
41
+
42
+ /**
43
+ * Gets a Famix entity by id
44
+ * @param id An id of a Famix entity
45
+ * @returns The Famix entity corresponding to the id or undefined if it doesn't exist
46
+ */
47
+ public getFamixEntityById(id: number): FamixBaseElement | undefined {
48
+ const entity = Array.from(this.elements.values()).find(e => e.id === id);
49
+ return entity;
50
+ }
51
+
52
+ /**
53
+ * Gets a Famix entity by fully qualified name
54
+ * @param fullyQualifiedName A fully qualified name
55
+ * @returns The Famix entity corresponding to the fully qualified name or undefined if it doesn't exist
56
+ */
57
+ public getFamixEntityByFullyQualifiedName(fullyQualifiedName: string): FamixBaseElement | undefined {
58
+ const allEntities = Array.from(this.elements.values()).filter(e => e instanceof NamedEntity) as Array<NamedEntity>;
59
+ const entity = allEntities.find(e => e.fullyQualifiedName === fullyQualifiedName);
60
+ return entity;
61
+ }
62
+
63
+ export(arg0: { format: string; }) {
64
+ if (arg0.format === "json") {
65
+ return this.getJSON();
66
+ } else {
67
+ throw new Error("Unsupported format");
68
+ }
69
+ }
70
+
71
+
72
+ // Only for tests
73
+
74
+ /**
75
+ * Gets all Famix entities
76
+ * @returns All Famix entities
77
+ */
78
+ public _getAllEntities(): Set<FamixBaseElement> {
79
+ return new Set(Array.from(this.elements.values()));
80
+ }
81
+
82
+ /**
83
+ * Gets all Famix entities of a given type
84
+ * @param theType A type of Famix entity
85
+ * @returns All Famix entities of the given type
86
+ */
87
+ public _getAllEntitiesWithType(theType: string): Set<FamixBaseElement> {
88
+ return new Set(Array.from(this.elements.values()).filter(e => (e as FamixBaseElement).constructor.name === theType));
89
+ }
90
+
91
+ /**
92
+ * Gets a Famix class by name
93
+ * @param name A class name
94
+ * @returns The Famix class corresponding to the name or undefined if it doesn't exist
95
+ */
96
+ public _getFamixClass(fullyQualifiedName: string): Class | undefined {
97
+ return Array.from(this.famixClasses.values()).find(ns => ns.fullyQualifiedName === fullyQualifiedName);
98
+ }
99
+
100
+ /**
101
+ * Gets a Famix interface by name
102
+ * @param name An interface name
103
+ * @returns The Famix interface corresponding to the name or undefined if it doesn't exist
104
+ */
105
+ public _getFamixInterface(fullyQualifiedName: string): Interface | undefined {
106
+ return Array.from(this.famixInterfaces.values()).find(ns => ns.fullyQualifiedName === fullyQualifiedName);
107
+ }
108
+
109
+ /**
110
+ * Gets a Famix method by name
111
+ * @param name A method name
112
+ * @returns The Famix method corresponding to the name or undefined if it doesn't exist
113
+ */
114
+ public _getFamixMethod(fullyQualifiedName: string): Method | undefined {
115
+ return Array.from(this.famixMethods.values()).find(ns => ns.fullyQualifiedName === fullyQualifiedName);
116
+ }
117
+
118
+ /**
119
+ * Gets a Famix function by name
120
+ * @param name A function name
121
+ * @returns The Famix function corresponding to the name or undefined if it doesn't exist
122
+ */
123
+ public _getFamixFunction(fullyQualifiedName: string): FamixFunctionEntity | undefined {
124
+ return Array.from(this.famixFunctions.values()).find(ns => ns.fullyQualifiedName === fullyQualifiedName);
125
+ }
126
+
127
+
128
+ /**
129
+ * Gets a Famix variable by name
130
+ * @param name A variable name
131
+ * @returns The Famix variable corresponding to the name or undefined if it doesn't exist
132
+ */
133
+ public _getFamixVariable(fullyQualifiedName: string): Variable | undefined {
134
+ return Array.from(this.famixVariables.values()).find(v => v.fullyQualifiedName === fullyQualifiedName);
135
+ }
136
+
137
+ /**
138
+ * Gets a Famix namespace by name
139
+ * @param name A namespace name
140
+ * @returns The Famix namespace corresponding to the name or undefined if it doesn't exist
141
+ */
142
+ public _getFamixModule(fullyQualifiedName: string): Module | undefined {
143
+ return Array.from(this.famixModules.values()).find(ns => ns.fullyQualifiedName === fullyQualifiedName);
144
+ }
145
+
146
+ /**
147
+ * Gets all Famix namespaces
148
+ * @returns All Famix namespaces
149
+ */
150
+ public _getFamixModules(): Set<Module> {
151
+ return new Set(Array.from(this.famixModules.values()));
152
+ }
153
+
154
+ /**
155
+ * Gets a Famix file by name
156
+ * @param name A file name
157
+ * @returns The Famix file corresponding to the name or undefined if it doesn't exist
158
+ */
159
+ public _getFamixFile(fullyQualifiedName: string): ScriptEntity | Module | undefined {
160
+ return Array.from(this.famixFiles.values()).find(ns => ns.name === fullyQualifiedName);
161
+ }
162
+
163
+ /**
164
+ * Gets all Famix files
165
+ * @returns All Famix files
166
+ */
167
+ public _getFamixFiles(): Set<ScriptEntity | Module> {
168
+ return new Set(Array.from(this.famixFiles.values()));
169
+ }
170
+
171
+ /**
172
+ * Gets all method names as a set from a class
173
+ * @param className A class name
174
+ * @returns The set of class "className" method names
175
+ */
176
+ public _methodNamesAsSetFromClass(className: string): Set<string> {
177
+ const theClass = this._getFamixClass(className) as Class;
178
+ return new Set(Array.from(theClass.methods).map(m => m.name));
179
+ }
180
+
181
+ /**
182
+ * Gets all method parents as a set from a class
183
+ * @param className A class name
184
+ * @returns The set of class "className" method parents
185
+ */
186
+ public _methodParentsAsSetFromClass(className: string): Set<Type> {
187
+ const theClass = this._getFamixClass(className) as Class;
188
+ return new Set(Array.from(theClass.methods).map(m => m.parentEntity));
189
+ }
190
+
191
+ /**
192
+ * Gets the map of Famix element ids and their Famix element from a JSON model
193
+ * @param model A JSON model
194
+ * @returns The map of Famix element ids and their Famix element from the JSON model
195
+ */
196
+ public _initMapFromModel(model: string): Map<number, unknown> {
197
+ const parsedModel: Array<FamixBaseElement> = JSON.parse(model);
198
+ const idToElementMap: Map<number, unknown> = new Map();
199
+ parsedModel.forEach(element => {
200
+ idToElementMap.set(element.id, element);
201
+ });
202
+ return idToElementMap;
203
+ }
204
+
205
+
206
+ /**
207
+ * Adds a Famix element to the repository
208
+ * @param element A Famix element
209
+ */
210
+ public addElement(element: FamixBaseElement): void {
211
+ if (element instanceof Class) {
212
+ this.famixClasses.add(element);
213
+ } else if (element instanceof Interface) {
214
+ this.famixInterfaces.add(element);
215
+ } else if (element instanceof Module) {
216
+ this.famixModules.add(element);
217
+ } else if (element instanceof Variable) {
218
+ this.famixVariables.add(element);
219
+ } else if (element instanceof Method) {
220
+ this.famixMethods.add(element);
221
+ } else if (element instanceof FamixFunctionEntity || element instanceof ArrowFunction) {
222
+ this.famixFunctions.add(element);
223
+ } else if (element instanceof ScriptEntity || element instanceof Module) {
224
+ this.famixFiles.add(element);
225
+ }
226
+ this.elements.add(element);
227
+ element.id = this.idCounter;
228
+ this.idCounter++;
229
+ }
230
+
231
+ /**
232
+ * Gets a JSON representation of the repository
233
+ * @returns A JSON representation of the repository
234
+ */
235
+ public getJSON(): string {
236
+ let ret = "[";
237
+ for (const element of Array.from(this.elements.values())) {
238
+ ret = ret + element.getJSON() + ",";
239
+ }
240
+ ret = ret.substring(0, ret.length - 1);
241
+ return ret + "]";
242
+ }
243
+ }