yukigo 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (144) hide show
  1. package/.mocharc.json +3 -3
  2. package/CHANGELOG.md +26 -0
  3. package/README.md +193 -199
  4. package/dist/analyzer/GraphBuilder.d.ts +29 -0
  5. package/dist/analyzer/GraphBuilder.js +99 -0
  6. package/dist/analyzer/index.d.ts +11 -23
  7. package/dist/analyzer/index.js +100 -58
  8. package/dist/analyzer/inspections/functional/functional.d.ts +44 -0
  9. package/dist/analyzer/inspections/functional/functional.js +149 -0
  10. package/dist/analyzer/inspections/functional/smells.d.ts +16 -0
  11. package/dist/analyzer/inspections/functional/smells.js +98 -0
  12. package/dist/analyzer/inspections/{generic.d.ts → generic/generic.d.ts} +70 -43
  13. package/dist/analyzer/inspections/generic/generic.js +604 -0
  14. package/dist/analyzer/inspections/generic/smells.d.ts +61 -0
  15. package/dist/analyzer/inspections/generic/smells.js +349 -0
  16. package/dist/analyzer/inspections/imperative/imperative.d.ts +35 -0
  17. package/dist/analyzer/inspections/imperative/imperative.js +109 -0
  18. package/dist/analyzer/inspections/imperative/smells.d.ts +16 -0
  19. package/dist/analyzer/inspections/imperative/smells.js +58 -0
  20. package/dist/analyzer/inspections/logic/logic.d.ts +32 -0
  21. package/dist/analyzer/inspections/logic/logic.js +96 -0
  22. package/dist/analyzer/inspections/logic/smells.d.ts +15 -0
  23. package/dist/analyzer/inspections/logic/smells.js +60 -0
  24. package/dist/analyzer/inspections/object/object.d.ts +88 -0
  25. package/dist/analyzer/inspections/object/object.js +319 -0
  26. package/dist/analyzer/inspections/object/smells.d.ts +30 -0
  27. package/dist/analyzer/inspections/object/smells.js +135 -0
  28. package/dist/analyzer/utils.d.ts +26 -4
  29. package/dist/analyzer/utils.js +71 -13
  30. package/dist/index.d.ts +1 -0
  31. package/dist/index.js +1 -0
  32. package/dist/interpreter/components/EnvBuilder.d.ts +9 -5
  33. package/dist/interpreter/components/EnvBuilder.js +100 -30
  34. package/dist/interpreter/components/Operations.d.ts +4 -4
  35. package/dist/interpreter/components/Operations.js +17 -2
  36. package/dist/interpreter/components/PatternMatcher.d.ts +47 -17
  37. package/dist/interpreter/components/PatternMatcher.js +264 -119
  38. package/dist/interpreter/components/RuntimeContext.d.ts +35 -0
  39. package/dist/interpreter/components/RuntimeContext.js +93 -0
  40. package/dist/interpreter/components/TestRunner.d.ts +18 -0
  41. package/dist/interpreter/components/TestRunner.js +103 -0
  42. package/dist/interpreter/components/Visitor.d.ts +63 -57
  43. package/dist/interpreter/components/Visitor.js +508 -173
  44. package/dist/interpreter/components/logic/LogicEngine.d.ts +29 -0
  45. package/dist/interpreter/components/logic/LogicEngine.js +259 -0
  46. package/dist/interpreter/components/logic/LogicResolver.d.ts +53 -0
  47. package/dist/interpreter/components/logic/LogicResolver.js +471 -0
  48. package/dist/interpreter/components/logic/LogicTranslator.d.ts +14 -0
  49. package/dist/interpreter/components/logic/LogicTranslator.js +99 -0
  50. package/dist/interpreter/components/runtimes/FunctionRuntime.d.ts +12 -0
  51. package/dist/interpreter/components/runtimes/FunctionRuntime.js +147 -0
  52. package/dist/interpreter/components/runtimes/LazyRuntime.d.ts +19 -0
  53. package/dist/interpreter/components/runtimes/LazyRuntime.js +269 -0
  54. package/dist/interpreter/components/runtimes/ObjectRuntime.d.ts +35 -0
  55. package/dist/interpreter/components/runtimes/ObjectRuntime.js +126 -0
  56. package/dist/interpreter/entities.d.ts +105 -0
  57. package/dist/interpreter/entities.js +96 -0
  58. package/dist/interpreter/errors.d.ts +1 -1
  59. package/dist/interpreter/index.d.ts +4 -12
  60. package/dist/interpreter/index.js +10 -13
  61. package/dist/interpreter/trampoline.d.ts +17 -0
  62. package/dist/interpreter/trampoline.js +38 -0
  63. package/dist/interpreter/utils.d.ts +4 -7
  64. package/dist/interpreter/utils.js +25 -17
  65. package/dist/tester/index.d.ts +25 -0
  66. package/dist/tester/index.js +108 -0
  67. package/dist/utils/helpers.d.ts +0 -4
  68. package/dist/utils/helpers.js +20 -24
  69. package/package.json +2 -2
  70. package/src/analyzer/GraphBuilder.ts +142 -0
  71. package/src/analyzer/index.ts +185 -132
  72. package/src/analyzer/inspections/functional/functional.ts +121 -0
  73. package/src/analyzer/inspections/functional/smells.ts +102 -0
  74. package/src/analyzer/inspections/{generic.ts → generic/generic.ts} +581 -499
  75. package/src/analyzer/inspections/generic/smells.ts +365 -0
  76. package/src/analyzer/inspections/imperative/imperative.ts +101 -0
  77. package/src/analyzer/inspections/imperative/smells.ts +54 -0
  78. package/src/analyzer/inspections/logic/logic.ts +90 -0
  79. package/src/analyzer/inspections/logic/smells.ts +54 -0
  80. package/src/analyzer/inspections/{object.ts → object/object.ts} +264 -282
  81. package/src/analyzer/inspections/object/smells.ts +144 -0
  82. package/src/analyzer/utils.ts +109 -26
  83. package/src/index.ts +3 -2
  84. package/src/interpreter/components/EnvBuilder.ts +202 -97
  85. package/src/interpreter/components/Operations.ts +99 -81
  86. package/src/interpreter/components/PatternMatcher.ts +475 -254
  87. package/src/interpreter/components/RuntimeContext.ts +119 -0
  88. package/src/interpreter/components/TestRunner.ts +151 -0
  89. package/src/interpreter/components/Visitor.ts +1065 -493
  90. package/src/interpreter/components/logic/LogicEngine.ts +519 -0
  91. package/src/interpreter/components/logic/LogicResolver.ts +858 -0
  92. package/src/interpreter/components/logic/LogicTranslator.ts +149 -0
  93. package/src/interpreter/components/runtimes/FunctionRuntime.ts +227 -0
  94. package/src/interpreter/components/runtimes/LazyRuntime.ts +334 -0
  95. package/src/interpreter/components/runtimes/ObjectRuntime.ts +224 -0
  96. package/src/interpreter/errors.ts +47 -47
  97. package/src/interpreter/index.ts +52 -59
  98. package/src/interpreter/trampoline.ts +71 -0
  99. package/src/interpreter/utils.ts +84 -79
  100. package/src/tester/index.ts +128 -0
  101. package/src/utils/helpers.ts +67 -73
  102. package/tests/analyzer/functional.spec.ts +207 -221
  103. package/tests/analyzer/generic.spec.ts +178 -100
  104. package/tests/analyzer/helpers.spec.ts +83 -83
  105. package/tests/analyzer/logic.spec.ts +237 -292
  106. package/tests/analyzer/oop.spec.ts +323 -338
  107. package/tests/analyzer/transitive.spec.ts +166 -0
  108. package/tests/interpreter/EnvBuilder.spec.ts +183 -178
  109. package/tests/interpreter/FunctionRuntime.spec.ts +223 -234
  110. package/tests/interpreter/LazyRuntime.spec.ts +225 -190
  111. package/tests/interpreter/LogicEngine.spec.ts +327 -194
  112. package/tests/interpreter/LogicSubstitution.spec.ts +80 -0
  113. package/tests/interpreter/ObjectRuntime.spec.ts +606 -0
  114. package/tests/interpreter/Operations.spec.ts +220 -220
  115. package/tests/interpreter/PatternSystem.spec.ts +213 -189
  116. package/tests/interpreter/Tests.spec.ts +122 -0
  117. package/tests/interpreter/interpreter.spec.ts +991 -937
  118. package/tests/tester/Tester.spec.ts +153 -0
  119. package/tsconfig.build.json +15 -7
  120. package/tsconfig.json +25 -17
  121. package/dist/analyzer/inspections/functional.d.ts +0 -46
  122. package/dist/analyzer/inspections/functional.js +0 -123
  123. package/dist/analyzer/inspections/generic.js +0 -427
  124. package/dist/analyzer/inspections/imperative.d.ts +0 -37
  125. package/dist/analyzer/inspections/imperative.js +0 -105
  126. package/dist/analyzer/inspections/logic.d.ts +0 -49
  127. package/dist/analyzer/inspections/logic.js +0 -140
  128. package/dist/analyzer/inspections/object.d.ts +0 -83
  129. package/dist/analyzer/inspections/object.js +0 -235
  130. package/dist/interpreter/components/FunctionRuntime.d.ts +0 -8
  131. package/dist/interpreter/components/FunctionRuntime.js +0 -52
  132. package/dist/interpreter/components/LazyRuntime.d.ts +0 -7
  133. package/dist/interpreter/components/LazyRuntime.js +0 -75
  134. package/dist/interpreter/components/LogicEngine.d.ts +0 -21
  135. package/dist/interpreter/components/LogicEngine.js +0 -152
  136. package/dist/interpreter/components/LogicResolver.d.ts +0 -11
  137. package/dist/interpreter/components/LogicResolver.js +0 -87
  138. package/src/analyzer/inspections/functional.ts +0 -159
  139. package/src/analyzer/inspections/imperative.ts +0 -129
  140. package/src/analyzer/inspections/logic.ts +0 -166
  141. package/src/interpreter/components/FunctionRuntime.ts +0 -79
  142. package/src/interpreter/components/LazyRuntime.ts +0 -97
  143. package/src/interpreter/components/LogicEngine.ts +0 -227
  144. package/src/interpreter/components/LogicResolver.ts +0 -130
@@ -0,0 +1,15 @@
1
+ import { AssignOperation, Exist, UnifyOperation } from "yukigo-ast";
2
+ import { ScopedVisitor, VisitorConstructor } from "../../utils.js";
3
+ export declare class HasRedundantReduction extends ScopedVisitor {
4
+ visitAssignOperation(node: AssignOperation): void;
5
+ }
6
+ export declare class UsesUnificationOperator extends ScopedVisitor {
7
+ visitUnifyOperation(node: UnifyOperation): void;
8
+ }
9
+ export declare class UsesCut extends ScopedVisitor {
10
+ visitExist(node: Exist): void;
11
+ }
12
+ export declare class UsesFail extends ScopedVisitor {
13
+ visitExist(node: Exist): void;
14
+ }
15
+ export declare const logicSmells: Record<string, VisitorConstructor>;
@@ -0,0 +1,60 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ import { Exist, isYukigoPrimitive, StopTraversalException, SymbolPrimitive, } from "yukigo-ast";
8
+ import { AutoScoped, ScopedVisitor } from "../../utils.js";
9
+ let HasRedundantReduction = class HasRedundantReduction extends ScopedVisitor {
10
+ visitAssignOperation(node) {
11
+ const left = node.left;
12
+ const right = node.right;
13
+ if (!(left instanceof SymbolPrimitive))
14
+ return;
15
+ const redundantReductionParameters = isYukigoPrimitive(right);
16
+ const redundantReductionFunctors = right instanceof Exist;
17
+ const isRedundant = redundantReductionParameters || redundantReductionFunctors;
18
+ if (isRedundant)
19
+ throw new StopTraversalException();
20
+ }
21
+ };
22
+ HasRedundantReduction = __decorate([
23
+ AutoScoped
24
+ ], HasRedundantReduction);
25
+ export { HasRedundantReduction };
26
+ let UsesUnificationOperator = class UsesUnificationOperator extends ScopedVisitor {
27
+ visitUnifyOperation(node) {
28
+ throw new StopTraversalException();
29
+ }
30
+ };
31
+ UsesUnificationOperator = __decorate([
32
+ AutoScoped
33
+ ], UsesUnificationOperator);
34
+ export { UsesUnificationOperator };
35
+ let UsesCut = class UsesCut extends ScopedVisitor {
36
+ visitExist(node) {
37
+ if (node.identifier.value === "!")
38
+ throw new StopTraversalException();
39
+ }
40
+ };
41
+ UsesCut = __decorate([
42
+ AutoScoped
43
+ ], UsesCut);
44
+ export { UsesCut };
45
+ let UsesFail = class UsesFail extends ScopedVisitor {
46
+ visitExist(node) {
47
+ if (node.identifier.value === "fail")
48
+ throw new StopTraversalException();
49
+ }
50
+ };
51
+ UsesFail = __decorate([
52
+ AutoScoped
53
+ ], UsesFail);
54
+ export { UsesFail };
55
+ export const logicSmells = {
56
+ HasRedundantReduction: HasRedundantReduction,
57
+ UsesCut: UsesCut,
58
+ UsesFail: UsesFail,
59
+ UsesUnificationOperator: UsesUnificationOperator,
60
+ };
@@ -0,0 +1,88 @@
1
+ import { Attribute, Class, Interface, Method, New, Object, PrimitiveMethod, Send, TraverseVisitor } from "yukigo-ast";
2
+ import { ScopedVisitor, VisitorConstructor } from "../../utils.js";
3
+ export declare class DeclaresAttribute extends ScopedVisitor {
4
+ private attributeName;
5
+ constructor(attributeName: string, scope?: string);
6
+ visitAttribute(node: Attribute): void;
7
+ }
8
+ export declare class DeclaresClass extends ScopedVisitor {
9
+ private className;
10
+ constructor(className: string, scope?: string);
11
+ visitClass(node: Class): void;
12
+ }
13
+ export declare class DeclaresInterface extends TraverseVisitor {
14
+ private interfaceName;
15
+ constructor(interfaceName: string);
16
+ visitInterface(node: Interface): void;
17
+ }
18
+ export declare class DeclaresMethod extends ScopedVisitor {
19
+ private methodName;
20
+ constructor(methodName: string, scope?: string);
21
+ visitMethod(node: Method): void;
22
+ }
23
+ export declare class DeclaresObject extends TraverseVisitor {
24
+ private objectName;
25
+ constructor(objectName: string);
26
+ visitObject(node: Object): void;
27
+ }
28
+ export declare class DeclaresPrimitive extends ScopedVisitor {
29
+ private operatorName;
30
+ constructor(operatorName: string, scope?: string);
31
+ visitPrimitiveMethod(node: PrimitiveMethod): void;
32
+ }
33
+ export declare class DeclaresSuperclass extends ScopedVisitor {
34
+ private superclassName;
35
+ constructor(superclassName: string, scope?: string);
36
+ visitClass(node: Class): void;
37
+ }
38
+ export declare class Implements extends ScopedVisitor {
39
+ private interfaceName;
40
+ constructor(interfaceName: string, scope?: string);
41
+ visitClass(node: Class): void;
42
+ }
43
+ export declare class IncludeMixin extends ScopedVisitor {
44
+ private mixinsName;
45
+ constructor(mixinsName: string, scope?: string);
46
+ visitClass(node: Class): void;
47
+ }
48
+ export declare class Instantiates extends ScopedVisitor {
49
+ private className;
50
+ constructor(className: string, scope?: string);
51
+ visitNew(node: New): void;
52
+ }
53
+ export declare class UsesDynamicPolymorphism extends ScopedVisitor {
54
+ private selectorName;
55
+ private count;
56
+ constructor(selectorName: string, scope?: string);
57
+ visitMethod(node: Method): void;
58
+ }
59
+ export declare class UsesInheritance extends ScopedVisitor {
60
+ constructor(scope?: string);
61
+ visitClass(node: Class): void;
62
+ visitInterface(node: Interface): void;
63
+ }
64
+ export declare class UsesMixins extends ScopedVisitor {
65
+ constructor(scope?: string);
66
+ visitClass(node: Class): void;
67
+ }
68
+ export declare class UsesObjectComposition extends ScopedVisitor {
69
+ constructor(scope?: string);
70
+ visitAttribute(node: Attribute): void;
71
+ }
72
+ export declare class UsesStaticMethodOverload extends TraverseVisitor {
73
+ private scopes;
74
+ visitClass(node: Class): void;
75
+ visitObject(node: Object): void;
76
+ visitMethod(node: Method): void;
77
+ }
78
+ export declare class UsesDynamicMethodOverload extends ScopedVisitor {
79
+ constructor(scope?: string);
80
+ visitMethod(node: Method): void;
81
+ }
82
+ export declare class UsesTemplateMethod extends ScopedVisitor {
83
+ private abstractMethodsStack;
84
+ constructor(scope?: string);
85
+ visitClass(node: Class): void;
86
+ visitSend(node: Send): void;
87
+ }
88
+ export declare const objectInspections: Record<string, VisitorConstructor>;
@@ -0,0 +1,319 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ import { New, Self, StopTraversalException, SymbolPrimitive, TraverseVisitor, } from "yukigo-ast";
8
+ import { AutoScoped, ScopedVisitor } from "../../utils.js";
9
+ let DeclaresAttribute = class DeclaresAttribute extends ScopedVisitor {
10
+ attributeName;
11
+ constructor(attributeName, scope) {
12
+ super(scope);
13
+ this.attributeName = attributeName;
14
+ }
15
+ visitAttribute(node) {
16
+ if (node.identifier.value === this.attributeName)
17
+ throw new StopTraversalException();
18
+ }
19
+ };
20
+ DeclaresAttribute = __decorate([
21
+ AutoScoped
22
+ ], DeclaresAttribute);
23
+ export { DeclaresAttribute };
24
+ let DeclaresClass = class DeclaresClass extends ScopedVisitor {
25
+ className;
26
+ constructor(className, scope) {
27
+ super(scope);
28
+ this.className = className;
29
+ }
30
+ visitClass(node) {
31
+ if (node.identifier.value === this.className)
32
+ throw new StopTraversalException();
33
+ }
34
+ };
35
+ DeclaresClass = __decorate([
36
+ AutoScoped
37
+ ], DeclaresClass);
38
+ export { DeclaresClass };
39
+ export class DeclaresInterface extends TraverseVisitor {
40
+ interfaceName;
41
+ constructor(interfaceName) {
42
+ super();
43
+ this.interfaceName = interfaceName;
44
+ }
45
+ visitInterface(node) {
46
+ if (node.identifier.value === this.interfaceName)
47
+ throw new StopTraversalException();
48
+ }
49
+ }
50
+ let DeclaresMethod = class DeclaresMethod extends ScopedVisitor {
51
+ methodName;
52
+ constructor(methodName, scope) {
53
+ super(scope);
54
+ this.methodName = methodName;
55
+ }
56
+ visitMethod(node) {
57
+ if (node.identifier.value === this.methodName)
58
+ throw new StopTraversalException();
59
+ }
60
+ };
61
+ DeclaresMethod = __decorate([
62
+ AutoScoped
63
+ ], DeclaresMethod);
64
+ export { DeclaresMethod };
65
+ export class DeclaresObject extends TraverseVisitor {
66
+ objectName;
67
+ constructor(objectName) {
68
+ super();
69
+ this.objectName = objectName;
70
+ }
71
+ visitObject(node) {
72
+ if (node.identifier.value === this.objectName)
73
+ throw new StopTraversalException();
74
+ }
75
+ }
76
+ let DeclaresPrimitive = class DeclaresPrimitive extends ScopedVisitor {
77
+ operatorName;
78
+ constructor(operatorName, scope) {
79
+ super(scope);
80
+ this.operatorName = operatorName;
81
+ }
82
+ visitPrimitiveMethod(node) {
83
+ if (node.operator === this.operatorName)
84
+ throw new StopTraversalException();
85
+ }
86
+ };
87
+ DeclaresPrimitive = __decorate([
88
+ AutoScoped
89
+ ], DeclaresPrimitive);
90
+ export { DeclaresPrimitive };
91
+ let DeclaresSuperclass = class DeclaresSuperclass extends ScopedVisitor {
92
+ superclassName;
93
+ constructor(superclassName, scope) {
94
+ super(scope);
95
+ this.superclassName = superclassName;
96
+ }
97
+ visitClass(node) {
98
+ if (node.extendsSymbol && node.extendsSymbol.value === this.superclassName)
99
+ throw new StopTraversalException();
100
+ }
101
+ };
102
+ DeclaresSuperclass = __decorate([
103
+ AutoScoped
104
+ ], DeclaresSuperclass);
105
+ export { DeclaresSuperclass };
106
+ let Implements = class Implements extends ScopedVisitor {
107
+ interfaceName;
108
+ constructor(interfaceName, scope) {
109
+ super(scope);
110
+ this.interfaceName = interfaceName;
111
+ }
112
+ visitClass(node) {
113
+ if (node.implementsNode &&
114
+ node.implementsNode.identifier.value === this.interfaceName)
115
+ throw new StopTraversalException();
116
+ }
117
+ };
118
+ Implements = __decorate([
119
+ AutoScoped
120
+ ], Implements);
121
+ export { Implements };
122
+ let IncludeMixin = class IncludeMixin extends ScopedVisitor {
123
+ mixinsName;
124
+ constructor(mixinsName, scope) {
125
+ super(scope);
126
+ this.mixinsName = mixinsName;
127
+ }
128
+ visitClass(node) {
129
+ if (node.includes.some((sym) => sym.value === this.mixinsName))
130
+ throw new StopTraversalException();
131
+ }
132
+ };
133
+ IncludeMixin = __decorate([
134
+ AutoScoped
135
+ ], IncludeMixin);
136
+ export { IncludeMixin };
137
+ let Instantiates = class Instantiates extends ScopedVisitor {
138
+ className;
139
+ constructor(className, scope) {
140
+ super(scope);
141
+ this.className = className;
142
+ }
143
+ visitNew(node) {
144
+ if (node.identifier.value === this.className)
145
+ throw new StopTraversalException();
146
+ }
147
+ };
148
+ Instantiates = __decorate([
149
+ AutoScoped
150
+ ], Instantiates);
151
+ export { Instantiates };
152
+ let UsesDynamicPolymorphism = class UsesDynamicPolymorphism extends ScopedVisitor {
153
+ selectorName;
154
+ count = 0;
155
+ constructor(selectorName, scope) {
156
+ super(scope);
157
+ this.selectorName = selectorName;
158
+ }
159
+ visitMethod(node) {
160
+ if (node.identifier.value === this.selectorName) {
161
+ this.count++;
162
+ if (this.count >= 2)
163
+ throw new StopTraversalException();
164
+ }
165
+ }
166
+ };
167
+ UsesDynamicPolymorphism = __decorate([
168
+ AutoScoped
169
+ ], UsesDynamicPolymorphism);
170
+ export { UsesDynamicPolymorphism };
171
+ let UsesInheritance = class UsesInheritance extends ScopedVisitor {
172
+ constructor(scope) {
173
+ super(scope);
174
+ }
175
+ visitClass(node) {
176
+ if (node.extendsSymbol)
177
+ throw new StopTraversalException();
178
+ }
179
+ visitInterface(node) {
180
+ if (node.extendsSymbol && node.extendsSymbol.length > 0)
181
+ throw new StopTraversalException();
182
+ }
183
+ };
184
+ UsesInheritance = __decorate([
185
+ AutoScoped
186
+ ], UsesInheritance);
187
+ export { UsesInheritance };
188
+ let UsesMixins = class UsesMixins extends ScopedVisitor {
189
+ constructor(scope) {
190
+ super(scope);
191
+ }
192
+ visitClass(node) {
193
+ if (node.includes.length > 0)
194
+ throw new StopTraversalException();
195
+ }
196
+ };
197
+ UsesMixins = __decorate([
198
+ AutoScoped
199
+ ], UsesMixins);
200
+ export { UsesMixins };
201
+ let UsesObjectComposition = class UsesObjectComposition extends ScopedVisitor {
202
+ constructor(scope) {
203
+ super(scope);
204
+ }
205
+ visitAttribute(node) {
206
+ if (node.expression instanceof New)
207
+ throw new StopTraversalException();
208
+ }
209
+ };
210
+ UsesObjectComposition = __decorate([
211
+ AutoScoped
212
+ ], UsesObjectComposition);
213
+ export { UsesObjectComposition };
214
+ export class UsesStaticMethodOverload extends TraverseVisitor {
215
+ scopes = [];
216
+ visitClass(node) {
217
+ this.scopes.push(new Set());
218
+ node.expression.accept(this);
219
+ this.scopes.pop();
220
+ }
221
+ visitObject(node) {
222
+ this.scopes.push(new Set());
223
+ node.expression.accept(this);
224
+ this.scopes.pop();
225
+ }
226
+ visitMethod(node) {
227
+ const currentScope = this.scopes[0];
228
+ const methodName = node.identifier.value;
229
+ if (currentScope.has(methodName))
230
+ throw new StopTraversalException();
231
+ currentScope.add(methodName);
232
+ }
233
+ }
234
+ let UsesDynamicMethodOverload = class UsesDynamicMethodOverload extends ScopedVisitor {
235
+ constructor(scope) {
236
+ super(scope);
237
+ }
238
+ visitMethod(node) {
239
+ if (node.equations.length > 1)
240
+ throw new StopTraversalException();
241
+ }
242
+ };
243
+ UsesDynamicMethodOverload = __decorate([
244
+ AutoScoped
245
+ ], UsesDynamicMethodOverload);
246
+ export { UsesDynamicMethodOverload };
247
+ let AbstractMethodCollector = class AbstractMethodCollector extends ScopedVisitor {
248
+ abstractMethods = new Set();
249
+ constructor(scope) {
250
+ super(scope);
251
+ }
252
+ visitMethod(node) {
253
+ if (node.getMetadata("isAbstract") === true)
254
+ this.abstractMethods.add(node.identifier.value);
255
+ }
256
+ // stop propagation to not mix scopes
257
+ visitClass(node) {
258
+ return;
259
+ }
260
+ visitObject(node) {
261
+ return;
262
+ }
263
+ };
264
+ AbstractMethodCollector = __decorate([
265
+ AutoScoped
266
+ ], AbstractMethodCollector);
267
+ let UsesTemplateMethod = class UsesTemplateMethod extends ScopedVisitor {
268
+ abstractMethodsStack = [];
269
+ constructor(scope) {
270
+ super(scope);
271
+ }
272
+ visitClass(node) {
273
+ const collector = new AbstractMethodCollector(this.binding);
274
+ if (node.expression)
275
+ node.expression.accept(collector);
276
+ this.abstractMethodsStack.push(collector.abstractMethods);
277
+ node.expression.accept(this);
278
+ this.abstractMethodsStack.pop();
279
+ }
280
+ visitSend(node) {
281
+ if (node.receiver instanceof Self) {
282
+ if (this.abstractMethodsStack.length === 0)
283
+ return;
284
+ const currentAbstractMethods = this.abstractMethodsStack[0];
285
+ // This doesnt match if message is complex expression
286
+ if (!(node.selector instanceof SymbolPrimitive))
287
+ return;
288
+ const selectorName = node.selector.value;
289
+ const isMessageAbstract = currentAbstractMethods.has(selectorName);
290
+ if (isMessageAbstract)
291
+ throw new StopTraversalException();
292
+ }
293
+ }
294
+ };
295
+ UsesTemplateMethod = __decorate([
296
+ AutoScoped
297
+ ], UsesTemplateMethod);
298
+ export { UsesTemplateMethod };
299
+ export const objectInspections = {
300
+ DeclaresAttribute: DeclaresAttribute,
301
+ DeclaresClass: DeclaresClass,
302
+ DeclaresInterface: DeclaresInterface,
303
+ DeclaresMethod: DeclaresMethod,
304
+ DeclaresObject: DeclaresObject,
305
+ DeclaresPrimitive: DeclaresPrimitive,
306
+ DeclaresSuperclass: DeclaresSuperclass,
307
+ Implements: Implements,
308
+ IncludeMixin: IncludeMixin,
309
+ Inherits: DeclaresSuperclass, // alias for DeclaresSuperclass
310
+ Instantiates: Instantiates,
311
+ UsesDynamicPolymorphism: UsesDynamicPolymorphism,
312
+ UsesInheritance: UsesInheritance,
313
+ UsesMixins: UsesMixins,
314
+ UsesObjectComposition: UsesObjectComposition,
315
+ UsesStaticMethodOverload: UsesStaticMethodOverload,
316
+ UsesDynamicMethodOverload: UsesDynamicMethodOverload,
317
+ UsesTemplateMethod: UsesTemplateMethod,
318
+ UsesStaticPolymorphism: UsesStaticMethodOverload, // alias for UsesStaticMethodOverload
319
+ };
@@ -0,0 +1,30 @@
1
+ import { Class, Interface, LogicalBinaryOperation, Method, Object, Return } from "yukigo-ast";
2
+ import { ScopedVisitor, VisitorConstructor } from "../../utils.js";
3
+ export declare class DoesNilTest extends ScopedVisitor {
4
+ visitLogicalBinaryOperation(node: LogicalBinaryOperation): void;
5
+ }
6
+ export declare class DoesTypeTest extends ScopedVisitor {
7
+ visitLogicalBinaryOperation(node: LogicalBinaryOperation): void;
8
+ }
9
+ export declare class ReturnsNil extends ScopedVisitor {
10
+ visitReturn(node: Return): void;
11
+ }
12
+ export declare class HasTooManyMethods extends ScopedVisitor {
13
+ private counter;
14
+ private readonly maxMethods;
15
+ constructor(maxMethods?: number, scopeName?: string);
16
+ visitInterface(node: Interface): void;
17
+ visitClass(node: Class): void;
18
+ visitObject(node: Object): void;
19
+ visitMethod(node: Method): void;
20
+ private checkMethodCount;
21
+ }
22
+ export declare class OverridesEqualOrHashButNotBoth extends ScopedVisitor {
23
+ visitClass(node: Class): void;
24
+ }
25
+ export declare class UsesNamedSelfReference extends ScopedVisitor {
26
+ visitObject(node: Object): void;
27
+ visitClass(node: Class): void;
28
+ private checkSelfReference;
29
+ }
30
+ export declare const objectSmells: Record<string, VisitorConstructor>;
@@ -0,0 +1,135 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ import { NilPrimitive, StopTraversalException, StringPrimitive, TraverseVisitor, } from "yukigo-ast";
8
+ import { AutoScoped, ScopedVisitor } from "../../utils.js";
9
+ import { Uses } from "../generic/generic.js";
10
+ class MethodCollector extends TraverseVisitor {
11
+ collectedMethods = [];
12
+ collect(node) {
13
+ node.expression.accept(this);
14
+ return this.collectedMethods;
15
+ }
16
+ visitMethod(node) {
17
+ this.collectedMethods.push(node);
18
+ }
19
+ }
20
+ let DoesNilTest = class DoesNilTest extends ScopedVisitor {
21
+ visitLogicalBinaryOperation(node) {
22
+ if (node.left instanceof NilPrimitive ||
23
+ node.right instanceof NilPrimitive) {
24
+ throw new StopTraversalException();
25
+ }
26
+ }
27
+ };
28
+ DoesNilTest = __decorate([
29
+ AutoScoped
30
+ ], DoesNilTest);
31
+ export { DoesNilTest };
32
+ let DoesTypeTest = class DoesTypeTest extends ScopedVisitor {
33
+ visitLogicalBinaryOperation(node) {
34
+ if (node.left instanceof StringPrimitive ||
35
+ node.right instanceof StringPrimitive) {
36
+ throw new StopTraversalException();
37
+ }
38
+ }
39
+ };
40
+ DoesTypeTest = __decorate([
41
+ AutoScoped
42
+ ], DoesTypeTest);
43
+ export { DoesTypeTest };
44
+ let ReturnsNil = class ReturnsNil extends ScopedVisitor {
45
+ visitReturn(node) {
46
+ if (!Boolean(node.body) || node.body instanceof NilPrimitive)
47
+ throw new StopTraversalException();
48
+ }
49
+ };
50
+ ReturnsNil = __decorate([
51
+ AutoScoped
52
+ ], ReturnsNil);
53
+ export { ReturnsNil };
54
+ let HasTooManyMethods = class HasTooManyMethods extends ScopedVisitor {
55
+ counter;
56
+ maxMethods;
57
+ constructor(maxMethods = 10, scopeName) {
58
+ super(scopeName);
59
+ this.maxMethods = maxMethods;
60
+ }
61
+ visitInterface(node) {
62
+ node.expression.accept(this);
63
+ this.checkMethodCount();
64
+ this.counter = 0;
65
+ }
66
+ visitClass(node) {
67
+ node.expression.accept(this);
68
+ this.checkMethodCount();
69
+ this.counter = 0;
70
+ }
71
+ visitObject(node) {
72
+ node.expression.accept(this);
73
+ this.checkMethodCount();
74
+ this.counter = 0;
75
+ }
76
+ visitMethod(node) {
77
+ this.counter += 1;
78
+ }
79
+ checkMethodCount() {
80
+ if (this.counter > this.maxMethods)
81
+ throw new StopTraversalException();
82
+ }
83
+ };
84
+ HasTooManyMethods = __decorate([
85
+ AutoScoped
86
+ ], HasTooManyMethods);
87
+ export { HasTooManyMethods };
88
+ let OverridesEqualOrHashButNotBoth = class OverridesEqualOrHashButNotBoth extends ScopedVisitor {
89
+ visitClass(node) {
90
+ const collector = new MethodCollector();
91
+ const methods = collector.collect(node);
92
+ const names = methods.map((m) => m.identifier.value);
93
+ const hasEquals = names.includes("equals") ||
94
+ names.includes("==") ||
95
+ names.includes("eql?");
96
+ const hasHash = names.includes("hashCode") || names.includes("hash");
97
+ if ((hasEquals && !hasHash) || (!hasEquals && hasHash))
98
+ throw new StopTraversalException();
99
+ }
100
+ };
101
+ OverridesEqualOrHashButNotBoth = __decorate([
102
+ AutoScoped
103
+ ], OverridesEqualOrHashButNotBoth);
104
+ export { OverridesEqualOrHashButNotBoth };
105
+ let UsesNamedSelfReference = class UsesNamedSelfReference extends ScopedVisitor {
106
+ visitObject(node) {
107
+ this.checkSelfReference(node.identifier.value, node.expression);
108
+ }
109
+ visitClass(node) {
110
+ this.checkSelfReference(node.identifier.value, node.expression);
111
+ }
112
+ checkSelfReference(selfName, body) {
113
+ const checker = new Uses(selfName, this.binding);
114
+ try {
115
+ body.accept(checker);
116
+ }
117
+ catch (e) {
118
+ if (e instanceof StopTraversalException)
119
+ throw new StopTraversalException();
120
+ throw e;
121
+ }
122
+ }
123
+ };
124
+ UsesNamedSelfReference = __decorate([
125
+ AutoScoped
126
+ ], UsesNamedSelfReference);
127
+ export { UsesNamedSelfReference };
128
+ export const objectSmells = {
129
+ DoesNilTest: DoesNilTest,
130
+ DoesTypeTest: DoesTypeTest,
131
+ HasTooManyMethods: HasTooManyMethods,
132
+ OverridesEqualOrHashButNotBoth: OverridesEqualOrHashButNotBoth,
133
+ ReturnsNil: ReturnsNil,
134
+ UsesNamedSelfReference: UsesNamedSelfReference,
135
+ };
@@ -1,4 +1,26 @@
1
- import { ASTNode, TraverseVisitor } from "@yukigo/ast";
2
- export type InspectionHandler = (node: ASTNode, args: string[], binding?: string) => boolean;
3
- export type InspectionMap = Record<string, InspectionHandler>;
4
- export declare function executeVisitor(node: ASTNode, visitor: TraverseVisitor): boolean;
1
+ import { Class, Fact, Function, Method, Object as YuObject, Procedure, Rule, TraverseVisitor, Variable } from "yukigo-ast";
2
+ export interface VisitorConstructor {
3
+ new (...args: any[]): TraverseVisitor & {
4
+ setBinding?(binding: string): void;
5
+ };
6
+ IS_INTRANSITIVE?: boolean;
7
+ }
8
+ export type InspectionMap = Record<string, VisitorConstructor>;
9
+ export declare class ScopedVisitor extends TraverseVisitor {
10
+ protected binding?: string;
11
+ inScope: boolean;
12
+ constructor(binding?: string);
13
+ setBinding(binding?: string): void;
14
+ visitVariable(node: Variable): void;
15
+ visitFunction(node: Function): void;
16
+ visitClass(node: Class): void;
17
+ visitObject(node: YuObject): void;
18
+ visitMethod(node: Method): void;
19
+ visitRule(node: Rule): void;
20
+ visitFact(node: Fact): void;
21
+ visitProcedure(node: Procedure): void;
22
+ private manageScope;
23
+ }
24
+ export declare function AutoScoped<T extends {
25
+ new (...args: any[]): any;
26
+ }>(constructor: T): void;