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.
- package/.mocharc.json +3 -3
- package/CHANGELOG.md +26 -0
- package/README.md +193 -199
- package/dist/analyzer/GraphBuilder.d.ts +29 -0
- package/dist/analyzer/GraphBuilder.js +99 -0
- package/dist/analyzer/index.d.ts +11 -23
- package/dist/analyzer/index.js +100 -58
- package/dist/analyzer/inspections/functional/functional.d.ts +44 -0
- package/dist/analyzer/inspections/functional/functional.js +149 -0
- package/dist/analyzer/inspections/functional/smells.d.ts +16 -0
- package/dist/analyzer/inspections/functional/smells.js +98 -0
- package/dist/analyzer/inspections/{generic.d.ts → generic/generic.d.ts} +70 -43
- package/dist/analyzer/inspections/generic/generic.js +604 -0
- package/dist/analyzer/inspections/generic/smells.d.ts +61 -0
- package/dist/analyzer/inspections/generic/smells.js +349 -0
- package/dist/analyzer/inspections/imperative/imperative.d.ts +35 -0
- package/dist/analyzer/inspections/imperative/imperative.js +109 -0
- package/dist/analyzer/inspections/imperative/smells.d.ts +16 -0
- package/dist/analyzer/inspections/imperative/smells.js +58 -0
- package/dist/analyzer/inspections/logic/logic.d.ts +32 -0
- package/dist/analyzer/inspections/logic/logic.js +96 -0
- package/dist/analyzer/inspections/logic/smells.d.ts +15 -0
- package/dist/analyzer/inspections/logic/smells.js +60 -0
- package/dist/analyzer/inspections/object/object.d.ts +88 -0
- package/dist/analyzer/inspections/object/object.js +319 -0
- package/dist/analyzer/inspections/object/smells.d.ts +30 -0
- package/dist/analyzer/inspections/object/smells.js +135 -0
- package/dist/analyzer/utils.d.ts +26 -4
- package/dist/analyzer/utils.js +71 -13
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/interpreter/components/EnvBuilder.d.ts +9 -5
- package/dist/interpreter/components/EnvBuilder.js +100 -30
- package/dist/interpreter/components/Operations.d.ts +4 -4
- package/dist/interpreter/components/Operations.js +17 -2
- package/dist/interpreter/components/PatternMatcher.d.ts +47 -17
- package/dist/interpreter/components/PatternMatcher.js +264 -119
- package/dist/interpreter/components/RuntimeContext.d.ts +35 -0
- package/dist/interpreter/components/RuntimeContext.js +93 -0
- package/dist/interpreter/components/TestRunner.d.ts +18 -0
- package/dist/interpreter/components/TestRunner.js +103 -0
- package/dist/interpreter/components/Visitor.d.ts +63 -57
- package/dist/interpreter/components/Visitor.js +508 -173
- package/dist/interpreter/components/logic/LogicEngine.d.ts +29 -0
- package/dist/interpreter/components/logic/LogicEngine.js +259 -0
- package/dist/interpreter/components/logic/LogicResolver.d.ts +53 -0
- package/dist/interpreter/components/logic/LogicResolver.js +471 -0
- package/dist/interpreter/components/logic/LogicTranslator.d.ts +14 -0
- package/dist/interpreter/components/logic/LogicTranslator.js +99 -0
- package/dist/interpreter/components/runtimes/FunctionRuntime.d.ts +12 -0
- package/dist/interpreter/components/runtimes/FunctionRuntime.js +147 -0
- package/dist/interpreter/components/runtimes/LazyRuntime.d.ts +19 -0
- package/dist/interpreter/components/runtimes/LazyRuntime.js +269 -0
- package/dist/interpreter/components/runtimes/ObjectRuntime.d.ts +35 -0
- package/dist/interpreter/components/runtimes/ObjectRuntime.js +126 -0
- package/dist/interpreter/entities.d.ts +105 -0
- package/dist/interpreter/entities.js +96 -0
- package/dist/interpreter/errors.d.ts +1 -1
- package/dist/interpreter/index.d.ts +4 -12
- package/dist/interpreter/index.js +10 -13
- package/dist/interpreter/trampoline.d.ts +17 -0
- package/dist/interpreter/trampoline.js +38 -0
- package/dist/interpreter/utils.d.ts +4 -7
- package/dist/interpreter/utils.js +25 -17
- package/dist/tester/index.d.ts +25 -0
- package/dist/tester/index.js +108 -0
- package/dist/utils/helpers.d.ts +0 -4
- package/dist/utils/helpers.js +20 -24
- package/package.json +2 -2
- package/src/analyzer/GraphBuilder.ts +142 -0
- package/src/analyzer/index.ts +185 -132
- package/src/analyzer/inspections/functional/functional.ts +121 -0
- package/src/analyzer/inspections/functional/smells.ts +102 -0
- package/src/analyzer/inspections/{generic.ts → generic/generic.ts} +581 -499
- package/src/analyzer/inspections/generic/smells.ts +365 -0
- package/src/analyzer/inspections/imperative/imperative.ts +101 -0
- package/src/analyzer/inspections/imperative/smells.ts +54 -0
- package/src/analyzer/inspections/logic/logic.ts +90 -0
- package/src/analyzer/inspections/logic/smells.ts +54 -0
- package/src/analyzer/inspections/{object.ts → object/object.ts} +264 -282
- package/src/analyzer/inspections/object/smells.ts +144 -0
- package/src/analyzer/utils.ts +109 -26
- package/src/index.ts +3 -2
- package/src/interpreter/components/EnvBuilder.ts +202 -97
- package/src/interpreter/components/Operations.ts +99 -81
- package/src/interpreter/components/PatternMatcher.ts +475 -254
- package/src/interpreter/components/RuntimeContext.ts +119 -0
- package/src/interpreter/components/TestRunner.ts +151 -0
- package/src/interpreter/components/Visitor.ts +1065 -493
- package/src/interpreter/components/logic/LogicEngine.ts +519 -0
- package/src/interpreter/components/logic/LogicResolver.ts +858 -0
- package/src/interpreter/components/logic/LogicTranslator.ts +149 -0
- package/src/interpreter/components/runtimes/FunctionRuntime.ts +227 -0
- package/src/interpreter/components/runtimes/LazyRuntime.ts +334 -0
- package/src/interpreter/components/runtimes/ObjectRuntime.ts +224 -0
- package/src/interpreter/errors.ts +47 -47
- package/src/interpreter/index.ts +52 -59
- package/src/interpreter/trampoline.ts +71 -0
- package/src/interpreter/utils.ts +84 -79
- package/src/tester/index.ts +128 -0
- package/src/utils/helpers.ts +67 -73
- package/tests/analyzer/functional.spec.ts +207 -221
- package/tests/analyzer/generic.spec.ts +178 -100
- package/tests/analyzer/helpers.spec.ts +83 -83
- package/tests/analyzer/logic.spec.ts +237 -292
- package/tests/analyzer/oop.spec.ts +323 -338
- package/tests/analyzer/transitive.spec.ts +166 -0
- package/tests/interpreter/EnvBuilder.spec.ts +183 -178
- package/tests/interpreter/FunctionRuntime.spec.ts +223 -234
- package/tests/interpreter/LazyRuntime.spec.ts +225 -190
- package/tests/interpreter/LogicEngine.spec.ts +327 -194
- package/tests/interpreter/LogicSubstitution.spec.ts +80 -0
- package/tests/interpreter/ObjectRuntime.spec.ts +606 -0
- package/tests/interpreter/Operations.spec.ts +220 -220
- package/tests/interpreter/PatternSystem.spec.ts +213 -189
- package/tests/interpreter/Tests.spec.ts +122 -0
- package/tests/interpreter/interpreter.spec.ts +991 -937
- package/tests/tester/Tester.spec.ts +153 -0
- package/tsconfig.build.json +15 -7
- package/tsconfig.json +25 -17
- package/dist/analyzer/inspections/functional.d.ts +0 -46
- package/dist/analyzer/inspections/functional.js +0 -123
- package/dist/analyzer/inspections/generic.js +0 -427
- package/dist/analyzer/inspections/imperative.d.ts +0 -37
- package/dist/analyzer/inspections/imperative.js +0 -105
- package/dist/analyzer/inspections/logic.d.ts +0 -49
- package/dist/analyzer/inspections/logic.js +0 -140
- package/dist/analyzer/inspections/object.d.ts +0 -83
- package/dist/analyzer/inspections/object.js +0 -235
- package/dist/interpreter/components/FunctionRuntime.d.ts +0 -8
- package/dist/interpreter/components/FunctionRuntime.js +0 -52
- package/dist/interpreter/components/LazyRuntime.d.ts +0 -7
- package/dist/interpreter/components/LazyRuntime.js +0 -75
- package/dist/interpreter/components/LogicEngine.d.ts +0 -21
- package/dist/interpreter/components/LogicEngine.js +0 -152
- package/dist/interpreter/components/LogicResolver.d.ts +0 -11
- package/dist/interpreter/components/LogicResolver.js +0 -87
- package/src/analyzer/inspections/functional.ts +0 -159
- package/src/analyzer/inspections/imperative.ts +0 -129
- package/src/analyzer/inspections/logic.ts +0 -166
- package/src/interpreter/components/FunctionRuntime.ts +0 -79
- package/src/interpreter/components/LazyRuntime.ts +0 -97
- package/src/interpreter/components/LogicEngine.ts +0 -227
- package/src/interpreter/components/LogicResolver.ts +0 -130
|
@@ -1,282 +1,264 @@
|
|
|
1
|
-
import {
|
|
2
|
-
Attribute,
|
|
3
|
-
Class,
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
} from "
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
node.implementsNode
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
this.count
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
class
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
Implements:
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
UsesMixins: (node, args) => executeVisitor(node, new UsesMixins()),
|
|
267
|
-
|
|
268
|
-
UsesObjectComposition: (node, args) =>
|
|
269
|
-
executeVisitor(node, new UsesObjectComposition()),
|
|
270
|
-
|
|
271
|
-
UsesStaticMethodOverload: (node, args) =>
|
|
272
|
-
executeVisitor(node, new UsesStaticMethodOverload()),
|
|
273
|
-
|
|
274
|
-
UsesDynamicMethodOverload: (node, args) =>
|
|
275
|
-
executeVisitor(node, new UsesDynamicMethodOverload()),
|
|
276
|
-
|
|
277
|
-
UsesTemplateMethod: (node, args) =>
|
|
278
|
-
executeVisitor(node, new UsesTemplateMethod()),
|
|
279
|
-
|
|
280
|
-
UsesStaticPolymorphism: (node, args) =>
|
|
281
|
-
executeVisitor(node, new UsesStaticMethodOverload()),
|
|
282
|
-
};
|
|
1
|
+
import {
|
|
2
|
+
Attribute,
|
|
3
|
+
Class,
|
|
4
|
+
Interface,
|
|
5
|
+
Method,
|
|
6
|
+
New,
|
|
7
|
+
Object,
|
|
8
|
+
PrimitiveMethod,
|
|
9
|
+
Self,
|
|
10
|
+
Send,
|
|
11
|
+
StopTraversalException,
|
|
12
|
+
SymbolPrimitive,
|
|
13
|
+
TraverseVisitor,
|
|
14
|
+
} from "yukigo-ast";
|
|
15
|
+
import { AutoScoped, ScopedVisitor, VisitorConstructor } from "../../utils.js";
|
|
16
|
+
@AutoScoped
|
|
17
|
+
export class DeclaresAttribute extends ScopedVisitor {
|
|
18
|
+
constructor(private attributeName: string, scope?: string) {
|
|
19
|
+
super(scope);
|
|
20
|
+
}
|
|
21
|
+
visitAttribute(node: Attribute): void {
|
|
22
|
+
if (node.identifier.value === this.attributeName)
|
|
23
|
+
throw new StopTraversalException();
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
@AutoScoped
|
|
27
|
+
export class DeclaresClass extends ScopedVisitor {
|
|
28
|
+
constructor(private className: string, scope?: string) {
|
|
29
|
+
super(scope);
|
|
30
|
+
}
|
|
31
|
+
visitClass(node: Class): void {
|
|
32
|
+
if (node.identifier.value === this.className)
|
|
33
|
+
throw new StopTraversalException();
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export class DeclaresInterface extends TraverseVisitor {
|
|
38
|
+
constructor(private interfaceName: string) {
|
|
39
|
+
super();
|
|
40
|
+
}
|
|
41
|
+
visitInterface(node: Interface): void {
|
|
42
|
+
if (node.identifier.value === this.interfaceName)
|
|
43
|
+
throw new StopTraversalException();
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
@AutoScoped
|
|
47
|
+
export class DeclaresMethod extends ScopedVisitor {
|
|
48
|
+
constructor(private methodName: string, scope?: string) {
|
|
49
|
+
super(scope);
|
|
50
|
+
}
|
|
51
|
+
visitMethod(node: Method): void {
|
|
52
|
+
if (node.identifier.value === this.methodName)
|
|
53
|
+
throw new StopTraversalException();
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export class DeclaresObject extends TraverseVisitor {
|
|
58
|
+
constructor(private objectName: string) {
|
|
59
|
+
super();
|
|
60
|
+
}
|
|
61
|
+
visitObject(node: Object): void {
|
|
62
|
+
if (node.identifier.value === this.objectName)
|
|
63
|
+
throw new StopTraversalException();
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
@AutoScoped
|
|
67
|
+
export class DeclaresPrimitive extends ScopedVisitor {
|
|
68
|
+
constructor(private operatorName: string, scope?: string) {
|
|
69
|
+
super(scope);
|
|
70
|
+
}
|
|
71
|
+
visitPrimitiveMethod(node: PrimitiveMethod): void {
|
|
72
|
+
if (node.operator === this.operatorName) throw new StopTraversalException();
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
@AutoScoped
|
|
76
|
+
export class DeclaresSuperclass extends ScopedVisitor {
|
|
77
|
+
constructor(private superclassName: string, scope?: string) {
|
|
78
|
+
super(scope);
|
|
79
|
+
}
|
|
80
|
+
visitClass(node: Class): void {
|
|
81
|
+
if (node.extendsSymbol && node.extendsSymbol.value === this.superclassName)
|
|
82
|
+
throw new StopTraversalException();
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
@AutoScoped
|
|
86
|
+
export class Implements extends ScopedVisitor {
|
|
87
|
+
constructor(private interfaceName: string, scope?: string) {
|
|
88
|
+
super(scope);
|
|
89
|
+
}
|
|
90
|
+
visitClass(node: Class): void {
|
|
91
|
+
if (
|
|
92
|
+
node.implementsNode &&
|
|
93
|
+
node.implementsNode.identifier.value === this.interfaceName
|
|
94
|
+
)
|
|
95
|
+
throw new StopTraversalException();
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
@AutoScoped
|
|
99
|
+
export class IncludeMixin extends ScopedVisitor {
|
|
100
|
+
constructor(private mixinsName: string, scope?: string) {
|
|
101
|
+
super(scope);
|
|
102
|
+
}
|
|
103
|
+
visitClass(node: Class): void {
|
|
104
|
+
if (node.includes.some((sym) => sym.value === this.mixinsName))
|
|
105
|
+
throw new StopTraversalException();
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
@AutoScoped
|
|
109
|
+
export class Instantiates extends ScopedVisitor {
|
|
110
|
+
constructor(private className: string, scope?: string) {
|
|
111
|
+
super(scope);
|
|
112
|
+
}
|
|
113
|
+
visitNew(node: New): void {
|
|
114
|
+
if (node.identifier.value === this.className)
|
|
115
|
+
throw new StopTraversalException();
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
@AutoScoped
|
|
119
|
+
export class UsesDynamicPolymorphism extends ScopedVisitor {
|
|
120
|
+
private count = 0;
|
|
121
|
+
|
|
122
|
+
constructor(private selectorName: string, scope?: string) {
|
|
123
|
+
super(scope);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
visitMethod(node: Method): void {
|
|
127
|
+
if (node.identifier.value === this.selectorName) {
|
|
128
|
+
this.count++;
|
|
129
|
+
if (this.count >= 2) throw new StopTraversalException();
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
@AutoScoped
|
|
134
|
+
export class UsesInheritance extends ScopedVisitor {
|
|
135
|
+
constructor(scope?: string) {
|
|
136
|
+
super(scope);
|
|
137
|
+
}
|
|
138
|
+
visitClass(node: Class): void {
|
|
139
|
+
if (node.extendsSymbol) throw new StopTraversalException();
|
|
140
|
+
}
|
|
141
|
+
visitInterface(node: Interface): void {
|
|
142
|
+
if (node.extendsSymbol && node.extendsSymbol.length > 0)
|
|
143
|
+
throw new StopTraversalException();
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
@AutoScoped
|
|
147
|
+
export class UsesMixins extends ScopedVisitor {
|
|
148
|
+
constructor(scope?: string) {
|
|
149
|
+
super(scope);
|
|
150
|
+
}
|
|
151
|
+
visitClass(node: Class): void {
|
|
152
|
+
if (node.includes.length > 0) throw new StopTraversalException();
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
@AutoScoped
|
|
156
|
+
export class UsesObjectComposition extends ScopedVisitor {
|
|
157
|
+
constructor(scope?: string) {
|
|
158
|
+
super(scope);
|
|
159
|
+
}
|
|
160
|
+
visitAttribute(node: Attribute): void {
|
|
161
|
+
if (node.expression instanceof New) throw new StopTraversalException();
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
export class UsesStaticMethodOverload extends TraverseVisitor {
|
|
166
|
+
private scopes: Set<string>[] = [];
|
|
167
|
+
visitClass(node: Class): void {
|
|
168
|
+
this.scopes.push(new Set());
|
|
169
|
+
node.expression.accept(this);
|
|
170
|
+
this.scopes.pop();
|
|
171
|
+
}
|
|
172
|
+
visitObject(node: Object): void {
|
|
173
|
+
this.scopes.push(new Set());
|
|
174
|
+
node.expression.accept(this);
|
|
175
|
+
this.scopes.pop();
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
visitMethod(node: Method): void {
|
|
179
|
+
const currentScope = this.scopes[0];
|
|
180
|
+
const methodName = node.identifier.value;
|
|
181
|
+
|
|
182
|
+
if (currentScope.has(methodName)) throw new StopTraversalException();
|
|
183
|
+
currentScope.add(methodName);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
@AutoScoped
|
|
187
|
+
export class UsesDynamicMethodOverload extends ScopedVisitor {
|
|
188
|
+
constructor(scope?: string) {
|
|
189
|
+
super(scope);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
visitMethod(node: Method): void {
|
|
193
|
+
if (node.equations.length > 1) throw new StopTraversalException();
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
@AutoScoped
|
|
197
|
+
class AbstractMethodCollector extends ScopedVisitor {
|
|
198
|
+
public abstractMethods: Set<string> = new Set();
|
|
199
|
+
constructor(scope?: string) {
|
|
200
|
+
super(scope);
|
|
201
|
+
}
|
|
202
|
+
visitMethod(node: Method): void {
|
|
203
|
+
if (node.getMetadata<boolean>("isAbstract") === true)
|
|
204
|
+
this.abstractMethods.add(node.identifier.value);
|
|
205
|
+
}
|
|
206
|
+
// stop propagation to not mix scopes
|
|
207
|
+
visitClass(node: Class) {
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
visitObject(node: Object) {
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
@AutoScoped
|
|
215
|
+
export class UsesTemplateMethod extends ScopedVisitor {
|
|
216
|
+
private abstractMethodsStack: Set<string>[] = [];
|
|
217
|
+
constructor(scope?: string) {
|
|
218
|
+
super(scope);
|
|
219
|
+
}
|
|
220
|
+
visitClass(node: Class): void {
|
|
221
|
+
const collector = new AbstractMethodCollector(this.binding);
|
|
222
|
+
if (node.expression) node.expression.accept(collector);
|
|
223
|
+
this.abstractMethodsStack.push(collector.abstractMethods);
|
|
224
|
+
node.expression.accept(this);
|
|
225
|
+
this.abstractMethodsStack.pop();
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
visitSend(node: Send): void {
|
|
229
|
+
if (node.receiver instanceof Self) {
|
|
230
|
+
if (this.abstractMethodsStack.length === 0) return;
|
|
231
|
+
const currentAbstractMethods = this.abstractMethodsStack[0];
|
|
232
|
+
|
|
233
|
+
// This doesnt match if message is complex expression
|
|
234
|
+
if (!(node.selector instanceof SymbolPrimitive)) return;
|
|
235
|
+
const selectorName = node.selector.value;
|
|
236
|
+
|
|
237
|
+
const isMessageAbstract = currentAbstractMethods.has(selectorName);
|
|
238
|
+
|
|
239
|
+
if (isMessageAbstract) throw new StopTraversalException();
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
export const objectInspections: Record<string, VisitorConstructor> = {
|
|
245
|
+
DeclaresAttribute: DeclaresAttribute,
|
|
246
|
+
DeclaresClass: DeclaresClass,
|
|
247
|
+
DeclaresInterface: DeclaresInterface,
|
|
248
|
+
DeclaresMethod: DeclaresMethod,
|
|
249
|
+
DeclaresObject: DeclaresObject,
|
|
250
|
+
DeclaresPrimitive: DeclaresPrimitive,
|
|
251
|
+
DeclaresSuperclass: DeclaresSuperclass,
|
|
252
|
+
Implements: Implements,
|
|
253
|
+
IncludeMixin: IncludeMixin,
|
|
254
|
+
Inherits: DeclaresSuperclass, // alias for DeclaresSuperclass
|
|
255
|
+
Instantiates: Instantiates,
|
|
256
|
+
UsesDynamicPolymorphism: UsesDynamicPolymorphism,
|
|
257
|
+
UsesInheritance: UsesInheritance,
|
|
258
|
+
UsesMixins: UsesMixins,
|
|
259
|
+
UsesObjectComposition: UsesObjectComposition,
|
|
260
|
+
UsesStaticMethodOverload: UsesStaticMethodOverload,
|
|
261
|
+
UsesDynamicMethodOverload: UsesDynamicMethodOverload,
|
|
262
|
+
UsesTemplateMethod: UsesTemplateMethod,
|
|
263
|
+
UsesStaticPolymorphism: UsesStaticMethodOverload, // alias for UsesStaticMethodOverload
|
|
264
|
+
};
|