@ball-lang/engine 1.4.3 → 1.4.4
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/compiled_engine.d.ts.map +1 -1
- package/dist/compiled_engine.js +33 -7
- package/dist/compiled_engine.js.map +1 -1
- package/dist/engine_setup.d.ts.map +1 -1
- package/dist/engine_setup.js +35 -4
- package/dist/engine_setup.js.map +1 -1
- package/package.json +4 -2
- package/src/compiled_engine.ts +33 -7
- package/src/engine_setup.ts +34 -3
package/src/compiled_engine.ts
CHANGED
|
@@ -3385,9 +3385,6 @@ export class BallEngine {
|
|
|
3385
3385
|
}
|
|
3386
3386
|
}
|
|
3387
3387
|
}
|
|
3388
|
-
if (((__ball_eq(name, 'List') || __ball_eq(name, 'Map')) || __ball_eq(name, 'Set'))) {
|
|
3389
|
-
return { ['__class_ref__']: name, ['__type__']: '__builtin_class__' };
|
|
3390
|
-
}
|
|
3391
3388
|
if (scope.has(name)) {
|
|
3392
3389
|
let bound = scope.lookup(name);
|
|
3393
3390
|
if (!__ball_eq(bound, null)) {
|
|
@@ -3499,6 +3496,9 @@ export class BallEngine {
|
|
|
3499
3496
|
this._globalScope.bind(staticField.fullName, value);
|
|
3500
3497
|
return value;
|
|
3501
3498
|
}
|
|
3499
|
+
if (((__ball_eq(name, 'List') || __ball_eq(name, 'Map')) || __ball_eq(name, 'Set'))) {
|
|
3500
|
+
return { ['__class_ref__']: name, ['__type__']: '__builtin_class__' };
|
|
3501
|
+
}
|
|
3502
3502
|
return scope.lookup(name);
|
|
3503
3503
|
}
|
|
3504
3504
|
|
|
@@ -3992,15 +3992,17 @@ export class BallEngine {
|
|
|
3992
3992
|
}
|
|
3993
3993
|
let instanceFields = {};
|
|
3994
3994
|
let allFieldNames = this._collectAllFieldNames(msg.typeName);
|
|
3995
|
-
for (const fieldName of typeDef.fieldNames) {
|
|
3996
|
-
instanceFields[fieldName] = null;
|
|
3997
|
-
}
|
|
3998
3995
|
for (const entry of fields.entries) {
|
|
3999
3996
|
if (!entry.key.startsWith('arg')) {
|
|
4000
3997
|
instanceFields[entry.key] = entry.value;
|
|
4001
3998
|
}
|
|
4002
3999
|
}
|
|
4003
4000
|
this._initFieldDefaults(msg.typeName, instanceFields);
|
|
4001
|
+
for (const fieldName of typeDef.fieldNames) {
|
|
4002
|
+
if (!(fieldName in instanceFields)) {
|
|
4003
|
+
instanceFields[fieldName] = null;
|
|
4004
|
+
}
|
|
4005
|
+
}
|
|
4004
4006
|
let ctorEntry = this._lookupConstructor(msg.typeName);
|
|
4005
4007
|
let resolvedParams = {};
|
|
4006
4008
|
if ((!__ball_eq(ctorEntry, null) && hasMetadata(ctorEntry.func))) {
|
|
@@ -4282,6 +4284,24 @@ export class BallEngine {
|
|
|
4282
4284
|
if ((__ball_eq(trimmed, '""') || __ball_eq(trimmed, '\'\''))) {
|
|
4283
4285
|
return '';
|
|
4284
4286
|
}
|
|
4287
|
+
if ((((trimmed.length >= 2) && trimmed.startsWith('[')) && trimmed.endsWith(']'))) {
|
|
4288
|
+
let inner = trimmed.substring(1, __ball_sub(trimmed.length, 1)).trim();
|
|
4289
|
+
if ((inner.length === 0)) {
|
|
4290
|
+
return [];
|
|
4291
|
+
}
|
|
4292
|
+
if ((!inner.includes('[') && !inner.includes('{'))) {
|
|
4293
|
+
return [...inner.split(',').map(((s) => {
|
|
4294
|
+
const input = s;
|
|
4295
|
+
return s.trim();
|
|
4296
|
+
})).filter(((s) => {
|
|
4297
|
+
const input = s;
|
|
4298
|
+
return !(s.length === 0);
|
|
4299
|
+
})).map(((s) => {
|
|
4300
|
+
const input = s;
|
|
4301
|
+
return this._parseInitializer(s);
|
|
4302
|
+
}))];
|
|
4303
|
+
}
|
|
4304
|
+
}
|
|
4285
4305
|
let intVal = int.tryParse(trimmed);
|
|
4286
4306
|
if (!__ball_eq(intVal, null)) {
|
|
4287
4307
|
return intVal;
|
|
@@ -4290,7 +4310,7 @@ export class BallEngine {
|
|
|
4290
4310
|
if (!__ball_eq(doubleVal, null)) {
|
|
4291
4311
|
return doubleVal;
|
|
4292
4312
|
}
|
|
4293
|
-
if (((trimmed.startsWith('\'') && trimmed.endsWith('\'')) || (trimmed.startsWith('"') && trimmed.endsWith('"')))) {
|
|
4313
|
+
if (((trimmed.length >= 2) && ((trimmed.startsWith('\'') && trimmed.endsWith('\'')) || (trimmed.startsWith('"') && trimmed.endsWith('"'))))) {
|
|
4294
4314
|
return trimmed.substring(1, __ball_sub(trimmed.length, 1));
|
|
4295
4315
|
}
|
|
4296
4316
|
return trimmed;
|
|
@@ -4334,6 +4354,12 @@ export class BallEngine {
|
|
|
4334
4354
|
superFields[fname] = __ball_index(childFields, fname);
|
|
4335
4355
|
}
|
|
4336
4356
|
}
|
|
4357
|
+
this._initFieldDefaults(superclass, superFields);
|
|
4358
|
+
for (const fname of parentTypeDef.fieldNames) {
|
|
4359
|
+
if (!(fname in superFields)) {
|
|
4360
|
+
superFields[fname] = null;
|
|
4361
|
+
}
|
|
4362
|
+
}
|
|
4337
4363
|
let parentMethods = this._resolveTypeMethods(qualifiedSuperclass);
|
|
4338
4364
|
let parentMethodsMap = parentMethods.cast();
|
|
4339
4365
|
let grandparent = parentTypeDef.superclass;
|
package/src/engine_setup.ts
CHANGED
|
@@ -485,8 +485,16 @@ export function createEngineSetup(mod: EngineModule) {
|
|
|
485
485
|
if (v && typeof v === 'object' && v.__ball_generator__ === true) return __bts(v.values);
|
|
486
486
|
if (Array.isArray(v)) return '[' + v.map(__bts).join(', ') + ']';
|
|
487
487
|
if (v instanceof Map) {
|
|
488
|
+
// NOT `v.entries()` — the compiled engine's own preamble shadows
|
|
489
|
+
// `Map.prototype.entries` with a Dart-style GETTER (returning an array
|
|
490
|
+
// of {key,value} objects, matching Dart's `Map.entries` property) so
|
|
491
|
+
// Ball's `.entries` field access works. That shadow makes `v.entries`
|
|
492
|
+
// non-callable, so `v.entries()` throws "not a function" for any real
|
|
493
|
+
// Map value. Iterate the Map directly instead — a Map's default
|
|
494
|
+
// iterator already yields [key, value] pairs and is unaffected by the
|
|
495
|
+
// entries/keys/values property shadowing.
|
|
488
496
|
const parts: string[] = [];
|
|
489
|
-
for (const [k, val] of v
|
|
497
|
+
for (const [k, val] of v) parts.push(__bts(k) + ': ' + __bts(val));
|
|
490
498
|
return '{' + parts.join(', ') + '}';
|
|
491
499
|
}
|
|
492
500
|
if (v instanceof Set) return '{' + [...v].map(__bts).join(', ') + '}';
|
|
@@ -906,7 +914,16 @@ export function createEngineSetup(mod: EngineModule) {
|
|
|
906
914
|
_r('string_char_at', (i: any) => { const m = _m(i); return String(m['value'] ?? m['string'] ?? '').charAt(Number(m['index'] ?? m['arg0'] ?? 0)); });
|
|
907
915
|
_r('string_to_int', (i: any) => {
|
|
908
916
|
const m = _m(i); const s = String(m['value'] ?? m['string'] ?? i ?? '').trim();
|
|
909
|
-
|
|
917
|
+
// `.message` must be the bare invalid text (Dart's `FormatException.message`
|
|
918
|
+
// is never prefixed with the type name — only `.toString()` adds that).
|
|
919
|
+
// Setting `name: 'FormatException'` (not just a `message` override) lets
|
|
920
|
+
// the default `Error.prototype.toString()` ("name: message") produce the
|
|
921
|
+
// Dart-correct "FormatException: <text>" for anything that prints the
|
|
922
|
+
// caught exception itself rather than `.message`. Previously the message
|
|
923
|
+
// override clobbered the "FormatException: " prefix right back out,
|
|
924
|
+
// leaving `.name` as the native "Error" — undetected because no
|
|
925
|
+
// conformance fixture prints a caught FormatException directly.
|
|
926
|
+
if (!/^-?\d+$/.test(s)) throw Object.assign(new Error(s), { name: 'FormatException', __type__: 'FormatException' });
|
|
910
927
|
return parseInt(s, 10);
|
|
911
928
|
});
|
|
912
929
|
_r('writeCharCode', (i: any) => { const m = _m(i); const self = m['self']; if (typeof self === 'object' && self !== null) { self['__buffer__'] = (self['__buffer__'] ?? '') + String.fromCharCode(Number(m['arg0'] ?? m['value'] ?? 0)); } return null; });
|
|
@@ -965,7 +982,21 @@ export function createEngineSetup(mod: EngineModule) {
|
|
|
965
982
|
return true;
|
|
966
983
|
});
|
|
967
984
|
_r('concat', (i: any) => { const m = _m(i); return String(m['left'] ?? '') + String(m['right'] ?? ''); });
|
|
968
|
-
|
|
985
|
+
// `?? i` (used by most unary helpers below) can't distinguish "no `value`
|
|
986
|
+
// field" from "`value` is explicitly null" — for every OTHER helper that's
|
|
987
|
+
// harmless (a null numeric/string arg just coerces away), but for
|
|
988
|
+
// null_check it inverts the function's entire purpose: `x!` where `x` is
|
|
989
|
+
// null must throw (matches the Dart engine's `_extractUnaryArg` + null
|
|
990
|
+
// check — see engine_std.dart's 'null_check' and its
|
|
991
|
+
// "throws BallRuntimeError on null" test), yet `m['value'] ?? i` silently
|
|
992
|
+
// fell back to the (truthy) input map and returned it instead of
|
|
993
|
+
// throwing. hasOwnProperty-gate so an explicit null is honored.
|
|
994
|
+
_r('null_check', (i: any) => {
|
|
995
|
+
const m = _m(i);
|
|
996
|
+
const v = Object.prototype.hasOwnProperty.call(m, 'value') ? m['value'] : i;
|
|
997
|
+
if (v == null) throw new Error('Null check operator used on a null value');
|
|
998
|
+
return v;
|
|
999
|
+
});
|
|
969
1000
|
_r('compare_to', (i: any) => {
|
|
970
1001
|
const m = _m(i); const l = m['left'] ?? m['value'] ?? m['self'] ?? m['a'] ?? 0; const r = m['right'] ?? m['other'] ?? m['arg0'] ?? m['b'] ?? 0;
|
|
971
1002
|
if (typeof l === 'string' && typeof r === 'string') return l < r ? -1 : l > r ? 1 : 0;
|