c-next 0.1.42 → 0.1.43

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "c-next",
3
- "version": "0.1.42",
3
+ "version": "0.1.43",
4
4
  "description": "A safer C for embedded systems development. Transpiles to clean, readable C.",
5
5
  "main": "src/index.ts",
6
6
  "bin": {
@@ -3698,6 +3698,12 @@ export default class CodeGenerator implements IOrchestrator {
3698
3698
  // Get the text representation to analyze
3699
3699
  const text = ctx.getText();
3700
3700
 
3701
+ // Check if it's a function call returning an enum
3702
+ const enumReturnType = this._getFunctionCallEnumType(text);
3703
+ if (enumReturnType) {
3704
+ return enumReturnType;
3705
+ }
3706
+
3701
3707
  // Check if it's a simple identifier that's an enum variable
3702
3708
  if (/^[a-zA-Z_]\w*$/.exec(text)) {
3703
3709
  const typeInfo = this.context.typeRegistry.get(text);
@@ -3765,6 +3771,61 @@ export default class CodeGenerator implements IOrchestrator {
3765
3771
  return null;
3766
3772
  }
3767
3773
 
3774
+ /**
3775
+ * Check if an expression is a function call returning an enum type.
3776
+ * Handles patterns:
3777
+ * - func() or func(args) - global function
3778
+ * - Scope.method() or Scope.method(args) - scope method from outside
3779
+ * - this.method() or this.method(args) - scope method from inside
3780
+ * - global.func() or global.func(args) - global function from inside scope
3781
+ */
3782
+ private _getFunctionCallEnumType(text: string): string | null {
3783
+ // Check if this looks like a function call (contains parentheses)
3784
+ const parenIndex = text.indexOf("(");
3785
+ if (parenIndex === -1) {
3786
+ return null;
3787
+ }
3788
+
3789
+ // Extract the function reference (everything before the opening paren)
3790
+ const funcRef = text.substring(0, parenIndex);
3791
+ const parts = funcRef.split(".");
3792
+
3793
+ let fullFuncName: string | null = null;
3794
+
3795
+ if (parts.length === 1) {
3796
+ // Simple function call: func()
3797
+ fullFuncName = parts[0];
3798
+ } else if (parts.length === 2) {
3799
+ if (parts[0] === "this" && this.context.currentScope) {
3800
+ // this.method() -> Scope_method
3801
+ fullFuncName = `${this.context.currentScope}_${parts[1]}`;
3802
+ } else if (parts[0] === "global") {
3803
+ // global.func() -> func
3804
+ fullFuncName = parts[1];
3805
+ } else if (this.symbols!.knownScopes.has(parts[0])) {
3806
+ // Scope.method() -> Scope_method
3807
+ fullFuncName = `${parts[0]}_${parts[1]}`;
3808
+ }
3809
+ }
3810
+
3811
+ if (!fullFuncName) {
3812
+ return null;
3813
+ }
3814
+
3815
+ // Look up the function's return type
3816
+ const returnType = this.symbols!.functionReturnTypes.get(fullFuncName);
3817
+ if (!returnType) {
3818
+ return null;
3819
+ }
3820
+
3821
+ // Check if the return type is an enum
3822
+ if (this.symbols!.knownEnums.has(returnType)) {
3823
+ return returnType;
3824
+ }
3825
+
3826
+ return null;
3827
+ }
3828
+
3768
3829
  /**
3769
3830
  * ADR-017: Check if an expression represents an integer literal or numeric type.
3770
3831
  * Used to detect comparisons between enums and integers.
@@ -108,6 +108,15 @@ interface ISymbolInfo {
108
108
  */
109
109
  readonly scopePrivateConstValues: ReadonlyMap<string, string>;
110
110
 
111
+ // === Function Return Types ===
112
+
113
+ /**
114
+ * Function return types: "functionName" -> return type string.
115
+ * Used to determine enum types for function call expressions.
116
+ * Keys are full function names (e.g., "Motor_getMode" for scope methods, "getState" for globals).
117
+ */
118
+ readonly functionReturnTypes: ReadonlyMap<string, string>;
119
+
111
120
  /**
112
121
  * Check if a scope variable is used in only one function.
113
122
  * Returns the function name if single-function, null otherwise.
@@ -13,6 +13,7 @@ import ESymbolKind from "../../../types/ESymbolKind";
13
13
  import TSymbol from "../../types/TSymbol";
14
14
  import IBitmapSymbol from "../../types/IBitmapSymbol";
15
15
  import IEnumSymbol from "../../types/IEnumSymbol";
16
+ import IFunctionSymbol from "../../types/IFunctionSymbol";
16
17
  import IStructSymbol from "../../types/IStructSymbol";
17
18
  import IRegisterSymbol from "../../types/IRegisterSymbol";
18
19
  import IScopeSymbol from "../../types/IScopeSymbol";
@@ -86,6 +87,9 @@ class TSymbolInfoAdapter {
86
87
  // === Issue #282: Private const values for inlining ===
87
88
  const scopePrivateConstValues = new Map<string, string>();
88
89
 
90
+ // === Function Return Types ===
91
+ const functionReturnTypes = new Map<string, string>();
92
+
89
93
  // Process each symbol
90
94
  for (const symbol of symbols) {
91
95
  switch (symbol.kind) {
@@ -141,8 +145,9 @@ class TSymbolInfoAdapter {
141
145
  TSymbolInfoAdapter.processVariable(symbol, scopePrivateConstValues);
142
146
  break;
143
147
 
144
- // Functions don't add to ISymbolInfo directly
148
+ // Track function return types for enum validation
145
149
  case ESymbolKind.Function:
150
+ TSymbolInfoAdapter.processFunction(symbol, functionReturnTypes);
146
151
  break;
147
152
  }
148
153
  }
@@ -185,6 +190,9 @@ class TSymbolInfoAdapter {
185
190
  // Issue #282: Private const values for inlining
186
191
  scopePrivateConstValues,
187
192
 
193
+ // Function return types
194
+ functionReturnTypes,
195
+
188
196
  // Methods
189
197
  getSingleFunctionForVariable: (scopeName: string, varName: string) =>
190
198
  TSymbolInfoAdapter.getSingleFunctionForVariable(
@@ -346,6 +354,15 @@ class TSymbolInfoAdapter {
346
354
  }
347
355
  }
348
356
 
357
+ private static processFunction(
358
+ func: IFunctionSymbol,
359
+ functionReturnTypes: Map<string, string>,
360
+ ): void {
361
+ // Track function return types for enum validation in assignments
362
+ // This enables recognizing that Motor.getMode() returns Motor_EMode
363
+ functionReturnTypes.set(func.name, func.returnType);
364
+ }
365
+
349
366
  private static cnextTypeToCType(typeName: string): string {
350
367
  return CNEXT_TO_C_TYPE[typeName] || typeName;
351
368
  }
@@ -390,13 +407,19 @@ class TSymbolInfoAdapter {
390
407
  // Create mutable copies of enum-related data
391
408
  const mergedKnownEnums = new Set(base.knownEnums);
392
409
  const mergedEnumMembers = new Map<string, Map<string, number>>();
410
+ const mergedFunctionReturnTypes = new Map<string, string>();
393
411
 
394
412
  // Copy base enum members
395
413
  for (const [enumName, members] of base.enumMembers) {
396
414
  mergedEnumMembers.set(enumName, new Map(members));
397
415
  }
398
416
 
399
- // Merge in external enum info
417
+ // Copy base function return types
418
+ for (const [funcName, returnType] of base.functionReturnTypes) {
419
+ mergedFunctionReturnTypes.set(funcName, returnType);
420
+ }
421
+
422
+ // Merge in external enum info and function return types
400
423
  for (const external of externalEnumSources) {
401
424
  for (const enumName of external.knownEnums) {
402
425
  mergedKnownEnums.add(enumName);
@@ -407,6 +430,12 @@ class TSymbolInfoAdapter {
407
430
  mergedEnumMembers.set(enumName, new Map(members));
408
431
  }
409
432
  }
433
+ // Merge function return types from external sources
434
+ for (const [funcName, returnType] of external.functionReturnTypes) {
435
+ if (!mergedFunctionReturnTypes.has(funcName)) {
436
+ mergedFunctionReturnTypes.set(funcName, returnType);
437
+ }
438
+ }
410
439
  }
411
440
 
412
441
  // Return new ISymbolInfo with merged enum data
@@ -448,6 +477,9 @@ class TSymbolInfoAdapter {
448
477
  // Private const values
449
478
  scopePrivateConstValues: base.scopePrivateConstValues,
450
479
 
480
+ // Function return types - merged
481
+ functionReturnTypes: mergedFunctionReturnTypes,
482
+
451
483
  // Methods - delegate to base's implementation
452
484
  getSingleFunctionForVariable: base.getSingleFunctionForVariable,
453
485
  hasPublicSymbols: base.hasPublicSymbols,