yukigo 0.2.0 → 0.2.2
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/CHANGELOG.md +28 -0
- package/dist/analyzer/index.d.ts +7 -0
- package/dist/src/analyzer/GraphBuilder.d.ts +30 -0
- package/dist/src/analyzer/GraphBuilder.js +100 -0
- package/dist/src/analyzer/index.d.ts +59 -0
- package/dist/src/analyzer/index.js +152 -0
- package/dist/src/analyzer/inspections/functional/functional.d.ts +44 -0
- package/dist/src/analyzer/inspections/functional/functional.js +149 -0
- package/dist/src/analyzer/inspections/functional/smells.d.ts +16 -0
- package/dist/src/analyzer/inspections/functional/smells.js +98 -0
- package/dist/src/analyzer/inspections/generic/generic.d.ts +178 -0
- package/dist/src/analyzer/inspections/generic/generic.js +604 -0
- package/dist/src/analyzer/inspections/generic/smells.d.ts +61 -0
- package/dist/src/analyzer/inspections/generic/smells.js +349 -0
- package/dist/src/analyzer/inspections/imperative/imperative.d.ts +35 -0
- package/dist/src/analyzer/inspections/imperative/imperative.js +109 -0
- package/dist/src/analyzer/inspections/imperative/smells.d.ts +16 -0
- package/dist/src/analyzer/inspections/imperative/smells.js +58 -0
- package/dist/src/analyzer/inspections/logic/logic.d.ts +32 -0
- package/dist/src/analyzer/inspections/logic/logic.js +96 -0
- package/dist/src/analyzer/inspections/logic/smells.d.ts +15 -0
- package/dist/src/analyzer/inspections/logic/smells.js +60 -0
- package/dist/src/analyzer/inspections/object/object.d.ts +90 -0
- package/dist/src/analyzer/inspections/object/object.js +321 -0
- package/dist/src/analyzer/inspections/object/smells.d.ts +30 -0
- package/dist/src/analyzer/inspections/object/smells.js +135 -0
- package/dist/src/analyzer/utils.d.ts +30 -0
- package/dist/src/analyzer/utils.js +78 -0
- package/dist/src/index.d.ts +4 -0
- package/dist/src/index.js +4 -0
- package/dist/src/interpreter/components/EnvBuilder.d.ts +21 -0
- package/dist/src/interpreter/components/EnvBuilder.js +155 -0
- package/dist/src/interpreter/components/Operations.d.ts +14 -0
- package/dist/src/interpreter/components/Operations.js +84 -0
- package/dist/src/interpreter/components/PatternMatcher.d.ts +73 -0
- package/dist/src/interpreter/components/PatternMatcher.js +358 -0
- package/dist/src/interpreter/components/RuntimeContext.d.ts +35 -0
- package/dist/src/interpreter/components/RuntimeContext.js +93 -0
- package/dist/src/interpreter/components/TestRunner.d.ts +19 -0
- package/dist/src/interpreter/components/TestRunner.js +110 -0
- package/dist/src/interpreter/components/Visitor.d.ts +71 -0
- package/dist/src/interpreter/components/Visitor.js +638 -0
- package/dist/src/interpreter/components/logic/LogicEngine.d.ts +29 -0
- package/dist/src/interpreter/components/logic/LogicEngine.js +259 -0
- package/dist/src/interpreter/components/logic/LogicResolver.d.ts +53 -0
- package/dist/src/interpreter/components/logic/LogicResolver.js +484 -0
- package/dist/src/interpreter/components/logic/LogicTranslator.d.ts +14 -0
- package/dist/src/interpreter/components/logic/LogicTranslator.js +99 -0
- package/dist/src/interpreter/components/runtimes/FunctionRuntime.d.ts +12 -0
- package/dist/src/interpreter/components/runtimes/FunctionRuntime.js +149 -0
- package/dist/src/interpreter/components/runtimes/LazyRuntime.d.ts +19 -0
- package/dist/src/interpreter/components/runtimes/LazyRuntime.js +269 -0
- package/dist/src/interpreter/components/runtimes/ObjectRuntime.d.ts +35 -0
- package/dist/src/interpreter/components/runtimes/ObjectRuntime.js +126 -0
- package/dist/src/interpreter/errors.d.ts +19 -0
- package/dist/src/interpreter/errors.js +36 -0
- package/dist/src/interpreter/index.d.ts +24 -0
- package/dist/src/interpreter/index.js +41 -0
- package/dist/src/interpreter/trampoline.d.ts +17 -0
- package/dist/src/interpreter/trampoline.js +38 -0
- package/dist/src/interpreter/utils.d.ts +11 -0
- package/dist/src/interpreter/utils.js +65 -0
- package/dist/src/tester/index.d.ts +25 -0
- package/dist/src/tester/index.js +113 -0
- package/dist/src/utils/helpers.d.ts +13 -0
- package/dist/src/utils/helpers.js +52 -0
- package/dist/utils/helpers.d.ts +5 -1
- package/dist/utils/helpers.js +79 -6
- package/package.json +4 -2
- package/src/analyzer/index.ts +9 -0
- package/src/utils/helpers.ts +111 -10
- package/tests/analyzer/helpers.spec.ts +14 -8
- package/tests/tester/Tester.spec.ts +0 -1
package/src/utils/helpers.ts
CHANGED
|
@@ -1,11 +1,26 @@
|
|
|
1
1
|
import { parseDocument } from "yaml";
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
InspectionRule,
|
|
4
|
+
TargetSuffix,
|
|
5
|
+
} from "../analyzer/index.js";
|
|
6
|
+
|
|
7
|
+
const declareMap: Record<string, string> = {
|
|
8
|
+
HasBinding: "Declares",
|
|
9
|
+
HasTypeDeclaration: "DeclaresTypeAlias",
|
|
10
|
+
HasTypeSignature: "DeclaresTypeSignature",
|
|
11
|
+
HasVariable: "DeclaresVariable",
|
|
12
|
+
HasDirectRecursion: "DeclaresRecursively",
|
|
13
|
+
};
|
|
3
14
|
|
|
4
15
|
type MulangInspection = {
|
|
5
16
|
inspection: string;
|
|
6
17
|
binding: string;
|
|
18
|
+
args?: string[];
|
|
7
19
|
};
|
|
8
20
|
|
|
21
|
+
const NEGATION_PREFIXES = new Set(["Not", "Except"]);
|
|
22
|
+
const SUFFIX_ARGS = new Set<TargetSuffix>(["like", "except"]);
|
|
23
|
+
|
|
9
24
|
const isValidFormat = (inspection: any): inspection is MulangInspection =>
|
|
10
25
|
typeof inspection === "object" &&
|
|
11
26
|
"inspection" in inspection &&
|
|
@@ -17,22 +32,27 @@ const isValidFormat = (inspection: any): inspection is MulangInspection =>
|
|
|
17
32
|
* @returns An array of InspectionRule objects.
|
|
18
33
|
*/
|
|
19
34
|
export class MulangAdapter {
|
|
20
|
-
public translateMulangInspection(mulangInspection:
|
|
35
|
+
public translateMulangInspection(mulangInspection: unknown): InspectionRule {
|
|
21
36
|
if (!isValidFormat(mulangInspection))
|
|
22
37
|
throw new Error(
|
|
23
|
-
`Skipping malformed Mulang inspection entry: ${mulangInspection}
|
|
38
|
+
`Skipping malformed Mulang inspection entry: ${mulangInspection}`,
|
|
24
39
|
);
|
|
25
40
|
|
|
26
|
-
|
|
27
|
-
const expected
|
|
28
|
-
|
|
29
|
-
|
|
41
|
+
// transforms Mulang v0 to v2
|
|
42
|
+
const { inspection, expected, binding, args } =
|
|
43
|
+
this.transformToV2(mulangInspection);
|
|
44
|
+
|
|
45
|
+
const { resolvedArgs, targetSuffix, matcher } =
|
|
46
|
+
this.retrieveArguments(args);
|
|
30
47
|
|
|
31
48
|
return {
|
|
32
|
-
inspection
|
|
49
|
+
inspection,
|
|
33
50
|
expected,
|
|
34
|
-
|
|
35
|
-
|
|
51
|
+
binding,
|
|
52
|
+
args: resolvedArgs,
|
|
53
|
+
// these should not exist in the InspectionRule if they are undefined
|
|
54
|
+
...(targetSuffix !== undefined && { targetSuffix }),
|
|
55
|
+
...(matcher !== undefined && { matcher }),
|
|
36
56
|
};
|
|
37
57
|
}
|
|
38
58
|
|
|
@@ -64,4 +84,85 @@ export class MulangAdapter {
|
|
|
64
84
|
|
|
65
85
|
return inspectionRules;
|
|
66
86
|
}
|
|
87
|
+
|
|
88
|
+
private transformToV2(mulangInspection: MulangInspection) {
|
|
89
|
+
const parts = mulangInspection.inspection.split(":");
|
|
90
|
+
const {
|
|
91
|
+
expected,
|
|
92
|
+
inspection,
|
|
93
|
+
args: parsedArgs,
|
|
94
|
+
} = this.parseNegation(parts);
|
|
95
|
+
const args = mulangInspection.args ?? parsedArgs;
|
|
96
|
+
const v2 = this.applyV0ToV2(inspection, args, mulangInspection.binding);
|
|
97
|
+
return { expected, ...v2 };
|
|
98
|
+
}
|
|
99
|
+
private parseNegation(parts: string[]) {
|
|
100
|
+
const negated = NEGATION_PREFIXES.has(parts[0]);
|
|
101
|
+
return {
|
|
102
|
+
expected: !negated,
|
|
103
|
+
inspection: parts[negated ? 1 : 0],
|
|
104
|
+
args: parts.slice(negated ? 2 : 1),
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
private applyV0ToV2(inspection: string, args: string[], binding: string) {
|
|
108
|
+
if (inspection in declareMap)
|
|
109
|
+
return {
|
|
110
|
+
inspection: declareMap[inspection],
|
|
111
|
+
...promoteBindingToTarget(args, binding),
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
if (inspection === "HasArity")
|
|
115
|
+
return {
|
|
116
|
+
inspection: `DeclaresComputationWithArity${args[0]}`,
|
|
117
|
+
...promoteBindingToTarget([], binding),
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
if (inspection.startsWith("Has"))
|
|
121
|
+
return {
|
|
122
|
+
inspection: inspection.replace(/^Has(Usage)?/, (_, usage) =>
|
|
123
|
+
usage ? "Uses" : "Uses",
|
|
124
|
+
),
|
|
125
|
+
args,
|
|
126
|
+
binding,
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
return { inspection, args, binding };
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
private retrieveArguments(args: string[]) {
|
|
133
|
+
const targetSuffix = args.find((a): a is TargetSuffix =>
|
|
134
|
+
SUFFIX_ARGS.has(a as TargetSuffix),
|
|
135
|
+
);
|
|
136
|
+
|
|
137
|
+
const matcherIndex = args.findIndex((a) => a.startsWith("With"));
|
|
138
|
+
const matcher =
|
|
139
|
+
matcherIndex !== -1
|
|
140
|
+
? {
|
|
141
|
+
type: "with_" + args[matcherIndex].slice(4).toLowerCase(),
|
|
142
|
+
value: args[matcherIndex + 1],
|
|
143
|
+
}
|
|
144
|
+
: undefined;
|
|
145
|
+
|
|
146
|
+
const consumed = new Set([
|
|
147
|
+
...(targetSuffix ? [targetSuffix] : []),
|
|
148
|
+
...(matcherIndex !== -1
|
|
149
|
+
? [args[matcherIndex], args[matcherIndex + 1]]
|
|
150
|
+
: []),
|
|
151
|
+
]);
|
|
152
|
+
|
|
153
|
+
const resolvedArgs = args.filter((a) => !consumed.has(a));
|
|
154
|
+
|
|
155
|
+
return {
|
|
156
|
+
targetSuffix:
|
|
157
|
+
targetSuffix ??
|
|
158
|
+
(resolvedArgs.length > 0 ? ("named" as TargetSuffix) : undefined),
|
|
159
|
+
matcher,
|
|
160
|
+
resolvedArgs,
|
|
161
|
+
};
|
|
162
|
+
}
|
|
67
163
|
}
|
|
164
|
+
|
|
165
|
+
const promoteBindingToTarget = (args: string[], binding: string) => ({
|
|
166
|
+
args: binding && binding !== "*" ? [binding, ...args] : args,
|
|
167
|
+
binding: "*",
|
|
168
|
+
});
|
|
@@ -31,48 +31,54 @@ expectations:
|
|
|
31
31
|
|
|
32
32
|
const yukigoExpectations =
|
|
33
33
|
mulangAdapter.translateMulangExpectations(mulangExpectations);
|
|
34
|
+
|
|
34
35
|
assert.deepEqual(yukigoExpectations, [
|
|
35
36
|
{
|
|
36
|
-
inspection: "
|
|
37
|
-
binding: "
|
|
38
|
-
args: [],
|
|
37
|
+
inspection: "Declares",
|
|
38
|
+
binding: "*",
|
|
39
|
+
args: ["squareList"],
|
|
39
40
|
expected: true,
|
|
41
|
+
targetSuffix: "named",
|
|
40
42
|
},
|
|
41
43
|
{
|
|
42
|
-
inspection: "
|
|
44
|
+
inspection: "UsesLambdaExpression",
|
|
43
45
|
binding: "squareList",
|
|
44
46
|
args: [],
|
|
45
47
|
expected: true,
|
|
46
48
|
},
|
|
47
49
|
{
|
|
48
|
-
inspection: "
|
|
50
|
+
inspection: "UsesArithmetic",
|
|
49
51
|
binding: "square",
|
|
50
52
|
args: [],
|
|
51
53
|
expected: true,
|
|
52
54
|
},
|
|
53
55
|
{
|
|
54
|
-
inspection: "
|
|
55
|
-
binding: "
|
|
56
|
-
args: [],
|
|
56
|
+
inspection: "Declares",
|
|
57
|
+
binding: "*",
|
|
58
|
+
args: ["doble"],
|
|
57
59
|
expected: false,
|
|
60
|
+
targetSuffix: "named",
|
|
58
61
|
},
|
|
59
62
|
{
|
|
60
63
|
inspection: "Uses",
|
|
61
64
|
binding: "square",
|
|
62
65
|
args: ["x"],
|
|
63
66
|
expected: true,
|
|
67
|
+
targetSuffix: "named",
|
|
64
68
|
},
|
|
65
69
|
{
|
|
66
70
|
inspection: "Uses",
|
|
67
71
|
binding: "squareList",
|
|
68
72
|
args: ["map"],
|
|
69
73
|
expected: true,
|
|
74
|
+
targetSuffix: "named",
|
|
70
75
|
},
|
|
71
76
|
{
|
|
72
77
|
inspection: "Uses",
|
|
73
78
|
binding: "squareList",
|
|
74
79
|
args: ["map"],
|
|
75
80
|
expected: false,
|
|
81
|
+
targetSuffix: "named",
|
|
76
82
|
},
|
|
77
83
|
]);
|
|
78
84
|
});
|