@ball-lang/compiler 1.68.4 → 1.68.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/compiler.d.ts +14 -2
- package/dist/compiler.d.ts.map +1 -1
- package/dist/compiler.js +75 -52
- package/dist/compiler.js.map +1 -1
- package/package.json +1 -1
- package/src/compiler.ts +89 -47
package/dist/compiler.d.ts
CHANGED
|
@@ -174,8 +174,20 @@ export declare class BallCompiler {
|
|
|
174
174
|
private filterCtorBody;
|
|
175
175
|
/**
|
|
176
176
|
* Builds a named constructor as a static factory method.
|
|
177
|
-
*
|
|
178
|
-
*
|
|
177
|
+
*
|
|
178
|
+
* Every named constructor that is not a Dart `factory` CONSTRUCTS a real
|
|
179
|
+
* instance — whether it carries an initializer list (`Point.origin() : x =
|
|
180
|
+
* 0`), `this.`-formals (`Box.of(this.value)`), a plain body
|
|
181
|
+
* (`Bar.named(int x) { print(x); }`), or any combination. The instance comes
|
|
182
|
+
* from `Object.create(C.prototype)` so no user constructor runs, which means
|
|
183
|
+
* the class's inline field initializers do not run either: every declared
|
|
184
|
+
* field is seeded with its own default FIRST (Dart's ordering — inline field
|
|
185
|
+
* initializers, then the initializer list, then the body), and only then do
|
|
186
|
+
* the constructor-specific writes land on top (#564).
|
|
187
|
+
*
|
|
188
|
+
* A `factory` named constructor is the one exception: by definition it
|
|
189
|
+
* returns some other object, so its body runs as the static method's own
|
|
190
|
+
* statements and its value is the method's result.
|
|
179
191
|
*/
|
|
180
192
|
private buildNamedCtor;
|
|
181
193
|
private buildMethod;
|
package/dist/compiler.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compiler.d.ts","sourceRoot":"","sources":["../src/compiler.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAMV,MAAM,EACN,OAAO,EAIR,MAAM,YAAY,CAAC;AAGpB,MAAM,WAAW,cAAc;IAC7B,2EAA2E;IAC3E,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,sEAAsE;IACtE,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,uDAAuD;AACvD,MAAM,WAAW,qBAAqB;IACpC,2EAA2E;IAC3E,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,sEAAsE;IACtE,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAQD,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAU;IAElC,+CAA+C;IAC/C,OAAO,CAAC,GAAG,CAAM;IACjB,OAAO,CAAC,KAAK,CAAK;IAElB,4EAA4E;IAC5E,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAqB;IAE/C,sEAAsE;IACtE,OAAO,CAAC,YAAY,CAA0B;IAE9C,mEAAmE;IACnE,OAAO,CAAC,kBAAkB,CAA0B;IAEpD,mEAAmE;IACnE,OAAO,CAAC,mBAAmB,CAA0B;IAErD,0EAA0E;IAC1E,OAAO,CAAC,uBAAuB,CAA0B;IAEzD;0EACsE;IACtE,OAAO,CAAC,uBAAuB,CAA0B;IAEzD;;;;OAIG;IACH,OAAO,CAAC,uBAAuB,CAA0B;IAEzD,8EAA8E;IAC9E,OAAO,CAAC,gBAAgB,CAAqB;IAE7C,8EAA8E;IAC9E,OAAO,CAAC,sBAAsB,CAA0B;IAExD,yEAAyE;IACzE,OAAO,CAAC,gBAAgB,CAA0B;IAElD,4DAA4D;IAC5D,OAAO,CAAC,aAAa,CAA0C;IAE/D;;;OAGG;IACH,OAAO,CAAC,iBAAiB,CAA0B;IAEnD;;;;;OAKG;IACH,OAAO,CAAC,WAAW,CAA6B;IAEhD;;;;;;;;;;OAUG;IACH,OAAO,CAAC,gBAAgB,CAAgB;IAExC;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,gBAAgB,CAKhB;IAER;;;;;OAKG;IACH,OAAO,CAAC,QAAQ,CAAK;IAErB,6EAA6E;IAC7E,OAAO,CAAC,SAAS,CAAK;gBAEV,OAAO,EAAE,OAAO;IAI5B,4BAA4B;IAC5B,OAAO,CAAC,OAAO,GAAE,cAAmB,GAAG,MAAM;IAggE7C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAgCG;IACH,cAAc,CAAC,OAAO,GAAE,qBAA0B,GAAG,MAAM;IAiB3D;;;;;;;;;;;;;;;;;OAiBG;IACH,OAAO,CAAC,gBAAgB;IAwKxB,OAAO,CAAC,gBAAgB;IAoDxB;;;;OAIG;IACH,OAAO,CAAC,QAAQ;IAUhB,wEAAwE;IACxE,OAAO,CAAC,iBAAiB;IAoBzB;;;;;;OAMG;IACH,OAAO,CAAC,aAAa;IAmBrB,OAAO,CAAC,SAAS;
|
|
1
|
+
{"version":3,"file":"compiler.d.ts","sourceRoot":"","sources":["../src/compiler.ts"],"names":[],"mappings":"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"}
|
package/dist/compiler.js
CHANGED
|
@@ -2259,8 +2259,11 @@ function __isUnknownFnError(e: any): boolean {
|
|
|
2259
2259
|
}
|
|
2260
2260
|
else {
|
|
2261
2261
|
// Named constructors are static factory methods that return a new
|
|
2262
|
-
// instance.
|
|
2263
|
-
|
|
2262
|
+
// instance. The class's own (non-static) field declarations go with
|
|
2263
|
+
// them: the instance is built with `Object.create`, which runs no
|
|
2264
|
+
// field initializer, so the builder has to seed each default itself
|
|
2265
|
+
// (#564).
|
|
2266
|
+
methods.push(this.buildNamedCtor(fn, mMeta, fieldNames, tsName, properties.filter((p) => !p.isStatic)));
|
|
2264
2267
|
}
|
|
2265
2268
|
}
|
|
2266
2269
|
else if (mMeta["is_getter"] === true) {
|
|
@@ -2402,8 +2405,15 @@ function __isUnknownFnError(e: any): boolean {
|
|
|
2402
2405
|
}
|
|
2403
2406
|
}
|
|
2404
2407
|
else {
|
|
2408
|
+
// ONLY a `this.`-formal writes a constructor parameter into the field of
|
|
2409
|
+
// the same name. A plain parameter that merely happens to share a
|
|
2410
|
+
// field's name is an ordinary local and must never clobber that field's
|
|
2411
|
+
// initializer — `class Foo { int x = 5; Foo(int x) { print(x); } }`
|
|
2412
|
+
// leaves `x` at 5 in Dart (#539/#564, conformance 453). The old
|
|
2413
|
+
// `|| classFields.has(p.name)` disjunct is the byte-identical defect the
|
|
2414
|
+
// Dart engine carried until #563.
|
|
2405
2415
|
for (const p of rawParams) {
|
|
2406
|
-
if (p.isThis
|
|
2416
|
+
if (p.isThis) {
|
|
2407
2417
|
prologueParts.push(`this.${p.name} = ${sanitize(p.name)};`);
|
|
2408
2418
|
}
|
|
2409
2419
|
}
|
|
@@ -2469,53 +2479,48 @@ function __isUnknownFnError(e: any): boolean {
|
|
|
2469
2479
|
}
|
|
2470
2480
|
/**
|
|
2471
2481
|
* Builds a named constructor as a static factory method.
|
|
2472
|
-
*
|
|
2473
|
-
*
|
|
2482
|
+
*
|
|
2483
|
+
* Every named constructor that is not a Dart `factory` CONSTRUCTS a real
|
|
2484
|
+
* instance — whether it carries an initializer list (`Point.origin() : x =
|
|
2485
|
+
* 0`), `this.`-formals (`Box.of(this.value)`), a plain body
|
|
2486
|
+
* (`Bar.named(int x) { print(x); }`), or any combination. The instance comes
|
|
2487
|
+
* from `Object.create(C.prototype)` so no user constructor runs, which means
|
|
2488
|
+
* the class's inline field initializers do not run either: every declared
|
|
2489
|
+
* field is seeded with its own default FIRST (Dart's ordering — inline field
|
|
2490
|
+
* initializers, then the initializer list, then the body), and only then do
|
|
2491
|
+
* the constructor-specific writes land on top (#564).
|
|
2492
|
+
*
|
|
2493
|
+
* A `factory` named constructor is the one exception: by definition it
|
|
2494
|
+
* returns some other object, so its body runs as the static method's own
|
|
2495
|
+
* statements and its value is the method's result.
|
|
2474
2496
|
*/
|
|
2475
|
-
buildNamedCtor(fn, meta, classFields, className) {
|
|
2497
|
+
buildNamedCtor(fn, meta, classFields, className, classProperties = []) {
|
|
2476
2498
|
const params = extractParams(fn);
|
|
2477
2499
|
const ctorParams = extractCtorParams(meta);
|
|
2478
2500
|
const initializers = Array.isArray(meta["initializers"]) ? meta["initializers"] : [];
|
|
2479
2501
|
// Build the body: resolve field initializers and create a new instance.
|
|
2480
2502
|
const bodyParts = [];
|
|
2481
|
-
|
|
2482
|
-
//
|
|
2483
|
-
|
|
2484
|
-
|
|
2485
|
-
|
|
2486
|
-
|
|
2487
|
-
let resolvedValue;
|
|
2488
|
-
if (params.includes(valueStr)) {
|
|
2489
|
-
resolvedValue = sanitize(valueStr);
|
|
2490
|
-
}
|
|
2491
|
-
else if (/^-?\d+(\.\d+)?$/.test(valueStr)) {
|
|
2492
|
-
// Numeric literal — wrap in BallDouble if it has a decimal point
|
|
2493
|
-
resolvedValue = valueStr.includes(".") ? `new BallDouble(${valueStr})` : valueStr;
|
|
2494
|
-
}
|
|
2495
|
-
else if (valueStr.startsWith("'") || valueStr.startsWith('"')) {
|
|
2496
|
-
resolvedValue = valueStr;
|
|
2497
|
-
}
|
|
2498
|
-
else {
|
|
2499
|
-
// Try to parse indexed access like "coords[0]"
|
|
2500
|
-
const idxMatch = /^(\w+)\[(\d+)\]$/.exec(valueStr);
|
|
2501
|
-
if (idxMatch && params.includes(idxMatch[1])) {
|
|
2502
|
-
resolvedValue = `${sanitize(idxMatch[1])}[${idxMatch[2]}]`;
|
|
2503
|
-
}
|
|
2504
|
-
else {
|
|
2505
|
-
resolvedValue = valueStr;
|
|
2506
|
-
}
|
|
2507
|
-
}
|
|
2508
|
-
ctorArgs.push(resolvedValue);
|
|
2509
|
-
}
|
|
2510
|
-
}
|
|
2511
|
-
// Also check for is_this params — they pass directly to the constructor
|
|
2503
|
+
// Does the ctor have any field write of its own? Only WHETHER matters
|
|
2504
|
+
// here; each value is resolved where the assignment is emitted, by
|
|
2505
|
+
// `resolveInitializerValue`. (A `this.`-formal counts only when there is
|
|
2506
|
+
// no initializer list at all, preserving the historical branch selection
|
|
2507
|
+
// for the `Foo.named(this.x) : super(...)` shape, which still falls
|
|
2508
|
+
// through to `return new Foo()`.)
|
|
2512
2509
|
const thisParams = ctorParams.filter(p => p.isThis);
|
|
2513
|
-
|
|
2514
|
-
|
|
2515
|
-
|
|
2516
|
-
|
|
2517
|
-
|
|
2518
|
-
|
|
2510
|
+
const hasFieldInitializers = initializers.some((i) => i?.kind === "field" && typeof i.name === "string");
|
|
2511
|
+
const hasCtorFieldWrites = hasFieldInitializers || (initializers.length === 0 && thisParams.length > 0);
|
|
2512
|
+
// A Dart `factory` returns some other object, so it is the ONE named
|
|
2513
|
+
// constructor that must not synthesize an instance of its own class.
|
|
2514
|
+
const isFactory = meta["is_factory"] === true;
|
|
2515
|
+
// Everything else constructs: an initializer list / `this.`-formal, or a
|
|
2516
|
+
// plain body, or both. A body-only named constructor
|
|
2517
|
+
// (`Bar.named(int x) { print(x); }`) used to fall through to the
|
|
2518
|
+
// run-the-body-as-a-static-method branch below, so it created no instance
|
|
2519
|
+
// at all — `this` inside it was the CLASS and the method returned the
|
|
2520
|
+
// body's value, i.e. `undefined` for a `print` (#564, conformance
|
|
2521
|
+
// 453/454).
|
|
2522
|
+
const constructsInstance = hasCtorFieldWrites || (fn.body !== undefined && !isFactory);
|
|
2523
|
+
if (constructsInstance) {
|
|
2519
2524
|
// Use Object.create to avoid calling the constructor (which might be a factory).
|
|
2520
2525
|
// This directly instantiates with fields set.
|
|
2521
2526
|
const assignments = initializers
|
|
@@ -2525,16 +2530,29 @@ function __isUnknownFnError(e: any): boolean {
|
|
|
2525
2530
|
const thisAssignments = thisParams.map(p => `__inst.${p.name} = ${sanitize(p.name)};`);
|
|
2526
2531
|
const allAssignments = [...assignments, ...thisAssignments];
|
|
2527
2532
|
bodyParts.push(`const __inst = Object.create(${className}.prototype);`);
|
|
2533
|
+
// `Object.create` deliberately runs no constructor — which also means it
|
|
2534
|
+
// runs none of the class's inline field initializers. Seed every
|
|
2535
|
+
// declared field with the SAME default the class declaration emits,
|
|
2536
|
+
// before any constructor-specific write, exactly as Dart orders them
|
|
2537
|
+
// (inline initializers, then the initializer list, then the body).
|
|
2538
|
+
// Without this a field the named constructor never mentions stayed
|
|
2539
|
+
// `undefined` forever (#564: `Init.viaList`'s `w`, `Baz.bare`'s `v`).
|
|
2540
|
+
for (const p of classProperties) {
|
|
2541
|
+
const def = dartInitializerToTs(p.dartInitializer, p.type, p.rawDartType);
|
|
2542
|
+
if (def !== undefined)
|
|
2543
|
+
bodyParts.push(`__inst.${p.name} = ${def};`);
|
|
2544
|
+
}
|
|
2528
2545
|
for (const a of allAssignments)
|
|
2529
2546
|
bodyParts.push(a);
|
|
2530
|
-
// A named constructor may have
|
|
2531
|
-
//
|
|
2532
|
-
// `Countdown.from(this.value) { … }`
|
|
2533
|
-
// body; the body used to be dropped
|
|
2534
|
-
// field the body set stayed unset
|
|
2535
|
-
// — a real `function`, not an
|
|
2536
|
-
// instance as `this`, so its
|
|
2537
|
-
// while the constructor's
|
|
2547
|
+
// A named constructor may have an initializer list / `this.`-params, a
|
|
2548
|
+
// body, or both (`Countdown.pair(int s) : value = s { tail = …; }`,
|
|
2549
|
+
// `Countdown.from(this.value) { … }`, `Bar.named(int x) { print(x); }`).
|
|
2550
|
+
// Dart runs the list first, then the body; the body used to be dropped
|
|
2551
|
+
// entirely by this branch, so every field the body set stayed unset
|
|
2552
|
+
// (conformance 436/438). `.call(__inst)` — a real `function`, not an
|
|
2553
|
+
// arrow — gives the compiled body the instance as `this`, so its
|
|
2554
|
+
// `this.<field>` writes land on `__inst`, while the constructor's
|
|
2555
|
+
// parameters stay in scope by closure.
|
|
2538
2556
|
if (fn.body) {
|
|
2539
2557
|
const captured = this.withMethodContext(new Set(params), classFields, () => this.captureInto(() => {
|
|
2540
2558
|
this.emitStatementOrExpression(fn.body, false);
|
|
@@ -2546,13 +2564,18 @@ function __isUnknownFnError(e: any): boolean {
|
|
|
2546
2564
|
bodyParts.push(`return __inst;`);
|
|
2547
2565
|
}
|
|
2548
2566
|
else if (fn.body) {
|
|
2549
|
-
//
|
|
2567
|
+
// A `factory` named constructor: its body IS the method — whatever it
|
|
2568
|
+
// evaluates to is what the caller gets, and no instance of this class is
|
|
2569
|
+
// synthesized. This is the only body-bearing shape that reaches here
|
|
2570
|
+
// (every non-factory body constructs, above).
|
|
2550
2571
|
const captured = this.withMethodContext(new Set(params), classFields, () => this.captureInto(() => {
|
|
2551
2572
|
this.emitStatementOrExpression(fn.body, true);
|
|
2552
2573
|
}));
|
|
2553
2574
|
bodyParts.push(captured);
|
|
2554
2575
|
}
|
|
2555
2576
|
else {
|
|
2577
|
+
// Nothing to run and nothing to assign: let the real constructor build
|
|
2578
|
+
// it (which runs the class's inline field initializers itself).
|
|
2556
2579
|
bodyParts.push(`return new ${className}();`);
|
|
2557
2580
|
}
|
|
2558
2581
|
return {
|