yukigo 0.1.0 → 0.1.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.
- package/.mocharc.json +3 -3
- 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 +10 -22
- package/dist/analyzer/index.js +99 -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/FunctionRuntime.d.ts +2 -2
- package/dist/interpreter/components/FunctionRuntime.js +34 -5
- package/dist/interpreter/components/LazyRuntime.d.ts +2 -2
- package/dist/interpreter/components/LazyRuntime.js +32 -13
- package/dist/interpreter/components/LogicEngine.d.ts +5 -2
- package/dist/interpreter/components/LogicEngine.js +40 -19
- package/dist/interpreter/components/LogicResolver.d.ts +1 -2
- package/dist/interpreter/components/LogicResolver.js +18 -8
- package/dist/interpreter/components/ObjectRuntime.d.ts +33 -0
- package/dist/interpreter/components/ObjectRuntime.js +123 -0
- package/dist/interpreter/components/Operations.d.ts +4 -4
- package/dist/interpreter/components/Operations.js +17 -2
- package/dist/interpreter/components/PatternMatcher.d.ts +46 -17
- package/dist/interpreter/components/PatternMatcher.js +264 -119
- package/dist/interpreter/components/RuntimeContext.d.ts +34 -0
- package/dist/interpreter/components/RuntimeContext.js +86 -0
- package/dist/interpreter/components/TestRunner.d.ts +18 -0
- package/dist/interpreter/components/TestRunner.js +144 -0
- package/dist/interpreter/components/Visitor.d.ts +63 -57
- package/dist/interpreter/components/Visitor.js +519 -172
- 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 +11 -0
- package/dist/interpreter/components/runtimes/FunctionRuntime.js +120 -0
- package/dist/interpreter/components/runtimes/LazyRuntime.d.ts +14 -0
- package/dist/interpreter/components/runtimes/LazyRuntime.js +238 -0
- package/dist/interpreter/components/runtimes/ObjectRuntime.d.ts +35 -0
- package/dist/interpreter/components/runtimes/ObjectRuntime.js +126 -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 +184 -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 +473 -254
- package/src/interpreter/components/RuntimeContext.ts +113 -0
- package/src/interpreter/components/TestRunner.ts +187 -0
- package/src/interpreter/components/Visitor.ts +1078 -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 +188 -0
- package/src/interpreter/components/runtimes/LazyRuntime.ts +301 -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 +164 -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 +981 -937
- package/tests/tester/Tester.spec.ts +153 -0
- package/tsconfig.build.json +15 -7
- package/tsconfig.json +25 -17
- package/tsconfig.tsbuildinfo +1 -0
- 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/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
package/.mocharc.json
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
{
|
|
2
|
-
"extension": ["ts"],
|
|
3
|
-
"spec": "tests/**/*.spec.ts"
|
|
1
|
+
{
|
|
2
|
+
"extension": ["ts"],
|
|
3
|
+
"spec": "tests/**/*.spec.ts"
|
|
4
4
|
}
|
package/README.md
CHANGED
|
@@ -1,199 +1,193 @@
|
|
|
1
|
-
# ❄️ Yukigo
|
|
2
|
-
A universal, multi-language, multi-paradigm code analyzer highly inspired in [mulang](https://github.com/mumuki/mulang)
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
### **
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
### **
|
|
15
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
```
|
|
195
|
-
|
|
196
|
-
The package `yukigo-ast` has all the current supported AST nodes.
|
|
197
|
-
For the grammar, you can use a tool like Jison or Nearley.
|
|
198
|
-
|
|
199
|
-
Here's a tutorial for implementing a small custom language.
|
|
1
|
+
# ❄️ Yukigo
|
|
2
|
+
A universal, multi-language, multi-paradigm code analyzer highly inspired in [mulang](https://github.com/mumuki/mulang)
|
|
3
|
+
|
|
4
|
+
## Components
|
|
5
|
+
|
|
6
|
+
### **Abstract Semantic Tree:**
|
|
7
|
+
|
|
8
|
+
This is the intermediate representation of any language. Allows us to analyse the semantics of the code independently of the paradigm or the language.
|
|
9
|
+
|
|
10
|
+
### **Analyzer:**
|
|
11
|
+
|
|
12
|
+
The Analyzer is the component that traverses the AST and runs the specified inspections.
|
|
13
|
+
|
|
14
|
+
### **Interpreter:**
|
|
15
|
+
|
|
16
|
+
The Interpreter is the component that evaluates provided Expression nodes and returns the resultant PrimitiveValue
|
|
17
|
+
|
|
18
|
+
# Usage
|
|
19
|
+
|
|
20
|
+
## Installation
|
|
21
|
+
|
|
22
|
+
We will be using Haskell as the target language in this example.
|
|
23
|
+
|
|
24
|
+
```
|
|
25
|
+
npm install yukigo yukigo-haskell-parser
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
or
|
|
29
|
+
|
|
30
|
+
```
|
|
31
|
+
yarn add yukigo yukigo-haskell-parser
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Example
|
|
35
|
+
|
|
36
|
+
```ts
|
|
37
|
+
import { Analyzer } from "yukigo";
|
|
38
|
+
import { YukigoHaskellParser } from "yukigo-haskell-parser";
|
|
39
|
+
|
|
40
|
+
const code = "doble num = num * 2";
|
|
41
|
+
const expectations = [
|
|
42
|
+
{
|
|
43
|
+
inspection: "HasBinding",
|
|
44
|
+
args: { name: "minimoEntre" },
|
|
45
|
+
expected: false,
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
inspection: "HasBinding",
|
|
49
|
+
args: { name: "doble" },
|
|
50
|
+
expected: true,
|
|
51
|
+
},
|
|
52
|
+
];
|
|
53
|
+
|
|
54
|
+
const parser = new YukigoHaskellParser();
|
|
55
|
+
const ast = parser.parse(code);
|
|
56
|
+
|
|
57
|
+
const analyzer = new ASTAnalyzer(ast);
|
|
58
|
+
const result = analyzer.analyse(expectations);
|
|
59
|
+
|
|
60
|
+
console.log(results);
|
|
61
|
+
// [
|
|
62
|
+
// {
|
|
63
|
+
// rule: {
|
|
64
|
+
// inspection: "HasBinding",
|
|
65
|
+
// args: { name: "minimoEntre" },
|
|
66
|
+
// expected: false,
|
|
67
|
+
// },
|
|
68
|
+
// passed: true,
|
|
69
|
+
// actual: false,
|
|
70
|
+
// },
|
|
71
|
+
// {
|
|
72
|
+
// rule: {
|
|
73
|
+
// inspection: "HasBinding",
|
|
74
|
+
// args: { name: "doble" },
|
|
75
|
+
// expected: true,
|
|
76
|
+
// },
|
|
77
|
+
// passed: true,
|
|
78
|
+
// actual: true,
|
|
79
|
+
// },
|
|
80
|
+
// ];
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## Example with Mulang's Inspections (in a YAML file)
|
|
84
|
+
|
|
85
|
+
```ts
|
|
86
|
+
import { Analyzer, translateMulangToInspectionRules } from "yukigo";
|
|
87
|
+
import { YukigoHaskellParser } from "yukigo-haskell-parser";
|
|
88
|
+
|
|
89
|
+
const code = `
|
|
90
|
+
squareList :: [Int] -> [Int]
|
|
91
|
+
squareList xs = map (\n -> n * n) xs
|
|
92
|
+
|
|
93
|
+
square :: Int -> Int
|
|
94
|
+
square n = n * n
|
|
95
|
+
|
|
96
|
+
squareList2 :: [Int] -> [Int]
|
|
97
|
+
squareList2 = map square
|
|
98
|
+
`;
|
|
99
|
+
|
|
100
|
+
// Assuming the expectations are in a yaml file. Implement a way to load the actual file.
|
|
101
|
+
const mulangInspections = `
|
|
102
|
+
expectations:
|
|
103
|
+
- !ruby/hash:ActiveSupport::HashWithIndifferentAccess
|
|
104
|
+
binding: squareList
|
|
105
|
+
inspection: HasBinding
|
|
106
|
+
- !ruby/hash:ActiveSupport::HashWithIndifferentAccess
|
|
107
|
+
binding: squareList
|
|
108
|
+
inspection: HasLambdaExpression
|
|
109
|
+
- !ruby/hash:ActiveSupport::HashWithIndifferentAccess
|
|
110
|
+
binding: square
|
|
111
|
+
inspection: HasArithmetic
|
|
112
|
+
- !ruby/hash:ActiveSupport::HashWithIndifferentAccess
|
|
113
|
+
binding: doble
|
|
114
|
+
inspection: Not:HasBinding
|
|
115
|
+
- !ruby/hash:ActiveSupport::HashWithIndifferentAccess
|
|
116
|
+
binding: square
|
|
117
|
+
inspection: Uses:n
|
|
118
|
+
- !ruby/hash:ActiveSupport::HashWithIndifferentAccess
|
|
119
|
+
binding: squareList2
|
|
120
|
+
inspection: Uses:map
|
|
121
|
+
`;
|
|
122
|
+
|
|
123
|
+
const expectations = translateMulangToInspectionRules(mulangInspections);
|
|
124
|
+
|
|
125
|
+
const parser = new YukigoHaskellParser();
|
|
126
|
+
const ast = parser.parse(code);
|
|
127
|
+
|
|
128
|
+
const analyzer = new Analyzer(ast);
|
|
129
|
+
const result = analyzer.analyse(expectations);
|
|
130
|
+
|
|
131
|
+
console.log(results);
|
|
132
|
+
// [
|
|
133
|
+
// {
|
|
134
|
+
// rule: { inspection: "HasBinding", args: [Object], expected: true },
|
|
135
|
+
// passed: true,
|
|
136
|
+
// actual: true,
|
|
137
|
+
// },
|
|
138
|
+
// {
|
|
139
|
+
// rule: {
|
|
140
|
+
// inspection: "HasLambdaExpression",
|
|
141
|
+
// args: [Object],
|
|
142
|
+
// expected: true,
|
|
143
|
+
// },
|
|
144
|
+
// passed: true,
|
|
145
|
+
// actual: true,
|
|
146
|
+
// },
|
|
147
|
+
// {
|
|
148
|
+
// rule: { inspection: "HasArithmetic", args: [Object], expected: true },
|
|
149
|
+
// passed: true,
|
|
150
|
+
// actual: true,
|
|
151
|
+
// },
|
|
152
|
+
// {
|
|
153
|
+
// rule: { inspection: "HasBinding", args: [Object], expected: false },
|
|
154
|
+
// passed: true,
|
|
155
|
+
// actual: false,
|
|
156
|
+
// },
|
|
157
|
+
// {
|
|
158
|
+
// rule: { inspection: "Uses", args: [Object], expected: true },
|
|
159
|
+
// passed: true,
|
|
160
|
+
// actual: true,
|
|
161
|
+
// },
|
|
162
|
+
// {
|
|
163
|
+
// rule: { inspection: "Uses", args: [Object], expected: true },
|
|
164
|
+
// passed: true,
|
|
165
|
+
// actual: true,
|
|
166
|
+
// },
|
|
167
|
+
// ];
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
# Relevant tools
|
|
171
|
+
- yukigo-ast: A library of AST node definitions and utilities for making yukigo parsers
|
|
172
|
+
|
|
173
|
+
## Tools
|
|
174
|
+
- [CLI](https://github.com/noiseArch/yukigo-cli)
|
|
175
|
+
- create-yukigo-parser: A scaffolding tool to quickstart a yukigo parser with recommended configuration
|
|
176
|
+
|
|
177
|
+
## Parsers
|
|
178
|
+
- Haskell
|
|
179
|
+
- Prolog
|
|
180
|
+
- Wollok
|
|
181
|
+
|
|
182
|
+
# How to make a parser
|
|
183
|
+
|
|
184
|
+
A yukigo's parser is a class that implements the interface `YukigoParser` which exposes a public method called `parse` and an `errors` array like this:
|
|
185
|
+
```ts
|
|
186
|
+
errors: string[];
|
|
187
|
+
parse: (code: string) => AST;
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
The package `yukigo-ast` has all the current supported AST nodes.
|
|
191
|
+
For the grammar, you can use a tool like Jison or Nearley.
|
|
192
|
+
|
|
193
|
+
Here's a [tutorial](https://miyukiproject.github.io/yukigo/guides/making-a-parser.html) for implementing a small custom language.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { Application, AST, ASTNode, Call, Class, Fact, Function, Interface, Method, New, Object as YuObject, Procedure, Rule, TraverseVisitor, TypeAlias, TypeSignature, Exist } from "yukigo-ast";
|
|
2
|
+
type DefinitionMap = Map<string, ASTNode[]>;
|
|
3
|
+
type CallsMap = Map<string, string[]>;
|
|
4
|
+
export type SymbolGraph = {
|
|
5
|
+
defs: DefinitionMap;
|
|
6
|
+
calls: CallsMap;
|
|
7
|
+
};
|
|
8
|
+
export declare class GraphBuilder extends TraverseVisitor {
|
|
9
|
+
private defs;
|
|
10
|
+
private calls;
|
|
11
|
+
private scope;
|
|
12
|
+
build(ast: AST): SymbolGraph;
|
|
13
|
+
private addDefinition;
|
|
14
|
+
visitFunction(node: Function): void;
|
|
15
|
+
visitMethod(node: Method): void;
|
|
16
|
+
visitProcedure(node: Procedure): void;
|
|
17
|
+
visitRule(node: Rule): void;
|
|
18
|
+
visitFact(node: Fact): void;
|
|
19
|
+
visitClass(node: Class): void;
|
|
20
|
+
visitObject(node: YuObject): void;
|
|
21
|
+
visitInterface(node: Interface): void;
|
|
22
|
+
visitTypeAlias(node: TypeAlias): void;
|
|
23
|
+
visitTypeSignature(node: TypeSignature): void;
|
|
24
|
+
visitCall(node: Call): void;
|
|
25
|
+
visitApplication(node: Application): void;
|
|
26
|
+
visitNew(node: New): void;
|
|
27
|
+
visitExist(node: Exist): void;
|
|
28
|
+
}
|
|
29
|
+
export {};
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { SymbolPrimitive, TraverseVisitor, } from "yukigo-ast";
|
|
2
|
+
export class GraphBuilder extends TraverseVisitor {
|
|
3
|
+
defs = new Map();
|
|
4
|
+
calls = new Map();
|
|
5
|
+
scope = "";
|
|
6
|
+
build(ast) {
|
|
7
|
+
ast.forEach((node) => node.accept(this));
|
|
8
|
+
return { defs: this.defs, calls: this.calls };
|
|
9
|
+
}
|
|
10
|
+
addDefinition(name, node) {
|
|
11
|
+
const existing = this.defs.get(name) || [];
|
|
12
|
+
this.defs.set(name, [...existing, node]);
|
|
13
|
+
}
|
|
14
|
+
visitFunction(node) {
|
|
15
|
+
this.scope = node.identifier.value;
|
|
16
|
+
this.addDefinition(this.scope, node);
|
|
17
|
+
this.traverseCollection(node.equations);
|
|
18
|
+
this.scope = "";
|
|
19
|
+
}
|
|
20
|
+
visitMethod(node) {
|
|
21
|
+
this.scope = node.identifier.value;
|
|
22
|
+
this.addDefinition(this.scope, node);
|
|
23
|
+
this.traverseCollection(node.equations);
|
|
24
|
+
this.scope = "";
|
|
25
|
+
}
|
|
26
|
+
visitProcedure(node) {
|
|
27
|
+
this.scope = node.identifier.value;
|
|
28
|
+
this.addDefinition(this.scope, node);
|
|
29
|
+
this.traverseCollection(node.equations);
|
|
30
|
+
this.scope = "";
|
|
31
|
+
}
|
|
32
|
+
visitRule(node) {
|
|
33
|
+
this.scope = node.identifier.value;
|
|
34
|
+
this.addDefinition(this.scope, node);
|
|
35
|
+
this.traverseCollection(node.equations);
|
|
36
|
+
this.scope = "";
|
|
37
|
+
}
|
|
38
|
+
visitFact(node) {
|
|
39
|
+
this.scope = node.identifier.value;
|
|
40
|
+
this.addDefinition(this.scope, node);
|
|
41
|
+
this.traverseCollection(node.patterns);
|
|
42
|
+
this.scope = "";
|
|
43
|
+
}
|
|
44
|
+
visitClass(node) {
|
|
45
|
+
this.scope = node.identifier.value;
|
|
46
|
+
this.addDefinition(this.scope, node);
|
|
47
|
+
node.expression.accept(this);
|
|
48
|
+
this.scope = "";
|
|
49
|
+
}
|
|
50
|
+
visitObject(node) {
|
|
51
|
+
this.scope = node.identifier.value;
|
|
52
|
+
this.addDefinition(this.scope, node);
|
|
53
|
+
node.expression.accept(this);
|
|
54
|
+
this.scope = "";
|
|
55
|
+
}
|
|
56
|
+
visitInterface(node) {
|
|
57
|
+
this.scope = node.identifier.value;
|
|
58
|
+
this.addDefinition(this.scope, node);
|
|
59
|
+
node.expression.accept(this);
|
|
60
|
+
this.scope = "";
|
|
61
|
+
}
|
|
62
|
+
visitTypeAlias(node) {
|
|
63
|
+
this.scope = node.identifier.value;
|
|
64
|
+
this.addDefinition(this.scope, node);
|
|
65
|
+
this.scope = "";
|
|
66
|
+
}
|
|
67
|
+
visitTypeSignature(node) {
|
|
68
|
+
this.scope = node.identifier.value;
|
|
69
|
+
this.addDefinition(this.scope, node);
|
|
70
|
+
this.scope = "";
|
|
71
|
+
}
|
|
72
|
+
visitCall(node) {
|
|
73
|
+
if (!this.scope)
|
|
74
|
+
return;
|
|
75
|
+
const arr = this.calls.get(this.scope) || [];
|
|
76
|
+
this.calls.set(this.scope, [node.callee.value, ...arr]);
|
|
77
|
+
}
|
|
78
|
+
visitApplication(node) {
|
|
79
|
+
if (!this.scope)
|
|
80
|
+
return;
|
|
81
|
+
const arr = this.calls.get(this.scope) || [];
|
|
82
|
+
if (node.functionExpr instanceof SymbolPrimitive)
|
|
83
|
+
this.calls.set(this.scope, [node.functionExpr.value, ...arr]);
|
|
84
|
+
else
|
|
85
|
+
node.functionExpr.accept(this);
|
|
86
|
+
}
|
|
87
|
+
visitNew(node) {
|
|
88
|
+
if (!this.scope)
|
|
89
|
+
return;
|
|
90
|
+
const arr = this.calls.get(this.scope) || [];
|
|
91
|
+
this.calls.set(this.scope, [node.identifier.value, ...arr]);
|
|
92
|
+
}
|
|
93
|
+
visitExist(node) {
|
|
94
|
+
if (!this.scope)
|
|
95
|
+
return;
|
|
96
|
+
const arr = this.calls.get(this.scope) || [];
|
|
97
|
+
this.calls.set(this.scope, [node.identifier.value, ...arr]);
|
|
98
|
+
}
|
|
99
|
+
}
|
package/dist/analyzer/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { AST } from "
|
|
2
|
-
import {
|
|
1
|
+
import { AST } from "yukigo-ast";
|
|
2
|
+
import { InspectionMap, VisitorConstructor } from "./utils.js";
|
|
3
3
|
export type AnalysisResult = {
|
|
4
4
|
rule: InspectionRule;
|
|
5
5
|
passed: boolean;
|
|
@@ -12,11 +12,12 @@ export type InspectionRule = {
|
|
|
12
12
|
args: string[];
|
|
13
13
|
expected: boolean;
|
|
14
14
|
};
|
|
15
|
-
export declare const
|
|
15
|
+
export declare const DefaultInspectionSet: InspectionMap;
|
|
16
|
+
export declare const DefaultSmellsSet: InspectionMap;
|
|
16
17
|
/**
|
|
17
18
|
* The Analyzer class.
|
|
18
19
|
* @remarks
|
|
19
|
-
* The Analyzer is the part of Yukigo which runs the inspections on the AST.
|
|
20
|
+
* The Analyzer is the part of Yukigo which runs the inspections on the AST.s
|
|
20
21
|
*/
|
|
21
22
|
export declare class Analyzer {
|
|
22
23
|
/**
|
|
@@ -24,27 +25,15 @@ export declare class Analyzer {
|
|
|
24
25
|
* You can load your set of inspections or leave the default one.
|
|
25
26
|
* @defaultValue a default set of inspections for each supported paradigm
|
|
26
27
|
*/
|
|
27
|
-
private
|
|
28
|
-
|
|
28
|
+
private inspectionConstructors;
|
|
29
|
+
private smellsConstructors;
|
|
30
|
+
constructor(inspectionSet?: InspectionMap, smellsSet?: InspectionMap);
|
|
29
31
|
/**
|
|
30
32
|
* Registers a new custom inspection handler after Analyzer was instantiated.
|
|
31
33
|
* @param name The name of the inspection (e.g., "HasArithmetic").
|
|
32
|
-
* @param
|
|
33
|
-
*
|
|
34
|
-
* @example
|
|
35
|
-
* // Implementation of HasArithmetic inspection
|
|
36
|
-
* export class UsesArithmetic extends TraverseVisitor {
|
|
37
|
-
* visitArithmeticBinaryOperation(node: ArithmeticBinaryOperation): void {
|
|
38
|
-
* throw new StopTraversalException();
|
|
39
|
-
* }
|
|
40
|
-
* visitArithmeticUnaryOperation(node: ArithmeticUnaryOperation): void {
|
|
41
|
-
* throw new StopTraversalException();
|
|
42
|
-
* }
|
|
43
|
-
* }
|
|
44
|
-
* const analyzer = new ASTAnalyzer(ast);
|
|
45
|
-
* analyzer.registerInspection("HasArithmetic", (node, args) => executeVisitor(node, new UsesArithmetic()));
|
|
34
|
+
* @param visitorConstructor The constructor for the TraverseVisitor class.
|
|
46
35
|
*/
|
|
47
|
-
registerInspection(name: string,
|
|
36
|
+
registerInspection(name: string, visitorConstructor: VisitorConstructor): void;
|
|
48
37
|
/**
|
|
49
38
|
* Runs a list of inspection rules against the AST.
|
|
50
39
|
* @param ast The parsed AST.
|
|
@@ -67,5 +56,4 @@ export declare class Analyzer {
|
|
|
67
56
|
* const analysisResults = analyzer.analyze(expectations);
|
|
68
57
|
*/
|
|
69
58
|
analyze(ast: AST, rules: InspectionRule[]): AnalysisResult[];
|
|
70
|
-
private runRule;
|
|
71
59
|
}
|