mirror of
https://github.com/vercel-labs/scriptc.git
synced 2026-10-02 00:25:34 +08:00
Admit receiver-bound this in static Test262 scripts (#495)
* Admit receiver-bound this in static Test262 scripts * Refresh Set seed diagnostic snapshot
This commit is contained in:
@@ -27,7 +27,7 @@ const sameDate = mutableDate === mutableDate; // scalar storage must not fake ob
|
||||
const wm = new WeakMap();
|
||||
const px = new Proxy({ a: 1 }, {});
|
||||
const buf = new ArrayBuffer(8);
|
||||
const st = new Set(new Set([1, 2])); // array seeds lower; Set/iterable seeds stay fenced
|
||||
const st = new Set(new Set([1, 2])); // string and array seeds lower; Set-valued seeds stay fenced
|
||||
// (new Error / TypeError / RangeError / SyntaxError now LOWER — the error
|
||||
// battery lives in the corpus; what stays fenced is the rest of the family
|
||||
// and the unlowered members of lowered error objects.)
|
||||
|
||||
@@ -114,7 +114,7 @@ stdlib-fence.ts:29:7 - error SC2020: 'ArrayBuffer' is part of the standard libra
|
||||
28 | const px = new Proxy({ a: 1 }, {});
|
||||
29 | const buf = new ArrayBuffer(8);
|
||||
| ^~~
|
||||
30 | const st = new Set(new Set([1, 2])); // array seeds lower; Set/iterable seeds stay fenced
|
||||
30 | const st = new Set(new Set([1, 2])); // string and array seeds lower; Set-valued seeds stay fenced
|
||||
|
||||
hint: no free-standing ArrayBuffer value exists — typed arrays own their storage (new Uint8Array(n) allocates; new Uint8Array(new ArrayBuffer(n)) erases the buffer into the view)
|
||||
|
||||
@@ -123,18 +123,18 @@ stdlib-fence.ts:29:13 - error SC2020: 'new ArrayBuffer' is part of the standard
|
||||
28 | const px = new Proxy({ a: 1 }, {});
|
||||
29 | const buf = new ArrayBuffer(8);
|
||||
| ^~~~~~~~~~~~~~~~~~
|
||||
30 | const st = new Set(new Set([1, 2])); // array seeds lower; Set/iterable seeds stay fenced
|
||||
30 | const st = new Set(new Set([1, 2])); // string and array seeds lower; Set-valued seeds stay fenced
|
||||
|
||||
hint: no free-standing ArrayBuffer value exists — typed arrays own their storage: allocate the view directly (new Uint8Array(n)), or erase a fresh buffer into one (new Uint8Array(new ArrayBuffer(n)), new DataView(new ArrayBuffer(n), ...))
|
||||
|
||||
stdlib-fence.ts:30:12 - error SC2020: 'new Set(values)' is part of the standard library types but has no scriptc lowering yet
|
||||
|
||||
29 | const buf = new ArrayBuffer(8);
|
||||
30 | const st = new Set(new Set([1, 2])); // array seeds lower; Set/iterable seeds stay fenced
|
||||
30 | const st = new Set(new Set([1, 2])); // string and array seeds lower; Set-valued seeds stay fenced
|
||||
| ^~~~~~~~~~~~~~~~~~~~~~~~
|
||||
31 | // (new Error / TypeError / RangeError / SyntaxError now LOWER — the error
|
||||
|
||||
hint: construct the Set empty and add() each value — only an array or fixed tuple of already-legal elements (string or number) seeds a Set
|
||||
hint: construct the Set empty and add() each value — only a string, array, or fixed tuple of already-legal elements (string or number) seeds a Set
|
||||
|
||||
stdlib-fence.ts:34:7 - error SC2020: 'AggregateError' is part of the standard library types but has no scriptc lowering yet
|
||||
|
||||
|
||||
@@ -47,13 +47,32 @@ test("unsupported execution requirements and assertion reflection remain exclusi
|
||||
expect(exclusion(text, metadata(text), "strict")).toBeUndefined();
|
||||
expect(exclusion(text, metadata(text), "sloppy")).toBeUndefined();
|
||||
const scriptGlobal = source("description: script global", "assert.sameValue((function () { return this; })(), globalThis);");
|
||||
expect(exclusion(scriptGlobal, metadata(scriptGlobal), "sloppy")).toBe("host:script-environment");
|
||||
expect(exclusion(scriptGlobal, metadata(scriptGlobal), "sloppy")).toBe("host:globalThis");
|
||||
const commonJsGlobal = source("description: CommonJS global", "assert.sameValue(module.exports, {});");
|
||||
expect(exclusion(commonJsGlobal, metadata(commonJsGlobal), "sloppy")).toBe("host:module");
|
||||
const asyncText = source("flags: [async]", "Promise.resolve().then(() => $DONE());");
|
||||
expect(exclusion(asyncText, metadata(asyncText), "strict")).toBeUndefined();
|
||||
});
|
||||
|
||||
test("receiver-bound this is admitted without adapting script-level this", () => {
|
||||
for (const [body, expected] of [
|
||||
["class C { read() { return this.value; } }", undefined],
|
||||
["class C { read() { return () => this.value; } }", undefined],
|
||||
["class C { value = this; }", undefined],
|
||||
["class C { static { this.value = 1; } }", undefined],
|
||||
["function read() { return this; }", undefined],
|
||||
["const read = () => this;", "host:script-environment"],
|
||||
["assert.sameValue(this, undefined);", "host:script-environment"],
|
||||
["class C { [this.key]() {} }", "host:script-environment"],
|
||||
["class C extends this.Base {}", "host:script-environment"],
|
||||
] as const) {
|
||||
const text = source("description: this binding", body);
|
||||
for (const variant of ["strict", "sloppy"] as const) {
|
||||
expect(exclusion(text, metadata(text), variant), `${variant}: ${body}`).toBe(expected);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
test("negative parse cases require the compiler's matching source diagnostic", () => {
|
||||
const text = source("negative: {phase: parse, type: SyntaxError}", "$DONOTEVALUATE();\nconst = ;");
|
||||
expect(exclusion(text, metadata(text), "strict")).toBeUndefined();
|
||||
|
||||
@@ -84,6 +84,17 @@ export function variants(meta) {
|
||||
return ["sloppy", "strict"];
|
||||
}
|
||||
|
||||
function hasOwnThisBinding(node) {
|
||||
let child = node;
|
||||
for (let parent = node.parent; parent; child = parent, parent = parent.parent) {
|
||||
if (ts.isArrowFunction(parent)) continue;
|
||||
if (ts.isFunctionLike(parent) && child === parent.body) return true;
|
||||
if (ts.isPropertyDeclaration(parent) && child === parent.initializer) return true;
|
||||
if (ts.isClassStaticBlockDeclaration(parent) && child === parent.body) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// The first static profile adapts scripts to standalone strict modules. Be
|
||||
// conservative about observable global-script semantics and helper reflection.
|
||||
// Exclusions are runner limitations, never implementation support claims.
|
||||
@@ -105,11 +116,8 @@ export function exclusion(source, meta, variant) {
|
||||
if (meta.flags.includes("async")) forbidden.delete("$DONE");
|
||||
const visit = (node) => {
|
||||
if (reason) return;
|
||||
if (variant === "sloppy" && node.kind === ts.SyntaxKind.ThisKeyword) {
|
||||
reason = "host:script-environment";
|
||||
return;
|
||||
}
|
||||
if (node.kind === ts.SyntaxKind.ThisKeyword || node.kind === ts.SyntaxKind.ImportKeyword || ts.isImportDeclaration(node) || ts.isExportDeclaration(node)) {
|
||||
if ((node.kind === ts.SyntaxKind.ThisKeyword && !hasOwnThisBinding(node)) ||
|
||||
node.kind === ts.SyntaxKind.ImportKeyword || ts.isImportDeclaration(node) || ts.isExportDeclaration(node)) {
|
||||
reason = "host:script-environment";
|
||||
} else if (ts.isIdentifier(node) && forbidden.has(node.text)) {
|
||||
reason = `host:${node.text}`;
|
||||
|
||||
@@ -176,6 +176,9 @@
|
||||
"test/language/expressions/class/elements/fields-string-name-propname-constructor.js",
|
||||
"test/language/expressions/function/dflt-params-duplicates.js",
|
||||
"test/language/statements/class/class-name-ident-static.js",
|
||||
"test/language/statements/class/elements/private-accessor-name/inst-private-name-ZWNJ.js",
|
||||
"test/language/statements/class/elements/private-field-as-arrow-function.js",
|
||||
"test/language/statements/class/elements/regular-definitions-rs-privatename-identifier-initializer.js",
|
||||
"test/language/statements/const/dstr/ary-ptrn-elem-ary-elem-init.js",
|
||||
"test/language/statements/const/dstr/ary-ptrn-elem-id-init-exhausted.js",
|
||||
"test/language/statements/const/dstr/ary-ptrn-elem-id-init-fn-name-arrow.js",
|
||||
@@ -370,6 +373,9 @@
|
||||
"test/language/expressions/class/elements/fields-string-name-propname-constructor.js": "70bce532b9f18d8795e9ea5d640bdd063004ce873d614cca05d8071aa615a605",
|
||||
"test/language/expressions/function/dflt-params-duplicates.js": "243c05deb19b7d54a13d4f69059a8fb8d55911f066b5cc0ae14cfc41503c28ae",
|
||||
"test/language/statements/class/class-name-ident-static.js": "04d24cb0b646cf244fdde005cf3c6ecf6ae82897265ab3e1fe5cab7a4d6f6a64",
|
||||
"test/language/statements/class/elements/private-accessor-name/inst-private-name-ZWNJ.js": "32add15642ac1c1f8867fd66e72f2643d78aa0abcecc1a92d1467c710ee3f425",
|
||||
"test/language/statements/class/elements/private-field-as-arrow-function.js": "1f1816c812604cc4aa23446b063bae8858287646ec43df4cfd076f11510ec6a1",
|
||||
"test/language/statements/class/elements/regular-definitions-rs-privatename-identifier-initializer.js": "a9920a5506cadfef3ad399bb07826345913df62e7f73616f4024df82bbeffbf1",
|
||||
"test/language/statements/const/dstr/ary-ptrn-elem-ary-elem-init.js": "00f23ce81293acc6bd718a5a0de431928ed18db45c7ce849a0f76c365bc1ec9a",
|
||||
"test/language/statements/const/dstr/ary-ptrn-elem-id-init-exhausted.js": "73e765928b855ea0f89bd159a317ec212179260523d444e38b3518c8ac6c1681",
|
||||
"test/language/statements/const/dstr/ary-ptrn-elem-id-init-fn-name-arrow.js": "086210fc19498dad9b760b90398a3b46b366f3c4d4ee184200136641752ba832",
|
||||
|
||||
+78
@@ -0,0 +1,78 @@
|
||||
// This file was procedurally generated from the following sources:
|
||||
// - src/accessor-names/private-name-ZWNJ.case
|
||||
// - src/accessor-names/private/cls-private-decl-inst.template
|
||||
/*---
|
||||
description: Private IdentifierName - ZWNJ (Class declaration, private instance method)
|
||||
features: [class, class-methods-private]
|
||||
flags: [generated]
|
||||
info: |
|
||||
ClassElement :
|
||||
MethodDefinition
|
||||
static MethodDefinition
|
||||
FieldDefinition ;
|
||||
;
|
||||
|
||||
FieldDefinition :
|
||||
ClassElementName Initializer _opt
|
||||
|
||||
ClassElementName :
|
||||
PropertyName
|
||||
PrivateName
|
||||
|
||||
PrivateName ::
|
||||
# IdentifierName
|
||||
|
||||
Initializer :
|
||||
= AssignmentExpression
|
||||
|
||||
IdentifierName ::
|
||||
IdentifierStart
|
||||
IdentifierName IdentifierPart
|
||||
|
||||
IdentifierStart ::
|
||||
UnicodeIDStart
|
||||
$
|
||||
_
|
||||
\ UnicodeEscapeSequence
|
||||
|
||||
IdentifierPart::
|
||||
UnicodeIDContinue
|
||||
$
|
||||
\ UnicodeEscapeSequence
|
||||
<ZWNJ> <ZWJ>
|
||||
|
||||
UnicodeIDStart::
|
||||
any Unicode code point with the Unicode property "ID_Start"
|
||||
|
||||
UnicodeIDContinue::
|
||||
any Unicode code point with the Unicode property "ID_Continue"
|
||||
|
||||
|
||||
NOTE 3
|
||||
The sets of code points with Unicode properties "ID_Start" and
|
||||
"ID_Continue" include, respectively, the code points with Unicode
|
||||
properties "Other_ID_Start" and "Other_ID_Continue".
|
||||
|
||||
---*/
|
||||
|
||||
var stringSet;
|
||||
|
||||
class C {
|
||||
get #ZW__NJ() { return 'get string'; }
|
||||
set #ZW__NJ(param) { stringSet = param; }
|
||||
|
||||
getPrivateReference() {
|
||||
return this.#ZW__NJ;
|
||||
}
|
||||
|
||||
setPrivateReference(value) {
|
||||
this.#ZW__NJ = value;
|
||||
}
|
||||
};
|
||||
|
||||
var inst = new C();
|
||||
|
||||
assert.sameValue(inst.getPrivateReference(), 'get string');
|
||||
|
||||
inst.setPrivateReference('set string');
|
||||
assert.sameValue(stringSet, 'set string');
|
||||
Vendored
+33
@@ -0,0 +1,33 @@
|
||||
// This file was procedurally generated from the following sources:
|
||||
// - src/class-elements/private-field-as-arrow-function.case
|
||||
// - src/class-elements/default/cls-decl.template
|
||||
/*---
|
||||
description: Calling arrow function returned from private field access (field definitions in a class declaration)
|
||||
esid: prod-FieldDefinition
|
||||
features: [class-fields-private, arrow-function, class]
|
||||
flags: [generated]
|
||||
info: |
|
||||
Updated Productions
|
||||
|
||||
CallExpression[Yield, Await]:
|
||||
CoverCallExpressionAndAsyncArrowHead[?Yield, ?Await]
|
||||
SuperCall[?Yield, ?Await]
|
||||
CallExpression[?Yield, ?Await]Arguments[?Yield, ?Await]
|
||||
CallExpression[?Yield, ?Await][Expression[+In, ?Yield, ?Await]]
|
||||
CallExpression[?Yield, ?Await].IdentifierName
|
||||
CallExpression[?Yield, ?Await]TemplateLiteral[?Yield, ?Await]
|
||||
CallExpression[?Yield, ?Await].PrivateName
|
||||
|
||||
---*/
|
||||
|
||||
|
||||
class C {
|
||||
#m = () => 'test262';
|
||||
|
||||
method() {
|
||||
return this.#m();
|
||||
}
|
||||
}
|
||||
|
||||
let c = new C();
|
||||
assert.sameValue(c.method(), 'test262');
|
||||
+87
@@ -0,0 +1,87 @@
|
||||
// This file was procedurally generated from the following sources:
|
||||
// - src/class-elements/rs-privatename-identifier-initializer.case
|
||||
// - src/class-elements/productions/cls-decl-regular-definitions.template
|
||||
/*---
|
||||
description: Valid PrivateName (regular fields defintion)
|
||||
esid: prod-FieldDefinition
|
||||
features: [class-fields-private, class, class-fields-public]
|
||||
flags: [generated]
|
||||
info: |
|
||||
ClassElement :
|
||||
MethodDefinition
|
||||
static MethodDefinition
|
||||
FieldDefinition ;
|
||||
;
|
||||
|
||||
FieldDefinition :
|
||||
ClassElementName Initializer _opt
|
||||
|
||||
ClassElementName :
|
||||
PropertyName
|
||||
PrivateName
|
||||
|
||||
PrivateName ::
|
||||
# IdentifierName
|
||||
|
||||
IdentifierName ::
|
||||
IdentifierStart
|
||||
IdentifierName IdentifierPart
|
||||
|
||||
IdentifierStart ::
|
||||
UnicodeIDStart
|
||||
$
|
||||
_
|
||||
\ UnicodeEscapeSequence
|
||||
|
||||
IdentifierPart::
|
||||
UnicodeIDContinue
|
||||
$
|
||||
\ UnicodeEscapeSequence
|
||||
<ZWNJ> <ZWJ>
|
||||
|
||||
UnicodeIDStart::
|
||||
any Unicode code point with the Unicode property "ID_Start"
|
||||
|
||||
UnicodeIDContinue::
|
||||
any Unicode code point with the Unicode property "ID_Continue"
|
||||
|
||||
|
||||
NOTE 3
|
||||
The sets of code points with Unicode properties "ID_Start" and
|
||||
"ID_Continue" include, respectively, the code points with Unicode
|
||||
properties "Other_ID_Start" and "Other_ID_Continue".
|
||||
|
||||
---*/
|
||||
|
||||
|
||||
class C {
|
||||
#$ = 1; #_ = 1; #\u{6F} = 1; #\u2118 = 1; #ZW_\u200C_NJ = 1; #ZW_\u200D_J = 1
|
||||
$() {
|
||||
return this.#$;
|
||||
}
|
||||
_() {
|
||||
return this.#_;
|
||||
}
|
||||
\u{6F}() {
|
||||
return this.#\u{6F};
|
||||
}
|
||||
\u2118() {
|
||||
return this.#\u2118;
|
||||
}
|
||||
ZW_\u200C_NJ() {
|
||||
return this.#ZW_\u200C_NJ;
|
||||
}
|
||||
ZW_\u200D_J() {
|
||||
return this.#ZW_\u200D_J;
|
||||
}
|
||||
}
|
||||
|
||||
var c = new C();
|
||||
|
||||
assert.sameValue(c.$(), 1);
|
||||
assert.sameValue(c._(), 1);
|
||||
assert.sameValue(c.\u{6F}(), 1);
|
||||
assert.sameValue(c.\u2118(), 1);
|
||||
assert.sameValue(c.ZW_\u200C_NJ(), 1);
|
||||
assert.sameValue(c.ZW_\u200D_J(), 1);
|
||||
|
||||
Reference in New Issue
Block a user