@ball-lang/compiler 1.3.5 → 1.3.6

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/dist/types.d.ts CHANGED
@@ -49,11 +49,11 @@ export interface TypeAlias {
49
49
  }
50
50
  export interface EnumDef {
51
51
  name: string;
52
- values: EnumValue[];
52
+ value?: EnumValue[];
53
53
  }
54
54
  export interface EnumValue {
55
55
  name: string;
56
- intValue?: string | number;
56
+ number?: number;
57
57
  }
58
58
  export interface DescriptorProto {
59
59
  name: string;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ball-lang/compiler",
3
- "version": "1.3.5",
3
+ "version": "1.3.6",
4
4
  "description": "Ball → TypeScript compiler. Consumes a Ball protobuf Program and emits idiomatic TypeScript via ts-morph. The canonical TS compiler for Ball — lives in TS land so TS syntax knowledge doesn't leak into other languages.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
package/src/compiler.ts CHANGED
@@ -219,6 +219,26 @@ export class BallCompiler {
219
219
  this.emitClass(sf, td, members);
220
220
  }
221
221
 
222
+ // Enums declared in Module.enums[] (google.protobuf.EnumDescriptorProto,
223
+ // proto3 JSON: `{name, value: [{name, number}]}`). Both encoders emit
224
+ // enum declarations here (the Dart encoder with module-qualified names
225
+ // like "main:Color"); dropping them left `Color.red` references dangling
226
+ // in the compiled output (#120).
227
+ const emittedTypeNames = new Set(allTypeDefs.map((td) => classTsName(td.name)));
228
+ for (const mod of userModules) {
229
+ for (const en of mod.enums ?? []) {
230
+ const tsName = classTsName(en.name);
231
+ // A typeDef of the same name already produced a class declaration.
232
+ if (emittedTypeNames.has(tsName)) continue;
233
+ emittedTypeNames.add(tsName);
234
+ const entries = (en.value ?? []).map((v, i) => ({
235
+ name: v.name,
236
+ index: typeof v.number === "number" ? v.number : i,
237
+ }));
238
+ this.emitEnumClass(sf, tsName, entries);
239
+ }
240
+ }
241
+
222
242
  // Top-level variables (kind == 'top_level_variable') emit as
223
243
  // `const <name> = <body>;` before free functions.
224
244
  for (const fn of freeFunctions.filter(
@@ -2350,6 +2370,32 @@ function __isUnknownFnError(e: any): boolean {
2350
2370
  return false;
2351
2371
  }
2352
2372
 
2373
+ /**
2374
+ * Emit a Dart-style enum as a TS class with static singleton instances,
2375
+ * `index`/`name` properties, a `values` list, and `toString()` returning
2376
+ * `'<Enum>.<member>'`. Shared by the two enum declaration paths:
2377
+ * typeDefs with `metadata.kind == "enum"` and `Module.enums[]`
2378
+ * (google.protobuf.EnumDescriptorProto) entries.
2379
+ */
2380
+ private emitEnumClass(
2381
+ sf: ReturnType<Project["createSourceFile"]>,
2382
+ tsName: string,
2383
+ entries: Array<{ name: string; index: number }>,
2384
+ ): void {
2385
+ const staticProps = entries.map(
2386
+ (e) => `static readonly ${sanitize(e.name)} = new ${tsName}(${e.index}, '${e.name}');`,
2387
+ );
2388
+ const valuesArray = entries.map((e) => `${tsName}.${sanitize(e.name)}`).join(", ");
2389
+ sf.addStatements(`export class ${tsName} {
2390
+ readonly index: number;
2391
+ readonly name: string;
2392
+ private constructor(index: number, name: string) { this.index = index; this.name = name; }
2393
+ ${staticProps.join("\n ")}
2394
+ static readonly values: ${tsName}[] = [${valuesArray}];
2395
+ toString(): string { return '${tsName}.' + this.name; }
2396
+ }`);
2397
+ }
2398
+
2353
2399
  private emitClass(
2354
2400
  sf: ReturnType<Project["createSourceFile"]>,
2355
2401
  td: TypeDefinition,
@@ -2361,18 +2407,11 @@ function __isUnknownFnError(e: any): boolean {
2361
2407
  // Enum handling: emit a class with static instances, index, name, values.
2362
2408
  if (meta["kind"] === "enum") {
2363
2409
  const enumValues = Array.isArray(meta["values"]) ? meta["values"] as any[] : [];
2364
- const valueNames = enumValues.map((v: any) => typeof v === "string" ? v : (v?.name ?? ""));
2365
- // Build the enum class with index, name, static instances, and values.
2366
- const staticProps = valueNames.map((name, i) => `static readonly ${sanitize(name)} = new ${tsName}(${i}, '${name}');`);
2367
- const valuesArray = valueNames.map((name) => `${tsName}.${sanitize(name)}`).join(", ");
2368
- sf.addStatements(`export class ${tsName} {
2369
- readonly index: number;
2370
- readonly name: string;
2371
- private constructor(index: number, name: string) { this.index = index; this.name = name; }
2372
- ${staticProps.join("\n ")}
2373
- static readonly values: ${tsName}[] = [${valuesArray}];
2374
- toString(): string { return '${tsName}.' + this.name; }
2375
- }`);
2410
+ const entries = enumValues.map((v: any, i: number) => ({
2411
+ name: typeof v === "string" ? v : (v?.name ?? ""),
2412
+ index: i,
2413
+ }));
2414
+ this.emitEnumClass(sf, tsName, entries);
2376
2415
  return;
2377
2416
  }
2378
2417
 
@@ -3283,10 +3322,12 @@ function __isUnknownFnError(e: any): boolean {
3283
3322
  const start = field(call, "start");
3284
3323
  let initStr: string;
3285
3324
  if (variable && start) {
3286
- // Use `var` (not `let`) to match Dart's shared-variable loop semantics.
3287
- // Dart closures in loops capture the shared variable (final value);
3288
- // JS `let` gives per-iteration copies which breaks this behavior.
3289
- initStr = `var ${variable} = ${this.expr(start)}`;
3325
+ // Use `let` for a per-iteration binding: Dart's C-style for loop gives
3326
+ // each iteration its OWN copy of the loop variable, so closures created
3327
+ // in the body capture that iteration's value (conformance 229/312).
3328
+ // JS `let` matches this exactly; `var` would share one binding and
3329
+ // leak the final value into every closure (#69).
3330
+ initStr = `let ${variable} = ${this.expr(start)}`;
3290
3331
  } else if (init && init.literal?.stringValue !== undefined) {
3291
3332
  initStr = translateInitString(init.literal.stringValue);
3292
3333
  } else if (init && init.block) {
@@ -3304,7 +3345,7 @@ function __isUnknownFnError(e: any): boolean {
3304
3345
  }
3305
3346
  }
3306
3347
  }
3307
- initStr = parts.length > 0 ? `var ${parts.join(", ")}` : "";
3348
+ initStr = parts.length > 0 ? `let ${parts.join(", ")}` : "";
3308
3349
  } else if (init) {
3309
3350
  initStr = this.expr(init);
3310
3351
  } else {
@@ -3796,10 +3837,11 @@ function __isUnknownFnError(e: any): boolean {
3796
3837
 
3797
3838
  /**
3798
3839
  * Render a C-style for-init `block` (a single-let, no-result block) as an
3799
- * inline declaration string like `var i = 0` — NOT an IIFE, so the loop
3840
+ * inline declaration string like `let i = 0` — NOT an IIFE, so the loop
3800
3841
  * variable stays in scope for the condition/update. Mirrors the Dart
3801
- * compiler's `_renderForInit`. Uses `var` to match Dart's shared-variable
3802
- * loop-capture semantics. Returns "" on an unrecognized shape.
3842
+ * compiler's `_renderForInit`. Uses `let` so each iteration gets its own
3843
+ * binding, matching Dart's per-iteration loop-variable capture semantics
3844
+ * (#69, conformance 312). Returns "" on an unrecognized shape.
3803
3845
  */
3804
3846
  private renderForInit(initExpr: Expression): string {
3805
3847
  const block = initExpr.block;
@@ -3820,7 +3862,7 @@ function __isUnknownFnError(e: any): boolean {
3820
3862
  bindings.push(name);
3821
3863
  }
3822
3864
  }
3823
- return bindings.length > 0 ? `var ${bindings.join(", ")}` : "";
3865
+ return bindings.length > 0 ? `let ${bindings.join(", ")}` : "";
3824
3866
  }
3825
3867
 
3826
3868
  private compileFieldAccess(fa: NonNullable<Expression["fieldAccess"]>): string {
package/src/types.ts CHANGED
@@ -55,14 +55,16 @@ export interface TypeAlias {
55
55
  metadata?: Struct;
56
56
  }
57
57
 
58
+ // google.protobuf.EnumDescriptorProto in proto3 JSON form:
59
+ // `{ "name": "main:Color", "value": [{ "name": "red", "number": 0 }] }`.
58
60
  export interface EnumDef {
59
61
  name: string;
60
- values: EnumValue[];
62
+ value?: EnumValue[];
61
63
  }
62
64
 
63
65
  export interface EnumValue {
64
66
  name: string;
65
- intValue?: string | number;
67
+ number?: number;
66
68
  }
67
69
 
68
70
  export interface DescriptorProto {