c-next 0.2.16 → 0.2.17

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 (56) hide show
  1. package/README.md +16 -0
  2. package/dist/index.js +1347 -414
  3. package/dist/index.js.map +3 -3
  4. package/grammar/CNext.g4 +4 -0
  5. package/package.json +5 -1
  6. package/src/transpiler/Transpiler.ts +90 -22
  7. package/src/transpiler/__tests__/DualCodePaths.test.ts +1 -1
  8. package/src/transpiler/logic/analysis/FunctionCallAnalyzer.ts +57 -10
  9. package/src/transpiler/logic/analysis/InitializationAnalyzer.ts +186 -14
  10. package/src/transpiler/logic/analysis/SignedShiftAnalyzer.ts +124 -12
  11. package/src/transpiler/logic/analysis/__tests__/FunctionCallAnalyzer.test.ts +200 -0
  12. package/src/transpiler/logic/analysis/__tests__/InitializationAnalyzer.test.ts +386 -1
  13. package/src/transpiler/logic/analysis/__tests__/SignedShiftAnalyzer.test.ts +211 -0
  14. package/src/transpiler/logic/parser/grammar/CNext.interp +1 -1
  15. package/src/transpiler/logic/parser/grammar/CNextParser.ts +154 -86
  16. package/src/transpiler/logic/symbols/SymbolTable.ts +17 -2
  17. package/src/transpiler/logic/symbols/__tests__/SymbolTable.test.ts +6 -4
  18. package/src/transpiler/logic/symbols/cnext/collectors/VariableCollector.ts +15 -2
  19. package/src/transpiler/logic/symbols/cnext/utils/TypeUtils.ts +64 -50
  20. package/src/transpiler/output/codegen/CodeGenerator.ts +151 -94
  21. package/src/transpiler/output/codegen/__tests__/CodeGenerator.coverage.test.ts +165 -17
  22. package/src/transpiler/output/codegen/__tests__/CodeGenerator.test.ts +150 -34
  23. package/src/transpiler/output/codegen/__tests__/TrackVariableTypeHelpers.test.ts +2 -2
  24. package/src/transpiler/output/codegen/__tests__/TypeValidator.test.ts +11 -0
  25. package/src/transpiler/output/codegen/generators/declarationGenerators/ScopeGenerator.ts +26 -7
  26. package/src/transpiler/output/codegen/generators/declarationGenerators/__tests__/ScopeGenerator.test.ts +86 -0
  27. package/src/transpiler/output/codegen/generators/expressions/BinaryExprGenerator.ts +43 -24
  28. package/src/transpiler/output/codegen/generators/expressions/CallExprGenerator.ts +48 -43
  29. package/src/transpiler/output/codegen/generators/expressions/ExpressionGenerator.ts +9 -2
  30. package/src/transpiler/output/codegen/generators/expressions/__tests__/CallExprGenerator.test.ts +44 -0
  31. package/src/transpiler/output/codegen/generators/expressions/__tests__/ExpressionGenerator.test.ts +82 -1
  32. package/src/transpiler/output/codegen/helpers/ParameterInputAdapter.ts +17 -3
  33. package/src/transpiler/output/codegen/helpers/ParameterSignatureBuilder.ts +17 -4
  34. package/src/transpiler/output/codegen/helpers/StringDeclHelper.ts +227 -32
  35. package/src/transpiler/output/codegen/helpers/SymbolLookupHelper.ts +0 -21
  36. package/src/transpiler/output/codegen/helpers/TypeGenerationHelper.ts +60 -39
  37. package/src/transpiler/output/codegen/helpers/TypeRegistrationEngine.ts +170 -36
  38. package/src/transpiler/output/codegen/helpers/VariableDeclHelper.ts +37 -39
  39. package/src/transpiler/output/codegen/helpers/__tests__/ParameterInputAdapter.test.ts +117 -0
  40. package/src/transpiler/output/codegen/helpers/__tests__/ParameterSignatureBuilder.test.ts +94 -2
  41. package/src/transpiler/output/codegen/helpers/__tests__/StringDeclHelper.test.ts +268 -1
  42. package/src/transpiler/output/codegen/helpers/__tests__/SymbolLookupHelper.test.ts +0 -64
  43. package/src/transpiler/output/codegen/helpers/__tests__/TypeRegistrationEngine.test.ts +101 -0
  44. package/src/transpiler/output/codegen/helpers/__tests__/VariableDeclHelper.test.ts +29 -5
  45. package/src/transpiler/output/codegen/types/ICallbackTypeInfo.ts +2 -1
  46. package/src/transpiler/output/codegen/types/IParameterInput.ts +7 -0
  47. package/src/transpiler/output/headers/BaseHeaderGenerator.ts +8 -0
  48. package/src/transpiler/output/headers/HeaderGeneratorUtils.ts +75 -0
  49. package/src/transpiler/output/headers/__tests__/HeaderGeneratorUtils.test.ts +280 -0
  50. package/src/transpiler/output/headers/generators/IHeaderTypeInput.ts +13 -0
  51. package/src/transpiler/output/headers/generators/generateStructHeader.ts +48 -28
  52. package/src/transpiler/state/CodeGenState.ts +71 -6
  53. package/src/transpiler/state/__tests__/CodeGenState.test.ts +253 -11
  54. package/src/utils/LiteralUtils.ts +23 -0
  55. package/src/utils/__tests__/LiteralUtils.test.ts +101 -0
  56. package/src/utils/types/IParameterSymbol.ts +1 -0
@@ -804,4 +804,284 @@ describe("HeaderGeneratorUtils", () => {
804
804
  expect(lines).toContain("#endif /* MY_FILE_H */");
805
805
  });
806
806
  });
807
+
808
+ describe("generateCallbackStructForwardDecls", () => {
809
+ it("returns empty array when no callback types provided", () => {
810
+ const result = HeaderGeneratorUtils.generateCallbackStructForwardDecls(
811
+ [],
812
+ );
813
+ expect(result).toEqual([]);
814
+ });
815
+
816
+ it("returns empty array when callback types is undefined", () => {
817
+ const input = {
818
+ structFields: new Map(),
819
+ structFieldDimensions: new Map(),
820
+ enumMembers: new Map(),
821
+ bitmapBackingType: new Map(),
822
+ bitmapFields: new Map(),
823
+ callbackTypes: undefined,
824
+ };
825
+ const result = HeaderGeneratorUtils.generateCallbackStructForwardDecls(
826
+ [],
827
+ input,
828
+ );
829
+ expect(result).toEqual([]);
830
+ });
831
+
832
+ it("generates forward declarations for struct parameters", () => {
833
+ const structs = [makeSymbol({ name: "DataStruct", kind: "struct" })];
834
+ const input = {
835
+ structFields: new Map(),
836
+ structFieldDimensions: new Map(),
837
+ enumMembers: new Map(),
838
+ bitmapBackingType: new Map(),
839
+ bitmapFields: new Map(),
840
+ callbackTypes: new Map([
841
+ [
842
+ "processData",
843
+ {
844
+ typedefName: "processData_t",
845
+ returnType: "void",
846
+ parameters: [
847
+ { type: "DataStruct", isStruct: true },
848
+ { type: "uint32_t", isStruct: false },
849
+ ],
850
+ },
851
+ ],
852
+ ]),
853
+ };
854
+ const result = HeaderGeneratorUtils.generateCallbackStructForwardDecls(
855
+ structs,
856
+ input,
857
+ );
858
+ expect(result).toContain("typedef struct DataStruct DataStruct;");
859
+ });
860
+
861
+ it("deduplicates struct forward declarations", () => {
862
+ const structs = [makeSymbol({ name: "MyStruct", kind: "struct" })];
863
+ const input = {
864
+ structFields: new Map(),
865
+ structFieldDimensions: new Map(),
866
+ enumMembers: new Map(),
867
+ bitmapBackingType: new Map(),
868
+ bitmapFields: new Map(),
869
+ callbackTypes: new Map([
870
+ [
871
+ "handler1",
872
+ {
873
+ typedefName: "handler1_t",
874
+ returnType: "void",
875
+ parameters: [{ type: "MyStruct", isStruct: true }],
876
+ },
877
+ ],
878
+ [
879
+ "handler2",
880
+ {
881
+ typedefName: "handler2_t",
882
+ returnType: "void",
883
+ parameters: [{ type: "MyStruct", isStruct: true }],
884
+ },
885
+ ],
886
+ ]),
887
+ };
888
+ const result = HeaderGeneratorUtils.generateCallbackStructForwardDecls(
889
+ structs,
890
+ input,
891
+ );
892
+ const myStructDecls = result.filter((l) => l.includes("MyStruct"));
893
+ expect(myStructDecls.length).toBe(1);
894
+ });
895
+
896
+ it("ignores non-struct parameters", () => {
897
+ const input = {
898
+ structFields: new Map(),
899
+ structFieldDimensions: new Map(),
900
+ enumMembers: new Map(),
901
+ bitmapBackingType: new Map(),
902
+ bitmapFields: new Map(),
903
+ callbackTypes: new Map([
904
+ [
905
+ "handler",
906
+ {
907
+ typedefName: "handler_t",
908
+ returnType: "uint32_t",
909
+ parameters: [
910
+ { type: "uint32_t", isStruct: false },
911
+ { type: "bool", isStruct: false },
912
+ ],
913
+ },
914
+ ],
915
+ ]),
916
+ };
917
+ const result = HeaderGeneratorUtils.generateCallbackStructForwardDecls(
918
+ [],
919
+ input,
920
+ );
921
+ expect(result).toEqual([]);
922
+ });
923
+
924
+ it("only includes local structs in forward declarations", () => {
925
+ // ExternalStruct is not in the local structs list
926
+ const structs = [makeSymbol({ name: "LocalStruct", kind: "struct" })];
927
+ const input = {
928
+ structFields: new Map(),
929
+ structFieldDimensions: new Map(),
930
+ enumMembers: new Map(),
931
+ bitmapBackingType: new Map(),
932
+ bitmapFields: new Map(),
933
+ callbackTypes: new Map([
934
+ [
935
+ "handler",
936
+ {
937
+ typedefName: "handler_t",
938
+ returnType: "void",
939
+ parameters: [
940
+ { type: "LocalStruct", isStruct: true },
941
+ { type: "ExternalStruct", isStruct: true },
942
+ ],
943
+ },
944
+ ],
945
+ ]),
946
+ };
947
+ const result = HeaderGeneratorUtils.generateCallbackStructForwardDecls(
948
+ structs,
949
+ input,
950
+ );
951
+ expect(result).toContain("typedef struct LocalStruct LocalStruct;");
952
+ expect(result).not.toContain("ExternalStruct");
953
+ });
954
+ });
955
+
956
+ describe("generateCallbackTypedefSection", () => {
957
+ it("returns empty array when no callback types provided", () => {
958
+ const result = HeaderGeneratorUtils.generateCallbackTypedefSection();
959
+ expect(result).toEqual([]);
960
+ });
961
+
962
+ it("returns empty array when callback types is undefined", () => {
963
+ const input = {
964
+ structFields: new Map(),
965
+ structFieldDimensions: new Map(),
966
+ enumMembers: new Map(),
967
+ bitmapBackingType: new Map(),
968
+ bitmapFields: new Map(),
969
+ callbackTypes: undefined,
970
+ };
971
+ const result = HeaderGeneratorUtils.generateCallbackTypedefSection(
972
+ input,
973
+ false,
974
+ );
975
+ expect(result).toEqual([]);
976
+ });
977
+
978
+ it("generates C-style function pointer typedef", () => {
979
+ const input = {
980
+ structFields: new Map(),
981
+ structFieldDimensions: new Map(),
982
+ enumMembers: new Map(),
983
+ bitmapBackingType: new Map(),
984
+ bitmapFields: new Map(),
985
+ callbackTypes: new Map([
986
+ [
987
+ "processU32",
988
+ {
989
+ typedefName: "processU32_t",
990
+ returnType: "uint32_t",
991
+ parameters: [{ type: "uint32_t", isStruct: false }],
992
+ },
993
+ ],
994
+ ]),
995
+ };
996
+ const result = HeaderGeneratorUtils.generateCallbackTypedefSection(
997
+ input,
998
+ false,
999
+ );
1000
+ expect(result.join("\n")).toContain(
1001
+ "typedef uint32_t (*processU32_t)(uint32_t);",
1002
+ );
1003
+ });
1004
+
1005
+ it("generates C++ reference for struct parameters", () => {
1006
+ const input = {
1007
+ structFields: new Map(),
1008
+ structFieldDimensions: new Map(),
1009
+ enumMembers: new Map(),
1010
+ bitmapBackingType: new Map(),
1011
+ bitmapFields: new Map(),
1012
+ callbackTypes: new Map([
1013
+ [
1014
+ "processPoint",
1015
+ {
1016
+ typedefName: "processPoint_t",
1017
+ returnType: "uint32_t",
1018
+ parameters: [{ type: "Point", isStruct: true }],
1019
+ },
1020
+ ],
1021
+ ]),
1022
+ };
1023
+ const result = HeaderGeneratorUtils.generateCallbackTypedefSection(
1024
+ input,
1025
+ true,
1026
+ );
1027
+ expect(result.join("\n")).toContain("Point&");
1028
+ });
1029
+
1030
+ it("generates C pointer for struct parameters", () => {
1031
+ const input = {
1032
+ structFields: new Map(),
1033
+ structFieldDimensions: new Map(),
1034
+ enumMembers: new Map(),
1035
+ bitmapBackingType: new Map(),
1036
+ bitmapFields: new Map(),
1037
+ callbackTypes: new Map([
1038
+ [
1039
+ "processPoint",
1040
+ {
1041
+ typedefName: "processPoint_t",
1042
+ returnType: "uint32_t",
1043
+ parameters: [{ type: "Point", isStruct: true }],
1044
+ },
1045
+ ],
1046
+ ]),
1047
+ };
1048
+ const result = HeaderGeneratorUtils.generateCallbackTypedefSection(
1049
+ input,
1050
+ false,
1051
+ );
1052
+ expect(result.join("\n")).toContain("Point*");
1053
+ });
1054
+
1055
+ it("handles multiple parameters", () => {
1056
+ const input = {
1057
+ structFields: new Map(),
1058
+ structFieldDimensions: new Map(),
1059
+ enumMembers: new Map(),
1060
+ bitmapBackingType: new Map(),
1061
+ bitmapFields: new Map(),
1062
+ callbackTypes: new Map([
1063
+ [
1064
+ "multiParam",
1065
+ {
1066
+ typedefName: "multiParam_t",
1067
+ returnType: "void",
1068
+ parameters: [
1069
+ { type: "uint32_t", isStruct: false },
1070
+ { type: "Point", isStruct: true },
1071
+ { type: "bool", isStruct: false },
1072
+ ],
1073
+ },
1074
+ ],
1075
+ ]),
1076
+ };
1077
+ const result = HeaderGeneratorUtils.generateCallbackTypedefSection(
1078
+ input,
1079
+ false,
1080
+ );
1081
+ const typedef = result.find((l) => l.includes("multiParam_t"));
1082
+ expect(typedef).toContain("uint32_t");
1083
+ expect(typedef).toContain("Point*");
1084
+ expect(typedef).toContain("bool");
1085
+ });
1086
+ });
807
1087
  });
@@ -31,6 +31,19 @@ interface IHeaderTypeInput {
31
31
  string,
32
32
  ReadonlyMap<string, { readonly offset: number; readonly width: number }>
33
33
  >;
34
+
35
+ /** Callback types: functionName -> typedef info for header generation */
36
+ readonly callbackTypes?: ReadonlyMap<
37
+ string,
38
+ {
39
+ readonly typedefName: string;
40
+ readonly returnType: string;
41
+ readonly parameters: ReadonlyArray<{
42
+ readonly type: string;
43
+ readonly isStruct: boolean;
44
+ }>;
45
+ }
46
+ >;
34
47
  }
35
48
 
36
49
  export default IHeaderTypeInput;
@@ -11,6 +11,52 @@ import CppNamespaceUtils from "../../../../utils/CppNamespaceUtils";
11
11
 
12
12
  const { mapType } = typeUtils;
13
13
 
14
+ /**
15
+ * Resolve the C type for a struct field, checking for callback types first.
16
+ */
17
+ function resolveFieldCType(fieldType: string, input: IHeaderTypeInput): string {
18
+ // ADR-029: Check if field type is a callback type and use typedef name
19
+ const callbackInfo = input.callbackTypes?.get(fieldType);
20
+ if (callbackInfo) {
21
+ return callbackInfo.typedefName;
22
+ }
23
+ // Issue #502/#522: Convert C++ namespace types from _ to :: format
24
+ const convertedType = CppNamespaceUtils.convertToCppNamespace(
25
+ fieldType,
26
+ input.symbolTable,
27
+ );
28
+ return mapType(convertedType);
29
+ }
30
+
31
+ /**
32
+ * Generate the field line for a struct member, handling embedded dimensions.
33
+ *
34
+ * Issue #461: Handle string<N> types which map to char[N+1]
35
+ * The embedded dimension must come after array dimensions in C syntax.
36
+ * Example: string<64> arr[4] -> char arr[4][65], not char[65] arr[4]
37
+ */
38
+ function generateFieldLine(
39
+ fieldName: string,
40
+ cType: string,
41
+ dims: readonly number[] | undefined,
42
+ ): string {
43
+ const dimSuffix =
44
+ dims && dims.length > 0 ? dims.map((d) => `[${d}]`).join("") : "";
45
+ const embeddedMatch = /^(\w+)\[(\d+)\]$/.exec(cType);
46
+
47
+ if (!embeddedMatch) {
48
+ return ` ${cType} ${fieldName}${dimSuffix};`;
49
+ }
50
+
51
+ const baseType = embeddedMatch[1];
52
+ const embeddedDim = embeddedMatch[2];
53
+ // When dims are provided, they already include string capacity from StructCollector
54
+ if (dims && dims.length > 0) {
55
+ return ` ${baseType} ${fieldName}${dimSuffix};`;
56
+ }
57
+ return ` ${baseType} ${fieldName}[${embeddedDim}];`;
58
+ }
59
+
14
60
  /**
15
61
  * Generate a C typedef struct declaration for the given struct name.
16
62
  *
@@ -41,35 +87,9 @@ function generateStructHeader(name: string, input: IHeaderTypeInput): string {
41
87
 
42
88
  // Iterate fields in insertion order (Map preserves order)
43
89
  for (const [fieldName, fieldType] of fields) {
44
- // Issue #502/#522: Convert C++ namespace types from _ to :: format using shared utility
45
- const convertedType = CppNamespaceUtils.convertToCppNamespace(
46
- fieldType,
47
- input.symbolTable,
48
- );
49
- const cType = mapType(convertedType);
90
+ const cType = resolveFieldCType(fieldType, input);
50
91
  const dims = dimensions?.get(fieldName);
51
- const dimSuffix =
52
- dims && dims.length > 0 ? dims.map((d) => `[${d}]`).join("") : "";
53
-
54
- // Issue #461: Handle string<N> types which map to char[N+1]
55
- // The embedded dimension must come after array dimensions in C syntax
56
- // Example: string<64> arr[4] -> char arr[4][65], not char[65] arr[4]
57
- //
58
- // Fix: When dims already include the string capacity (from StructCollector),
59
- // use dimSuffix directly. Only extract embedded dim when no dims provided.
60
- const embeddedMatch = /^(\w+)\[(\d+)\]$/.exec(cType);
61
- if (embeddedMatch) {
62
- const baseType = embeddedMatch[1];
63
- const embeddedDim = embeddedMatch[2];
64
- // dims already includes string capacity, so just use dimSuffix
65
- if (dims && dims.length > 0) {
66
- lines.push(` ${baseType} ${fieldName}${dimSuffix};`);
67
- } else {
68
- lines.push(` ${baseType} ${fieldName}[${embeddedDim}];`);
69
- }
70
- } else {
71
- lines.push(` ${cType} ${fieldName}${dimSuffix};`);
72
- }
92
+ lines.push(generateFieldLine(fieldName, cType, dims));
73
93
  }
74
94
 
75
95
  lines.push(`} ${name};`);
@@ -217,6 +217,12 @@ export default class CodeGenState {
217
217
  /** Whether we're inside a function body */
218
218
  static inFunctionBody: boolean = false;
219
219
 
220
+ /** Whether we're generating the RHS of a variable declaration initializer.
221
+ * When true, struct literals use { .field = value } instead of (Type){ .field = value }
222
+ * because plain designated initializers are valid C99 at any scope, while compound
223
+ * literals are not constant expressions and fail at file scope on GCC < 13. */
224
+ static inDeclarationInit: boolean = false;
225
+
220
226
  /** Expected type for struct initializers and enum inference */
221
227
  static expectedType: string | null = null;
222
228
 
@@ -381,6 +387,7 @@ export default class CodeGenState {
381
387
  // Generation state
382
388
  this.indentLevel = 0;
383
389
  this.inFunctionBody = false;
390
+ this.inDeclarationInit = false;
384
391
  this.expectedType = null;
385
392
  this.suppressBareEnumResolution = false;
386
393
  this.mainArgsName = null;
@@ -476,6 +483,49 @@ export default class CodeGenState {
476
483
  }
477
484
  }
478
485
 
486
+ /** Execute fn with inDeclarationInit=true, restoring prior value on exit. */
487
+ static withDeclarationInit<T>(fn: () => T): T {
488
+ const saved = this.inDeclarationInit;
489
+ this.inDeclarationInit = true;
490
+ try {
491
+ return fn();
492
+ } finally {
493
+ this.inDeclarationInit = saved;
494
+ }
495
+ }
496
+
497
+ /** Execute fn with inDeclarationInit=false, restoring prior value on exit.
498
+ * Used in sub-expression contexts (function args, ternary arms) where
499
+ * plain designated initializers are not valid C. */
500
+ static withoutDeclarationInit<T>(fn: () => T): T {
501
+ const saved = this.inDeclarationInit;
502
+ this.inDeclarationInit = false;
503
+ try {
504
+ return fn();
505
+ } finally {
506
+ this.inDeclarationInit = saved;
507
+ }
508
+ }
509
+
510
+ /**
511
+ * Execute fn with expectedType=null, restoring prior value on exit.
512
+ * Issue #1032: Used in comparison contexts (relational/equality expressions)
513
+ * where MISRA 7.2 U suffix should NOT be applied - comparing `i32 < 0`
514
+ * should not generate `signedIdx < 0U` which changes comparison semantics.
515
+ */
516
+ static withoutExpectedType<T>(fn: () => T): T {
517
+ const savedType = this.expectedType;
518
+ const savedSuppress = this.suppressBareEnumResolution;
519
+ this.expectedType = null;
520
+ this.suppressBareEnumResolution = false;
521
+ try {
522
+ return fn();
523
+ } finally {
524
+ this.expectedType = savedType;
525
+ this.suppressBareEnumResolution = savedSuppress;
526
+ }
527
+ }
528
+
479
529
  // ===========================================================================
480
530
  // CONVENIENCE LOOKUP METHODS
481
531
  // ===========================================================================
@@ -1136,14 +1186,29 @@ export default class CodeGenState {
1136
1186
  }
1137
1187
 
1138
1188
  /**
1139
- * Check if a scope variable has an opaque type (and is thus a pointer).
1140
- * Used during access generation to determine if & prefix is needed.
1189
+ * Check if generated code accesses an opaque scope variable (and is thus
1190
+ * already a pointer). Used during argument generation to decide whether an
1191
+ * address-of (&) prefix is needed.
1141
1192
  *
1142
- * @param qualifiedName - The fully qualified variable name (e.g., "MyScope_widget")
1143
- * @returns true if this is an opaque scope variable (already a pointer)
1193
+ * Handles two forms:
1194
+ * - Direct access: "MyScope_widget" → the handle itself (pointer)
1195
+ * - Array-element access: "MyScope_widgets[i]" → an element of an opaque
1196
+ * handle array, which is itself a pointer (Issue #996)
1197
+ *
1198
+ * @param generatedCode - The generated access expression (e.g. "UI_widgets[i]")
1199
+ * @returns true if this resolves to an opaque scope variable (already a pointer)
1144
1200
  */
1145
- static isOpaqueScopeVariable(qualifiedName: string): boolean {
1146
- return this.opaqueScopeVariables.has(qualifiedName);
1201
+ static isOpaqueScopeVariableAccess(generatedCode: string): boolean {
1202
+ if (this.opaqueScopeVariables.has(generatedCode)) {
1203
+ return true;
1204
+ }
1205
+ // Issue #996: An element of an opaque-handle array is already a pointer.
1206
+ // Match on the base array name that precedes the subscript.
1207
+ const bracketIndex = generatedCode.indexOf("[");
1208
+ if (bracketIndex === -1) {
1209
+ return false;
1210
+ }
1211
+ return this.opaqueScopeVariables.has(generatedCode.slice(0, bracketIndex));
1147
1212
  }
1148
1213
 
1149
1214
  // ===========================================================================