@ball-lang/compiler 1.3.5 → 1.3.7
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/compiler.d.ts +12 -3
- package/dist/compiler.d.ts.map +1 -1
- package/dist/compiler.js +55 -20
- package/dist/compiler.js.map +1 -1
- package/dist/types.d.ts +2 -2
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/compiler.ts +63 -21
- package/src/types.ts +4 -2
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
|
-
|
|
52
|
+
value?: EnumValue[];
|
|
53
53
|
}
|
|
54
54
|
export interface EnumValue {
|
|
55
55
|
name: string;
|
|
56
|
-
|
|
56
|
+
number?: number;
|
|
57
57
|
}
|
|
58
58
|
export interface DescriptorProto {
|
|
59
59
|
name: string;
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,WAAW,OAAO;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,MAAM;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,WAAW,EAAE,CAAC;IACzB,QAAQ,CAAC,EAAE,cAAc,EAAE,CAAC;IAC5B,WAAW,CAAC,EAAE,SAAS,EAAE,CAAC;IAC1B,KAAK,CAAC,EAAE,OAAO,EAAE,CAAC;IAClB,aAAa,CAAC,EAAE,YAAY,EAAE,CAAC;IAC/B,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,YAAY,CAAC;CACvB;AAED,MAAM,WAAW,YAAY;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,eAAe,CAAC;IAC7B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,WAAW,OAAO;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,MAAM;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,WAAW,EAAE,CAAC;IACzB,QAAQ,CAAC,EAAE,cAAc,EAAE,CAAC;IAC5B,WAAW,CAAC,EAAE,SAAS,EAAE,CAAC;IAC1B,KAAK,CAAC,EAAE,OAAO,EAAE,CAAC;IAClB,aAAa,CAAC,EAAE,YAAY,EAAE,CAAC;IAC/B,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,YAAY,CAAC;CACvB;AAED,MAAM,WAAW,YAAY;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,eAAe,CAAC;IAC7B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAID,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,SAAS,EAAE,CAAC;CACrB;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,eAAe,EAAE,CAAC;CAC3B;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,CAAC,EAAE,YAAY,CAAC;IACpB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,SAAS,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IAC7B,WAAW,CAAC,EAAE;QAAE,MAAM,EAAE,UAAU,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IACpD,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,UAAU,CAAC;CACpB;AAED,MAAM,WAAW,OAAO;IACtB,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,SAAS,CAAC,EAAE;QAAE,QAAQ,EAAE,UAAU,EAAE,CAAA;KAAE,CAAC;IACvC,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,cAAc,EAAE,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,UAAU,CAAC;CACnB;AAED,MAAM,WAAW,KAAK;IACpB,UAAU,EAAE,SAAS,EAAE,CAAC;IACxB,MAAM,CAAC,EAAE,UAAU,CAAC;CACrB;AAED,MAAM,WAAW,SAAS;IACxB,GAAG,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,UAAU,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC9D,UAAU,CAAC,EAAE,UAAU,CAAC;CACzB;AAED,MAAM,WAAW,MAAO,SAAQ,WAAW;CAE1C;AAMD,MAAM,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ball-lang/compiler",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.7",
|
|
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
|
|
2365
|
-
|
|
2366
|
-
|
|
2367
|
-
|
|
2368
|
-
|
|
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 `
|
|
3287
|
-
//
|
|
3288
|
-
//
|
|
3289
|
-
|
|
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 ? `
|
|
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 `
|
|
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 `
|
|
3802
|
-
*
|
|
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 ? `
|
|
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
|
-
|
|
62
|
+
value?: EnumValue[];
|
|
61
63
|
}
|
|
62
64
|
|
|
63
65
|
export interface EnumValue {
|
|
64
66
|
name: string;
|
|
65
|
-
|
|
67
|
+
number?: number;
|
|
66
68
|
}
|
|
67
69
|
|
|
68
70
|
export interface DescriptorProto {
|