c-next 0.1.61 → 0.1.63
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/README.md +86 -63
- package/grammar/CNext.g4 +3 -17
- package/package.json +1 -1
- package/src/cli/serve/ServeCommand.ts +57 -45
- package/src/lib/__tests__/parseCHeader.mocked.test.ts +145 -0
- package/src/transpiler/Transpiler.ts +603 -613
- package/src/transpiler/__tests__/DualCodePaths.test.ts +5 -1
- package/src/transpiler/__tests__/Transpiler.coverage.test.ts +2 -99
- package/src/transpiler/__tests__/Transpiler.test.ts +3 -26
- package/src/transpiler/data/IncludeTreeWalker.ts +1 -1
- package/src/transpiler/logic/analysis/InitializationAnalyzer.ts +23 -52
- package/src/transpiler/logic/parser/grammar/CNext.interp +1 -3
- package/src/transpiler/logic/parser/grammar/CNextListener.ts +0 -22
- package/src/transpiler/logic/parser/grammar/CNextParser.ts +665 -1084
- package/src/transpiler/logic/parser/grammar/CNextVisitor.ts +0 -14
- package/src/transpiler/logic/symbols/CppSymbolCollector.ts +67 -43
- package/src/transpiler/logic/symbols/cnext/collectors/StructCollector.ts +156 -70
- package/src/transpiler/logic/symbols/cnext/collectors/VariableCollector.ts +31 -6
- package/src/transpiler/logic/symbols/cnext/utils/TypeUtils.ts +43 -11
- package/src/transpiler/output/codegen/CodeGenState.ts +811 -0
- package/src/transpiler/output/codegen/CodeGenerator.ts +1410 -2587
- package/src/transpiler/output/codegen/TypeResolver.ts +193 -149
- package/src/transpiler/output/codegen/TypeValidator.ts +148 -370
- package/src/transpiler/output/codegen/__tests__/CodeGenState.test.ts +446 -0
- package/src/transpiler/output/codegen/__tests__/CodeGenerator.test.ts +2082 -52
- package/src/transpiler/output/codegen/__tests__/TrackVariableTypeHelpers.test.ts +1 -1
- package/src/transpiler/output/codegen/__tests__/TypeResolver.test.ts +435 -196
- package/src/transpiler/output/codegen/__tests__/TypeValidator.resolution.test.ts +51 -67
- package/src/transpiler/output/codegen/__tests__/TypeValidator.test.ts +495 -471
- package/src/transpiler/output/codegen/analysis/MemberChainAnalyzer.ts +227 -66
- package/src/transpiler/output/codegen/analysis/StringLengthCounter.ts +55 -58
- package/src/transpiler/output/codegen/analysis/__tests__/MemberChainAnalyzer.test.ts +288 -275
- package/src/transpiler/output/codegen/analysis/__tests__/StringLengthCounter.test.ts +101 -144
- package/src/transpiler/output/codegen/assignment/AssignmentClassifier.ts +195 -133
- package/src/transpiler/output/codegen/assignment/AssignmentContextBuilder.ts +24 -74
- package/src/transpiler/output/codegen/assignment/AssignmentKind.ts +3 -0
- package/src/transpiler/output/codegen/assignment/IAssignmentContext.ts +3 -0
- package/src/transpiler/output/codegen/assignment/__tests__/AssignmentClassifier.test.ts +290 -320
- package/src/transpiler/output/codegen/assignment/handlers/BitAccessHandlers.ts +42 -0
- package/src/transpiler/output/codegen/assignment/handlers/__tests__/BitAccessHandlers.test.ts +76 -2
- package/src/transpiler/output/codegen/generators/GeneratorRegistry.ts +12 -0
- package/src/transpiler/output/codegen/generators/IOrchestrator.ts +5 -1
- package/src/transpiler/output/codegen/generators/__tests__/GeneratorRegistry.test.ts +28 -1
- package/src/transpiler/output/codegen/generators/declarationGenerators/ArrayDimensionUtils.ts +67 -0
- package/src/transpiler/output/codegen/generators/declarationGenerators/RegisterGenerator.ts +11 -24
- package/src/transpiler/output/codegen/generators/declarationGenerators/RegisterMacroGenerator.ts +64 -0
- package/src/transpiler/output/codegen/generators/declarationGenerators/ScopeGenerator.ts +137 -61
- package/src/transpiler/output/codegen/generators/declarationGenerators/ScopedRegisterGenerator.ts +18 -27
- package/src/transpiler/output/codegen/generators/declarationGenerators/StructGenerator.ts +100 -23
- package/src/transpiler/output/codegen/generators/declarationGenerators/__tests__/ArrayDimensionUtils.test.ts +125 -0
- package/src/transpiler/output/codegen/generators/declarationGenerators/__tests__/ScopeGenerator.test.ts +157 -4
- package/src/transpiler/output/codegen/generators/expressions/PostfixExpressionGenerator.ts +5 -1
- package/src/transpiler/output/codegen/generators/statements/ControlFlowGenerator.ts +1 -17
- package/src/transpiler/output/codegen/generators/support/HelperGenerator.ts +23 -22
- package/src/transpiler/output/codegen/helpers/ArrayAccessHelper.ts +129 -0
- package/src/transpiler/output/codegen/helpers/ArrayInitHelper.ts +54 -61
- package/src/transpiler/output/codegen/helpers/AssignmentExpectedTypeResolver.ts +40 -44
- package/src/transpiler/output/codegen/helpers/AssignmentTargetExtractor.ts +17 -45
- package/src/transpiler/output/codegen/helpers/AssignmentValidator.ts +83 -78
- package/src/transpiler/output/codegen/helpers/CppModeHelper.ts +22 -30
- package/src/transpiler/output/codegen/helpers/EnumAssignmentValidator.ts +108 -50
- package/src/transpiler/output/codegen/helpers/FloatBitHelper.ts +16 -31
- package/src/transpiler/output/codegen/helpers/MemberSeparatorResolver.ts +10 -3
- package/src/transpiler/output/codegen/helpers/StringDeclHelper.ts +103 -96
- package/src/transpiler/output/codegen/helpers/SymbolLookupHelper.ts +44 -0
- package/src/transpiler/output/codegen/helpers/TypeGenerationHelper.ts +9 -0
- package/src/transpiler/output/codegen/helpers/__tests__/ArrayAccessHelper.test.ts +479 -0
- package/src/transpiler/output/codegen/helpers/__tests__/ArrayInitHelper.test.ts +58 -103
- package/src/transpiler/output/codegen/helpers/__tests__/AssignmentExpectedTypeResolver.test.ts +97 -40
- package/src/transpiler/output/codegen/helpers/__tests__/AssignmentValidator.test.ts +223 -128
- package/src/transpiler/output/codegen/helpers/__tests__/CppModeHelper.test.ts +68 -41
- package/src/transpiler/output/codegen/helpers/__tests__/EnumAssignmentValidator.test.ts +198 -47
- package/src/transpiler/output/codegen/helpers/__tests__/FloatBitHelper.test.ts +39 -37
- package/src/transpiler/output/codegen/helpers/__tests__/MemberSeparatorResolver.test.ts +1 -0
- package/src/transpiler/output/codegen/helpers/__tests__/StringDeclHelper.test.ts +191 -453
- package/src/transpiler/output/codegen/helpers/__tests__/SymbolLookupHelper.test.ts +201 -0
- package/src/transpiler/output/codegen/helpers/__tests__/TypeGenerationHelper.test.ts +50 -0
- package/src/transpiler/output/codegen/resolution/EnumTypeResolver.ts +229 -0
- package/src/transpiler/output/codegen/resolution/ScopeResolver.ts +60 -0
- package/src/transpiler/output/codegen/resolution/SizeofResolver.ts +177 -0
- package/src/transpiler/output/codegen/resolution/__tests__/EnumTypeResolver.test.ts +336 -0
- package/src/transpiler/output/codegen/resolution/__tests__/SizeofResolver.test.ts +201 -0
- package/src/transpiler/output/codegen/types/IArrayAccessDeps.ts +23 -0
- package/src/transpiler/output/codegen/types/IArrayAccessInfo.ts +26 -0
- package/src/transpiler/output/codegen/types/IMemberSeparatorDeps.ts +7 -0
- package/src/transpiler/output/codegen/utils/CodegenParserUtils.ts +98 -0
- package/src/transpiler/output/codegen/utils/ExpressionUnwrapper.ts +22 -22
- package/src/transpiler/output/codegen/utils/__tests__/CodegenParserUtils.test.ts +228 -0
- package/src/transpiler/types/IFileResult.ts +0 -4
- package/src/transpiler/types/IPipelineFile.ts +27 -0
- package/src/transpiler/types/IPipelineInput.ts +23 -0
- package/src/transpiler/types/TranspilerState.ts +1 -1
- package/src/utils/FormatUtils.ts +28 -2
- package/src/utils/MapUtils.ts +25 -0
- package/src/utils/PostfixAnalysisUtils.ts +48 -0
- package/src/utils/__tests__/FormatUtils.test.ts +42 -0
- package/src/utils/__tests__/MapUtils.test.ts +85 -0
- package/src/utils/constants/OperatorMappings.ts +19 -0
- package/src/transpiler/logic/StandaloneContextBuilder.ts +0 -150
- package/src/transpiler/logic/__tests__/StandaloneContextBuilder.test.ts +0 -647
- package/src/transpiler/output/codegen/types/ITypeResolverDeps.ts +0 -23
- package/src/transpiler/output/codegen/types/ITypeValidatorDeps.ts +0 -53
- package/src/transpiler/types/ITranspileContext.ts +0 -49
- package/src/transpiler/types/ITranspileContribution.ts +0 -32
|
@@ -3,10 +3,10 @@
|
|
|
3
3
|
* Issue #644: strlen caching optimization
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import { describe, it, expect,
|
|
6
|
+
import { describe, it, expect, beforeEach } from "vitest";
|
|
7
7
|
import StringLengthCounter from "../StringLengthCounter";
|
|
8
8
|
import CNextSourceParser from "../../../../logic/parser/CNextSourceParser";
|
|
9
|
-
import
|
|
9
|
+
import CodeGenState from "../../CodeGenState";
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
12
|
* Parse a C-Next expression and return the expression context.
|
|
@@ -32,122 +32,102 @@ function parseBlock(statements: string) {
|
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
describe("StringLengthCounter", () => {
|
|
35
|
+
beforeEach(() => {
|
|
36
|
+
CodeGenState.reset();
|
|
37
|
+
});
|
|
38
|
+
|
|
35
39
|
describe("countExpression", () => {
|
|
36
40
|
it("counts single .length access on string variable", () => {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
isString: true,
|
|
45
|
-
stringCapacity: 64,
|
|
46
|
-
};
|
|
47
|
-
}
|
|
48
|
-
return undefined;
|
|
41
|
+
CodeGenState.typeRegistry.set("myStr", {
|
|
42
|
+
baseType: "char",
|
|
43
|
+
bitWidth: 8,
|
|
44
|
+
isArray: false,
|
|
45
|
+
isConst: false,
|
|
46
|
+
isString: true,
|
|
47
|
+
stringCapacity: 64,
|
|
49
48
|
});
|
|
50
49
|
|
|
51
|
-
const counter = new StringLengthCounter(typeRegistry);
|
|
52
50
|
const expr = parseExpression("myStr.length");
|
|
53
|
-
const counts =
|
|
51
|
+
const counts = StringLengthCounter.countExpression(expr);
|
|
54
52
|
|
|
55
53
|
expect(counts.get("myStr")).toBe(1);
|
|
56
54
|
});
|
|
57
55
|
|
|
58
56
|
it("counts multiple .length accesses on same variable", () => {
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
isString: true,
|
|
67
|
-
stringCapacity: 32,
|
|
68
|
-
};
|
|
69
|
-
}
|
|
70
|
-
return undefined;
|
|
57
|
+
CodeGenState.typeRegistry.set("str", {
|
|
58
|
+
baseType: "char",
|
|
59
|
+
bitWidth: 8,
|
|
60
|
+
isArray: false,
|
|
61
|
+
isConst: false,
|
|
62
|
+
isString: true,
|
|
63
|
+
stringCapacity: 32,
|
|
71
64
|
});
|
|
72
65
|
|
|
73
|
-
const counter = new StringLengthCounter(typeRegistry);
|
|
74
66
|
// Expression: str.length + str.length
|
|
75
67
|
const expr = parseExpression("str.length + str.length");
|
|
76
|
-
const counts =
|
|
68
|
+
const counts = StringLengthCounter.countExpression(expr);
|
|
77
69
|
|
|
78
70
|
expect(counts.get("str")).toBe(2);
|
|
79
71
|
});
|
|
80
72
|
|
|
81
73
|
it("counts .length accesses on different string variables", () => {
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
74
|
+
CodeGenState.typeRegistry.set("a", {
|
|
75
|
+
baseType: "char",
|
|
76
|
+
bitWidth: 8,
|
|
77
|
+
isArray: false,
|
|
78
|
+
isConst: false,
|
|
79
|
+
isString: true,
|
|
80
|
+
stringCapacity: 16,
|
|
81
|
+
});
|
|
82
|
+
CodeGenState.typeRegistry.set("b", {
|
|
83
|
+
baseType: "char",
|
|
84
|
+
bitWidth: 8,
|
|
85
|
+
isArray: false,
|
|
86
|
+
isConst: false,
|
|
87
|
+
isString: true,
|
|
88
|
+
stringCapacity: 16,
|
|
94
89
|
});
|
|
95
90
|
|
|
96
|
-
const counter = new StringLengthCounter(typeRegistry);
|
|
97
91
|
const expr = parseExpression("a.length + b.length");
|
|
98
|
-
const counts =
|
|
92
|
+
const counts = StringLengthCounter.countExpression(expr);
|
|
99
93
|
|
|
100
94
|
expect(counts.get("a")).toBe(1);
|
|
101
95
|
expect(counts.get("b")).toBe(1);
|
|
102
96
|
});
|
|
103
97
|
|
|
104
98
|
it("ignores .length on non-string variables", () => {
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
isConst: false,
|
|
112
|
-
arrayDimensions: [10],
|
|
113
|
-
};
|
|
114
|
-
}
|
|
115
|
-
return undefined;
|
|
99
|
+
CodeGenState.typeRegistry.set("arr", {
|
|
100
|
+
baseType: "u8",
|
|
101
|
+
bitWidth: 8,
|
|
102
|
+
isArray: true,
|
|
103
|
+
isConst: false,
|
|
104
|
+
arrayDimensions: [10],
|
|
116
105
|
});
|
|
117
106
|
|
|
118
|
-
const counter = new StringLengthCounter(typeRegistry);
|
|
119
107
|
const expr = parseExpression("arr.length");
|
|
120
|
-
const counts =
|
|
108
|
+
const counts = StringLengthCounter.countExpression(expr);
|
|
121
109
|
|
|
122
110
|
expect(counts.get("arr")).toBeUndefined();
|
|
123
111
|
});
|
|
124
112
|
|
|
125
113
|
it("ignores other member accesses", () => {
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
isArray: false,
|
|
132
|
-
isConst: false,
|
|
133
|
-
};
|
|
134
|
-
}
|
|
135
|
-
return undefined;
|
|
114
|
+
CodeGenState.typeRegistry.set("obj", {
|
|
115
|
+
baseType: "MyStruct",
|
|
116
|
+
bitWidth: 32,
|
|
117
|
+
isArray: false,
|
|
118
|
+
isConst: false,
|
|
136
119
|
});
|
|
137
120
|
|
|
138
|
-
const counter = new StringLengthCounter(typeRegistry);
|
|
139
121
|
const expr = parseExpression("obj.value");
|
|
140
|
-
const counts =
|
|
122
|
+
const counts = StringLengthCounter.countExpression(expr);
|
|
141
123
|
|
|
142
124
|
expect(counts.size).toBe(0);
|
|
143
125
|
});
|
|
144
126
|
|
|
145
127
|
it("handles unknown variables gracefully", () => {
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
const counter = new StringLengthCounter(typeRegistry);
|
|
128
|
+
// No type registered for "unknown"
|
|
149
129
|
const expr = parseExpression("unknown.length");
|
|
150
|
-
const counts =
|
|
130
|
+
const counts = StringLengthCounter.countExpression(expr);
|
|
151
131
|
|
|
152
132
|
expect(counts.size).toBe(0);
|
|
153
133
|
});
|
|
@@ -155,51 +135,39 @@ describe("StringLengthCounter", () => {
|
|
|
155
135
|
|
|
156
136
|
describe("countBlock", () => {
|
|
157
137
|
it("counts .length accesses across multiple statements", () => {
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
isString: true,
|
|
166
|
-
stringCapacity: 128,
|
|
167
|
-
};
|
|
168
|
-
}
|
|
169
|
-
return undefined;
|
|
138
|
+
CodeGenState.typeRegistry.set("msg", {
|
|
139
|
+
baseType: "char",
|
|
140
|
+
bitWidth: 8,
|
|
141
|
+
isArray: false,
|
|
142
|
+
isConst: false,
|
|
143
|
+
isString: true,
|
|
144
|
+
stringCapacity: 128,
|
|
170
145
|
});
|
|
171
146
|
|
|
172
|
-
const counter = new StringLengthCounter(typeRegistry);
|
|
173
147
|
const block = parseBlock(`
|
|
174
148
|
u32 len <- msg.length;
|
|
175
149
|
u32 doubled <- msg.length * 2;
|
|
176
150
|
`);
|
|
177
|
-
const counts =
|
|
151
|
+
const counts = StringLengthCounter.countBlock(block);
|
|
178
152
|
|
|
179
153
|
expect(counts.get("msg")).toBe(2);
|
|
180
154
|
});
|
|
181
155
|
|
|
182
156
|
it("counts .length in assignment statements", () => {
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
isString: true,
|
|
191
|
-
stringCapacity: 64,
|
|
192
|
-
};
|
|
193
|
-
}
|
|
194
|
-
return undefined;
|
|
157
|
+
CodeGenState.typeRegistry.set("text", {
|
|
158
|
+
baseType: "char",
|
|
159
|
+
bitWidth: 8,
|
|
160
|
+
isArray: false,
|
|
161
|
+
isConst: false,
|
|
162
|
+
isString: true,
|
|
163
|
+
stringCapacity: 64,
|
|
195
164
|
});
|
|
196
165
|
|
|
197
|
-
const counter = new StringLengthCounter(typeRegistry);
|
|
198
166
|
const block = parseBlock(`
|
|
199
167
|
u32 x;
|
|
200
168
|
x <- text.length;
|
|
201
169
|
`);
|
|
202
|
-
const counts =
|
|
170
|
+
const counts = StringLengthCounter.countBlock(block);
|
|
203
171
|
|
|
204
172
|
expect(counts.get("text")).toBe(1);
|
|
205
173
|
});
|
|
@@ -207,21 +175,22 @@ describe("StringLengthCounter", () => {
|
|
|
207
175
|
|
|
208
176
|
describe("countBlockInto", () => {
|
|
209
177
|
it("adds counts to existing map", () => {
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
178
|
+
CodeGenState.typeRegistry.set("s1", {
|
|
179
|
+
baseType: "char",
|
|
180
|
+
bitWidth: 8,
|
|
181
|
+
isArray: false,
|
|
182
|
+
isConst: false,
|
|
183
|
+
isString: true,
|
|
184
|
+
stringCapacity: 32,
|
|
185
|
+
});
|
|
186
|
+
CodeGenState.typeRegistry.set("s2", {
|
|
187
|
+
baseType: "char",
|
|
188
|
+
bitWidth: 8,
|
|
189
|
+
isArray: false,
|
|
190
|
+
isConst: false,
|
|
191
|
+
isString: true,
|
|
192
|
+
stringCapacity: 32,
|
|
222
193
|
});
|
|
223
|
-
|
|
224
|
-
const counter = new StringLengthCounter(typeRegistry);
|
|
225
194
|
|
|
226
195
|
// Pre-populate counts
|
|
227
196
|
const counts = new Map<string, number>();
|
|
@@ -231,7 +200,7 @@ describe("StringLengthCounter", () => {
|
|
|
231
200
|
u32 a <- s1.length;
|
|
232
201
|
u32 b <- s2.length;
|
|
233
202
|
`);
|
|
234
|
-
|
|
203
|
+
StringLengthCounter.countBlockInto(block, counts);
|
|
235
204
|
|
|
236
205
|
expect(counts.get("s1")).toBe(2); // 1 existing + 1 new
|
|
237
206
|
expect(counts.get("s2")).toBe(1);
|
|
@@ -240,45 +209,33 @@ describe("StringLengthCounter", () => {
|
|
|
240
209
|
|
|
241
210
|
describe("nested expressions", () => {
|
|
242
211
|
it("counts .length in ternary expressions", () => {
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
isString: true,
|
|
251
|
-
stringCapacity: 64,
|
|
252
|
-
};
|
|
253
|
-
}
|
|
254
|
-
return undefined;
|
|
212
|
+
CodeGenState.typeRegistry.set("str", {
|
|
213
|
+
baseType: "char",
|
|
214
|
+
bitWidth: 8,
|
|
215
|
+
isArray: false,
|
|
216
|
+
isConst: false,
|
|
217
|
+
isString: true,
|
|
218
|
+
stringCapacity: 64,
|
|
255
219
|
});
|
|
256
220
|
|
|
257
|
-
const counter = new StringLengthCounter(typeRegistry);
|
|
258
221
|
const expr = parseExpression("(str.length > 0) ? str.length : 0");
|
|
259
|
-
const counts =
|
|
222
|
+
const counts = StringLengthCounter.countExpression(expr);
|
|
260
223
|
|
|
261
224
|
expect(counts.get("str")).toBe(2);
|
|
262
225
|
});
|
|
263
226
|
|
|
264
227
|
it("counts .length in comparison expressions", () => {
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
isString: true,
|
|
273
|
-
stringCapacity: 50,
|
|
274
|
-
};
|
|
275
|
-
}
|
|
276
|
-
return undefined;
|
|
228
|
+
CodeGenState.typeRegistry.set("name", {
|
|
229
|
+
baseType: "char",
|
|
230
|
+
bitWidth: 8,
|
|
231
|
+
isArray: false,
|
|
232
|
+
isConst: false,
|
|
233
|
+
isString: true,
|
|
234
|
+
stringCapacity: 50,
|
|
277
235
|
});
|
|
278
236
|
|
|
279
|
-
const counter = new StringLengthCounter(typeRegistry);
|
|
280
237
|
const expr = parseExpression("name.length = 10");
|
|
281
|
-
const counts =
|
|
238
|
+
const counts = StringLengthCounter.countExpression(expr);
|
|
282
239
|
|
|
283
240
|
expect(counts.get("name")).toBe(1);
|
|
284
241
|
});
|