From afe217b318df5f197e64b30a8b5a4b391c777359 Mon Sep 17 00:00:00 2001 From: jugglinmike Date: Thu, 15 Jul 2021 08:49:12 -0400 Subject: [PATCH] Add tests for "Class Static Init. Blocks" proposal (#2968) * Add tests for "Class Static Init. Blocks" proposal This proposal is currently at "stage 3" in TC39's standardization process. * fixup! Add tests for "Class Static Init. Blocks" proposal * Correct identifier reference * Update tests for grammar * Update tests for identifiers * Add tests for scope derivation --- features.txt | 4 ++ .../static-init-await-binding.js | 18 ++++++ .../static-init-await-reference.js | 18 ++++++ .../class/static-init-await-binding.js | 23 ++++++++ .../class/static-init-await-reference.js | 28 +++++++++ .../function/static-init-await-binding.js | 18 ++++++ .../function/static-init-await-reference.js | 26 +++++++++ .../generators/static-init-await-binding.js | 18 ++++++ .../generators/static-init-await-reference.js | 26 +++++++++ ...ame-prop-name-literal-await-static-init.js | 22 +++++++ ...ier-shorthand-static-init-await-invalid.js | 26 +++++++++ ...ifier-shorthand-static-init-await-valid.js | 18 ++++++ .../static-init-await-binding-accessor.js | 18 ++++++ .../static-init-await-binding-generator.js | 18 ++++++ .../static-init-await-binding-normal.js | 18 ++++++ .../static-init-await-reference-accessor.js | 28 +++++++++ .../static-init-await-reference-generator.js | 28 +++++++++ .../static-init-await-reference-normal.js | 28 +++++++++ .../static-init-invalid-await.js | 25 ++++++++ .../break/static-init-without-label.js | 27 +++++++++ .../statements/class/static-init-abrupt.js | 46 +++++++++++++++ .../class/static-init-arguments-functions.js | 40 +++++++++++++ .../class/static-init-arguments-methods.js | 58 +++++++++++++++++++ .../static-init-await-binding-invalid.js | 26 +++++++++ .../class/static-init-await-binding-valid.js | 18 ++++++ .../class/static-init-expr-new-target.js | 23 ++++++++ .../statements/class/static-init-expr-this.js | 23 ++++++++ .../class/static-init-invalid-arguments.js | 23 ++++++++ .../class/static-init-invalid-await.js | 33 +++++++++++ .../class/static-init-invalid-label-dup.js | 24 ++++++++ .../class/static-init-invalid-lex-dup.js | 24 ++++++++ .../class/static-init-invalid-lex-var.js | 25 ++++++++ .../class/static-init-invalid-return.js | 27 +++++++++ .../class/static-init-invalid-super-call.js | 22 +++++++ ...tic-init-invalid-undefined-break-target.js | 25 ++++++++ ...-init-invalid-undefined-continue-target.js | 25 ++++++++ .../class/static-init-invalid-yield.js | 27 +++++++++ .../class/static-init-scope-lex-close.js | 27 +++++++++ .../class/static-init-scope-lex-derived.js | 23 ++++++++ .../class/static-init-scope-lex-open.js | 31 ++++++++++ .../class/static-init-scope-private.js | 25 ++++++++ .../class/static-init-scope-var-close.js | 27 +++++++++ .../class/static-init-scope-var-derived.js | 24 ++++++++ .../class/static-init-scope-var-open.js | 31 ++++++++++ .../statements/class/static-init-sequence.js | 38 ++++++++++++ .../static-init-statement-list-optional.js | 18 ++++++ .../class/static-init-super-property.js | 24 ++++++++ .../static-init-await-binding-invalid.js | 26 +++++++++ .../const/static-init-await-binding-valid.js | 18 ++++++ .../continue/static-init-with-label.js | 28 +++++++++ .../continue/static-init-without-label.js | 28 +++++++++ .../static-init-await-binding-invalid.js | 27 +++++++++ .../static-init-await-binding-valid.js | 18 ++++++ .../labeled/static-init-invalid-await.js | 25 ++++++++ .../let/static-init-await-binding-invalid.js | 26 +++++++++ .../let/static-init-await-binding-valid.js | 18 ++++++ .../try/static-init-await-binding-invalid.js | 26 +++++++++ .../try/static-init-await-binding-valid.js | 18 ++++++ ...-ptrn-elem-id-static-init-await-invalid.js | 26 +++++++++ ...ry-ptrn-elem-id-static-init-await-valid.js | 18 ++++++ ...-ptrn-elem-id-static-init-await-invalid.js | 26 +++++++++ ...bj-ptrn-elem-id-static-init-await-valid.js | 18 ++++++ .../static-init-await-binding-invalid.js | 26 +++++++++ .../static-init-await-binding-valid.js | 18 ++++++ 64 files changed, 1582 insertions(+) create mode 100644 test/language/expressions/arrow-function/static-init-await-binding.js create mode 100644 test/language/expressions/arrow-function/static-init-await-reference.js create mode 100644 test/language/expressions/class/static-init-await-binding.js create mode 100644 test/language/expressions/class/static-init-await-reference.js create mode 100644 test/language/expressions/function/static-init-await-binding.js create mode 100644 test/language/expressions/function/static-init-await-reference.js create mode 100644 test/language/expressions/generators/static-init-await-binding.js create mode 100644 test/language/expressions/generators/static-init-await-reference.js create mode 100644 test/language/expressions/object/ident-name-prop-name-literal-await-static-init.js create mode 100644 test/language/expressions/object/identifier-shorthand-static-init-await-invalid.js create mode 100644 test/language/expressions/object/identifier-shorthand-static-init-await-valid.js create mode 100644 test/language/expressions/object/method-definition/static-init-await-binding-accessor.js create mode 100644 test/language/expressions/object/method-definition/static-init-await-binding-generator.js create mode 100644 test/language/expressions/object/method-definition/static-init-await-binding-normal.js create mode 100644 test/language/expressions/object/method-definition/static-init-await-reference-accessor.js create mode 100644 test/language/expressions/object/method-definition/static-init-await-reference-generator.js create mode 100644 test/language/expressions/object/method-definition/static-init-await-reference-normal.js create mode 100644 test/language/identifier-resolution/static-init-invalid-await.js create mode 100644 test/language/statements/break/static-init-without-label.js create mode 100644 test/language/statements/class/static-init-abrupt.js create mode 100644 test/language/statements/class/static-init-arguments-functions.js create mode 100644 test/language/statements/class/static-init-arguments-methods.js create mode 100644 test/language/statements/class/static-init-await-binding-invalid.js create mode 100644 test/language/statements/class/static-init-await-binding-valid.js create mode 100644 test/language/statements/class/static-init-expr-new-target.js create mode 100644 test/language/statements/class/static-init-expr-this.js create mode 100644 test/language/statements/class/static-init-invalid-arguments.js create mode 100644 test/language/statements/class/static-init-invalid-await.js create mode 100644 test/language/statements/class/static-init-invalid-label-dup.js create mode 100644 test/language/statements/class/static-init-invalid-lex-dup.js create mode 100644 test/language/statements/class/static-init-invalid-lex-var.js create mode 100644 test/language/statements/class/static-init-invalid-return.js create mode 100644 test/language/statements/class/static-init-invalid-super-call.js create mode 100644 test/language/statements/class/static-init-invalid-undefined-break-target.js create mode 100644 test/language/statements/class/static-init-invalid-undefined-continue-target.js create mode 100644 test/language/statements/class/static-init-invalid-yield.js create mode 100644 test/language/statements/class/static-init-scope-lex-close.js create mode 100644 test/language/statements/class/static-init-scope-lex-derived.js create mode 100644 test/language/statements/class/static-init-scope-lex-open.js create mode 100644 test/language/statements/class/static-init-scope-private.js create mode 100644 test/language/statements/class/static-init-scope-var-close.js create mode 100644 test/language/statements/class/static-init-scope-var-derived.js create mode 100644 test/language/statements/class/static-init-scope-var-open.js create mode 100644 test/language/statements/class/static-init-sequence.js create mode 100644 test/language/statements/class/static-init-statement-list-optional.js create mode 100644 test/language/statements/class/static-init-super-property.js create mode 100644 test/language/statements/const/static-init-await-binding-invalid.js create mode 100644 test/language/statements/const/static-init-await-binding-valid.js create mode 100644 test/language/statements/continue/static-init-with-label.js create mode 100644 test/language/statements/continue/static-init-without-label.js create mode 100644 test/language/statements/function/static-init-await-binding-invalid.js create mode 100644 test/language/statements/function/static-init-await-binding-valid.js create mode 100644 test/language/statements/labeled/static-init-invalid-await.js create mode 100644 test/language/statements/let/static-init-await-binding-invalid.js create mode 100644 test/language/statements/let/static-init-await-binding-valid.js create mode 100644 test/language/statements/try/static-init-await-binding-invalid.js create mode 100644 test/language/statements/try/static-init-await-binding-valid.js create mode 100644 test/language/statements/variable/dstr/ary-ptrn-elem-id-static-init-await-invalid.js create mode 100644 test/language/statements/variable/dstr/ary-ptrn-elem-id-static-init-await-valid.js create mode 100644 test/language/statements/variable/dstr/obj-ptrn-elem-id-static-init-await-invalid.js create mode 100644 test/language/statements/variable/dstr/obj-ptrn-elem-id-static-init-await-valid.js create mode 100644 test/language/statements/variable/static-init-await-binding-invalid.js create mode 100644 test/language/statements/variable/static-init-await-binding-valid.js diff --git a/features.txt b/features.txt index 25278ef6b4..66d09e854a 100644 --- a/features.txt +++ b/features.txt @@ -217,6 +217,10 @@ align-detached-buffer-semantics-with-web-reality # https://github.com/tc39/proposal-accessible-object-hasownproperty Object.hasOwn +# Class static initialization blocks +# https://github.com/tc39/proposal-class-static-block +class-static-block + ## Standard language features # # Language features that have been included in a published version of the diff --git a/test/language/expressions/arrow-function/static-init-await-binding.js b/test/language/expressions/arrow-function/static-init-await-binding.js new file mode 100644 index 0000000000..c83c3a3c54 --- /dev/null +++ b/test/language/expressions/arrow-function/static-init-await-binding.js @@ -0,0 +1,18 @@ +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-class-definitions-static-semantics-early-errors +description: The `await` keyword is disallowed in the BindingIdentifier position +features: [class-static-block] +negative: + phase: parse + type: SyntaxError +---*/ + +$DONOTEVALUATE(); + +class C { + static { + (await => 0); + } +} diff --git a/test/language/expressions/arrow-function/static-init-await-reference.js b/test/language/expressions/arrow-function/static-init-await-reference.js new file mode 100644 index 0000000000..8b20af7e01 --- /dev/null +++ b/test/language/expressions/arrow-function/static-init-await-reference.js @@ -0,0 +1,18 @@ +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-class-definitions-static-semantics-early-errors +description: The `await` keyword is disallowed in the IdentifierReference position +features: [class-static-block] +negative: + phase: parse + type: SyntaxError +---*/ + +$DONOTEVALUATE(); + +class C { + static { + ((x = await) => 0); + } +} diff --git a/test/language/expressions/class/static-init-await-binding.js b/test/language/expressions/class/static-init-await-binding.js new file mode 100644 index 0000000000..c99b04c55e --- /dev/null +++ b/test/language/expressions/class/static-init-await-binding.js @@ -0,0 +1,23 @@ +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-class-definitions-static-semantics-early-errors +description: The `await` keyword is disallowed as a BindingIdentifier +info: | + ClassStaticBlockBody : ClassStaticBlockStatementList + + [...] + - It is a Syntax Error if ContainsAwait of ClassStaticBlockStatementList is true. +features: [class-static-block] +negative: + phase: parse + type: SyntaxError +---*/ + +$DONOTEVALUATE(); + +class C { + static { + (class await {}); + } +} diff --git a/test/language/expressions/class/static-init-await-reference.js b/test/language/expressions/class/static-init-await-reference.js new file mode 100644 index 0000000000..f27128a2f0 --- /dev/null +++ b/test/language/expressions/class/static-init-await-reference.js @@ -0,0 +1,28 @@ +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-class-definitions-static-semantics-early-errors +description: The `await` keyword is interpreted as a IdentifierReference in method parameter lists +info: | + ClassStaticBlockBody : ClassStaticBlockStatementList + + [...] + - It is a Syntax Error if ContainsAwait of ClassStaticBlockStatementList is true. +features: [class-static-block] +---*/ + +var await = 0; +var fromParam, fromBody; + +class C { + static { + new (class { + constructor(x = fromParam = await) { + fromBody = await; + } + }); + } +} + +assert.sameValue(fromParam, 0, 'from parameter'); +assert.sameValue(fromBody, 0, 'from body'); diff --git a/test/language/expressions/function/static-init-await-binding.js b/test/language/expressions/function/static-init-await-binding.js new file mode 100644 index 0000000000..cc8d0e090f --- /dev/null +++ b/test/language/expressions/function/static-init-await-binding.js @@ -0,0 +1,18 @@ +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-class-definitions-static-semantics-early-errors +description: The `await` keyword is interpreted as an IdentifierReference within function expressions +info: | + ClassStaticBlockBody : ClassStaticBlockStatementList + + [...] + - It is a Syntax Error if ContainsAwait of ClassStaticBlockStatementList is true. +features: [class-static-block] +---*/ + +class C { + static { + (function await(await) {}); + } +} diff --git a/test/language/expressions/function/static-init-await-reference.js b/test/language/expressions/function/static-init-await-reference.js new file mode 100644 index 0000000000..50a55c9953 --- /dev/null +++ b/test/language/expressions/function/static-init-await-reference.js @@ -0,0 +1,26 @@ +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-class-definitions-static-semantics-early-errors +description: The `await` keyword is interpreted as an IdentifierReference within function expressions +info: | + ClassStaticBlockBody : ClassStaticBlockStatementList + + [...] + - It is a Syntax Error if ContainsAwait of ClassStaticBlockStatementList is true. +features: [class-static-block] +---*/ + +var await = 0; +var fromParam, fromBody; + +class C { + static { + (function (x = fromParam = await) { + fromBody = await; + })(); + } +} + +assert.sameValue(fromParam, 0, 'from parameter'); +assert.sameValue(fromBody, 0, 'from body'); diff --git a/test/language/expressions/generators/static-init-await-binding.js b/test/language/expressions/generators/static-init-await-binding.js new file mode 100644 index 0000000000..09b52e8ebc --- /dev/null +++ b/test/language/expressions/generators/static-init-await-binding.js @@ -0,0 +1,18 @@ +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-class-definitions-static-semantics-early-errors +description: The `await` keyword is interpreted as an Identifier within generator function expressions +info: | + ClassStaticBlockBody : ClassStaticBlockStatementList + + [...] + - It is a Syntax Error if ContainsAwait of ClassStaticBlockStatementList is true. +features: [class-static-block] +---*/ + +class C { + static { + (function * await (await) {}); + } +} diff --git a/test/language/expressions/generators/static-init-await-reference.js b/test/language/expressions/generators/static-init-await-reference.js new file mode 100644 index 0000000000..952fd47ca1 --- /dev/null +++ b/test/language/expressions/generators/static-init-await-reference.js @@ -0,0 +1,26 @@ +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-class-definitions-static-semantics-early-errors +description: The `await` keyword is interpreted as an Identifier within generator function expressions +info: | + ClassStaticBlockBody : ClassStaticBlockStatementList + + [...] + - It is a Syntax Error if ContainsAwait of ClassStaticBlockStatementList is true. +features: [class-static-block] +---*/ + +var await = 0; +var fromParam, fromBody; + +class C { + static { + (function * (x = fromParam = await) { + fromBody = await; + })().next(); + } +} + +assert.sameValue(fromParam, 0, 'from parameter'); +assert.sameValue(fromBody, 0, 'from body'); diff --git a/test/language/expressions/object/ident-name-prop-name-literal-await-static-init.js b/test/language/expressions/object/ident-name-prop-name-literal-await-static-init.js new file mode 100644 index 0000000000..ab01dfc8e8 --- /dev/null +++ b/test/language/expressions/object/ident-name-prop-name-literal-await-static-init.js @@ -0,0 +1,22 @@ +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-class-definitions-static-semantics-early-errors +description: The restriction on `await` does not apply to IdentifierName +info: | + BindingIdentifier : Identifier + + [...] + - It is a Syntax Error if the code matched by this production is nested, + directly or indirectly (but not crossing function or static initialization + block boundaries), within a ClassStaticBlock and the StringValue of + Identifier is "await". +features: [class-static-block] +---*/ + +class C { + static { + ({ await: 0 }); + } +} + diff --git a/test/language/expressions/object/identifier-shorthand-static-init-await-invalid.js b/test/language/expressions/object/identifier-shorthand-static-init-await-invalid.js new file mode 100644 index 0000000000..2f693b46ac --- /dev/null +++ b/test/language/expressions/object/identifier-shorthand-static-init-await-invalid.js @@ -0,0 +1,26 @@ +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-class-definitions-static-semantics-early-errors +description: IdentifierReference may not be `await` within class static blocks +info: | + IdentifierReference : Identifier + + - It is a Syntax Error if the code matched by this production is nested, + directly or indirectly (but not crossing function or static initialization + block boundaries), within a ClassStaticBlock and the StringValue of + Identifier is "arguments" or "await". +negative: + phase: parse + type: SyntaxError +features: [class-static-block] +---*/ + +$DONOTEVALUATE(); + +class C { + static { + ({ await }); + } +} + diff --git a/test/language/expressions/object/identifier-shorthand-static-init-await-valid.js b/test/language/expressions/object/identifier-shorthand-static-init-await-valid.js new file mode 100644 index 0000000000..868bb9842f --- /dev/null +++ b/test/language/expressions/object/identifier-shorthand-static-init-await-valid.js @@ -0,0 +1,18 @@ +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-class-definitions-static-semantics-early-errors +description: The `await` keyword is interpreted as an identifier within the body of arrow functions +info: | + ClassStaticBlockBody : ClassStaticBlockStatementList + + [...] + - It is a Syntax Error if ContainsAwait of ClassStaticBlockStatementList is true. +features: [class-static-block] +---*/ + +class C { + static { + (() => ({ await })); + } +} diff --git a/test/language/expressions/object/method-definition/static-init-await-binding-accessor.js b/test/language/expressions/object/method-definition/static-init-await-binding-accessor.js new file mode 100644 index 0000000000..8eeda7fc6f --- /dev/null +++ b/test/language/expressions/object/method-definition/static-init-await-binding-accessor.js @@ -0,0 +1,18 @@ +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-class-definitions-static-semantics-early-errors +description: The `await` keyword is interpreted as an identifier within the body of accessor methods +info: | + ClassStaticBlockBody : ClassStaticBlockStatementList + + [...] + - It is a Syntax Error if ContainsAwait of ClassStaticBlockStatementList is true. +features: [class-static-block] +---*/ + +class C { + static { + ({set accessor(await) {}}); + } +} diff --git a/test/language/expressions/object/method-definition/static-init-await-binding-generator.js b/test/language/expressions/object/method-definition/static-init-await-binding-generator.js new file mode 100644 index 0000000000..33e5f18275 --- /dev/null +++ b/test/language/expressions/object/method-definition/static-init-await-binding-generator.js @@ -0,0 +1,18 @@ +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-class-definitions-static-semantics-early-errors +description: The `await` keyword is interpreted as an identifier within the parameter list of generator methods +info: | + ClassStaticBlockBody : ClassStaticBlockStatementList + + [...] + - It is a Syntax Error if ContainsAwait of ClassStaticBlockStatementList is true. +features: [class-static-block] +---*/ + +class C { + static { + ({*method(await) {}}); + } +} diff --git a/test/language/expressions/object/method-definition/static-init-await-binding-normal.js b/test/language/expressions/object/method-definition/static-init-await-binding-normal.js new file mode 100644 index 0000000000..4c548f4ba9 --- /dev/null +++ b/test/language/expressions/object/method-definition/static-init-await-binding-normal.js @@ -0,0 +1,18 @@ +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-class-definitions-static-semantics-early-errors +description: The `await` keyword is interpreted as an identifier within the parameter list of methods +info: | + ClassStaticBlockBody : ClassStaticBlockStatementList + + [...] + - It is a Syntax Error if ContainsAwait of ClassStaticBlockStatementList is true. +features: [class-static-block] +---*/ + +class C { + static { + ({method(await) {}}); + } +} diff --git a/test/language/expressions/object/method-definition/static-init-await-reference-accessor.js b/test/language/expressions/object/method-definition/static-init-await-reference-accessor.js new file mode 100644 index 0000000000..85e4fbc3ef --- /dev/null +++ b/test/language/expressions/object/method-definition/static-init-await-reference-accessor.js @@ -0,0 +1,28 @@ +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-class-definitions-static-semantics-early-errors +description: The `await` keyword is interpreted as an identifier within accessor methods +info: | + ClassStaticBlockBody : ClassStaticBlockStatementList + + [...] + - It is a Syntax Error if ContainsAwait of ClassStaticBlockStatementList is true. +features: [class-static-block] +---*/ + +var await = 0; +var fromParam, fromBody; + +class C { + static { + ({ + set accessor(x = fromParam = await) { + fromBody = await; + } + }).accessor = undefined; + } +} + +assert.sameValue(fromParam, 0, 'from parameter'); +assert.sameValue(fromBody, 0, 'from body'); diff --git a/test/language/expressions/object/method-definition/static-init-await-reference-generator.js b/test/language/expressions/object/method-definition/static-init-await-reference-generator.js new file mode 100644 index 0000000000..eaaf7a4be4 --- /dev/null +++ b/test/language/expressions/object/method-definition/static-init-await-reference-generator.js @@ -0,0 +1,28 @@ +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-class-definitions-static-semantics-early-errors +description: The `await` keyword is interpreted as an identifier within generator methods +info: | + ClassStaticBlockBody : ClassStaticBlockStatementList + + [...] + - It is a Syntax Error if ContainsAwait of ClassStaticBlockStatementList is true. +features: [class-static-block] +---*/ + +var await = 0; +var fromParam, fromBody; + +class C { + static { + ({ + *method(x = fromParam = await) { + fromBody = await; + } + }).method().next(); + } +} + +assert.sameValue(fromParam, 0, 'from parameter'); +assert.sameValue(fromBody, 0, 'from body'); diff --git a/test/language/expressions/object/method-definition/static-init-await-reference-normal.js b/test/language/expressions/object/method-definition/static-init-await-reference-normal.js new file mode 100644 index 0000000000..bafa30e4f6 --- /dev/null +++ b/test/language/expressions/object/method-definition/static-init-await-reference-normal.js @@ -0,0 +1,28 @@ +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-class-definitions-static-semantics-early-errors +description: The `await` keyword is interpreted as an identifier within methods +info: | + ClassStaticBlockBody : ClassStaticBlockStatementList + + [...] + - It is a Syntax Error if ContainsAwait of ClassStaticBlockStatementList is true. +features: [class-static-block] +---*/ + +var await = 0; +var fromParam, fromBody; + +class C { + static { + ({ + method(x = fromParam = await) { + fromBody = await; + } + }).method(); + } +} + +assert.sameValue(fromParam, 0, 'from parameter'); +assert.sameValue(fromBody, 0, 'from body'); diff --git a/test/language/identifier-resolution/static-init-invalid-await.js b/test/language/identifier-resolution/static-init-invalid-await.js new file mode 100644 index 0000000000..61ddd625d5 --- /dev/null +++ b/test/language/identifier-resolution/static-init-invalid-await.js @@ -0,0 +1,25 @@ +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-class-definitions-static-semantics-early-errors +description: Restriction on `await` +info: | + IdentifierReference : Identifier + + - It is a Syntax Error if the code matched by this production is nested, + directly or indirectly (but not crossing function or static initialization + block boundaries), within a ClassStaticBlock and the StringValue of + Identifier is "arguments" or "await". +negative: + phase: parse + type: SyntaxError +features: [class-static-block] +---*/ + +$DONOTEVALUATE(); + +class C { + static { + await; + } +} diff --git a/test/language/statements/break/static-init-without-label.js b/test/language/statements/break/static-init-without-label.js new file mode 100644 index 0000000000..2caeeabafb --- /dev/null +++ b/test/language/statements/break/static-init-without-label.js @@ -0,0 +1,27 @@ +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-break-statement +description: IterationStatement search does not traverse static initialization block boundaries (no label specified) +info: | + 4.2.1 Static Semantics: Early Errors + BreakStatement : break ; + + - It is a Syntax Error if this BreakStatement is not nested, directly or + indirectly (but not crossing function or static initialization block + boundaries), within an IterationStatement or a SwitchStatement. +negative: + phase: parse + type: SyntaxError +features: [class-static-block] +---*/ + +$DONOTEVALUATE(); + +label: while(false) { + class C { + static { + break; + } + } +} diff --git a/test/language/statements/class/static-init-abrupt.js b/test/language/statements/class/static-init-abrupt.js new file mode 100644 index 0000000000..c8270c10e7 --- /dev/null +++ b/test/language/statements/class/static-init-abrupt.js @@ -0,0 +1,46 @@ +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-class-definitions-static-semantics-early-errors +description: Returns abrupt completion and halts further class body evaluation +info: | + 34. For each element elementRecord of staticElements in List order, do + a. If elementRecord is a ClassFieldDefinition Record, then + [...] + b. Else, + i. Assert: fieldRecord is a ClassStaticBlockDefinition Record. + ii. Let status be the result of performing EvaluateStaticBlock(F, + elementRecord). + d. If status is an abrupt completion, then + i. Set the running execution context's LexicalEnvironment to lex. + ii. Set the running execution context's PrivateEnvironment to + outerPrivateEnvironment. + iii. Return Completion(status). +features: [class-static-fields-public, class-static-block] +---*/ + +var thrown = new Test262Error(); +var caught; +var sameBlock = false; +var subsequentField = false; +var subsequentBlock = false; + +try { + class C { + static { + throw thrown; + sameBlock = true; + } + static x = subsequentField = true; + static { + subsequentBlock = true; + } + } +} catch (error) { + caught = error; +} + +assert.sameValue(caught, thrown); +assert.sameValue(sameBlock, false, 'same block'); +assert.sameValue(subsequentField, false, 'subsequent field'); +assert.sameValue(subsequentBlock, false, 'subsequent block'); diff --git a/test/language/statements/class/static-init-arguments-functions.js b/test/language/statements/class/static-init-arguments-functions.js new file mode 100644 index 0000000000..19aefb2234 --- /dev/null +++ b/test/language/statements/class/static-init-arguments-functions.js @@ -0,0 +1,40 @@ +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-class-definitions-static-semantics-early-errors +description: The identifier `arguments` is not restricted within function forms +info: | + ClassStaticBlockBody : ClassStaticBlockStatementList + + - It is a Syntax Error if ContainsArguments of ClassStaticBlockStatementList + is true. +includes: [compareArray.js] +features: [class-static-block] +---*/ + +var fn, fnParam; +var gen, genParam; +var asyncFn, asyncFnParam; + +class C { + static { + (function({test262 = fnParam = arguments}) { + fn = arguments; + })('function'); + + (function * ({test262 = genParam = arguments}) { + gen = arguments; + })('generator function').next(); + + (async function ({test262 = asyncFnParam = arguments}) { + asyncFn = arguments; + })('async function'); + } +} + +assert(compareArray(['function'], fn), 'body'); +assert(compareArray(['function'], fnParam), 'parameter'); +assert(compareArray(['generator function'], gen), 'body'); +assert(compareArray(['generator function'], genParam), 'parameter'); +assert(compareArray(['async function'], asyncFn), 'body'); +assert(compareArray(['async function'], asyncFnParam), 'parameter'); diff --git a/test/language/statements/class/static-init-arguments-methods.js b/test/language/statements/class/static-init-arguments-methods.js new file mode 100644 index 0000000000..66862156d9 --- /dev/null +++ b/test/language/statements/class/static-init-arguments-methods.js @@ -0,0 +1,58 @@ +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-class-definitions-static-semantics-early-errors +description: The identifier `arguments` is not restricted within method forms +info: | + ClassStaticBlockBody : ClassStaticBlockStatementList + + - It is a Syntax Error if ContainsArguments of ClassStaticBlockStatementList + is true. +includes: [compareArray.js] +features: [class-static-block] +---*/ + +var instance; +var method, methodParam; +var getter; +var setter, setterParam; +var genMethod, genMethodParam; +var asyncMethod, asyncMethodParam; + +class C { + static { + instance = new class { + method({test262 = methodParam = arguments}) { + method = arguments; + } + get accessor() { + getter = arguments; + } + set accessor({test262 = setterParam = arguments}) { + setter = arguments; + } + *gen({test262 = genMethodParam = arguments}) { + genMethod = arguments; + } + async async({test262 = asyncMethodParam = arguments}) { + asyncMethod = arguments; + } + }(); + } +} + +instance.method('method'); +instance.accessor; +instance.accessor = 'setter'; +instance.gen('generator method').next(); +instance.async('async method'); + +assert(compareArray(['method'], method), 'body'); +assert(compareArray(['method'], methodParam), 'parameter'); +assert(compareArray([], getter), 'body'); +assert(compareArray(['setter'], setter), 'body'); +assert(compareArray(['setter'], setterParam), 'parameter'); +assert(compareArray(['generator method'], genMethod), 'body'); +assert(compareArray(['generator method'], genMethodParam), 'parameter'); +assert(compareArray(['async method'], asyncMethod), 'body'); +assert(compareArray(['async method'], asyncMethodParam), 'parameter'); diff --git a/test/language/statements/class/static-init-await-binding-invalid.js b/test/language/statements/class/static-init-await-binding-invalid.js new file mode 100644 index 0000000000..3f43b9139d --- /dev/null +++ b/test/language/statements/class/static-init-await-binding-invalid.js @@ -0,0 +1,26 @@ +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-class-definitions-static-semantics-early-errors +description: BindingIdentifier may not be `await` within class static blocks +info: | + BindingIdentifier : Identifier + + [...] + - It is a Syntax Error if the code matched by this production is nested, + directly or indirectly (but not crossing function or static initialization + block boundaries), within a ClassStaticBlock and the StringValue of + Identifier is "await". +negative: + phase: parse + type: SyntaxError +features: [class-static-block] +---*/ + +$DONOTEVALUATE(); + +class C { + static { + class await {} + } +} diff --git a/test/language/statements/class/static-init-await-binding-valid.js b/test/language/statements/class/static-init-await-binding-valid.js new file mode 100644 index 0000000000..fe10bb9c54 --- /dev/null +++ b/test/language/statements/class/static-init-await-binding-valid.js @@ -0,0 +1,18 @@ +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-class-definitions-static-semantics-early-errors +description: The `await` keyword is interpreted as an identifier within arrow function bodies +info: | + ClassStaticBlockBody : ClassStaticBlockStatementList + + [...] + - It is a Syntax Error if ContainsAwait of ClassStaticBlockStatementList is true. +features: [class-static-block] +---*/ + +class C { + static { + (() => { class await {} }); + } +} diff --git a/test/language/statements/class/static-init-expr-new-target.js b/test/language/statements/class/static-init-expr-new-target.js new file mode 100644 index 0000000000..10d3477160 --- /dev/null +++ b/test/language/statements/class/static-init-expr-new-target.js @@ -0,0 +1,23 @@ +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-operations-on-objects +description: The "new.target" value within a static initialization block is undefined +info: | + 2.1.1 EvaluateStaticBlock ( receiver , blockRecord ) + + 1. Assert: Type(receiver) is Object. + 2. Assert: blockRecord is a ClassStaticBlockDefinition Record. + 3. Perform ? Call(blockRecord.[[Body]], receiver). +features: [class-static-block] +---*/ + +var value = null; + +class C { + static { + value = new.target; + } +} + +assert.sameValue(value, undefined); diff --git a/test/language/statements/class/static-init-expr-this.js b/test/language/statements/class/static-init-expr-this.js new file mode 100644 index 0000000000..4d6f6ca295 --- /dev/null +++ b/test/language/statements/class/static-init-expr-this.js @@ -0,0 +1,23 @@ +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-operations-on-objects +description: The "this" value within a static initialization block is the class +info: | + 2.1.1 EvaluateStaticBlock ( receiver , blockRecord ) + + 1. Assert: Type(receiver) is Object. + 2. Assert: blockRecord is a ClassStaticBlockDefinition Record. + 3. Perform ? Call(blockRecord.[[Body]], receiver). +features: [class-static-block] +---*/ + +var value; + +class C { + static { + value = this; + } +} + +assert.sameValue(value, C); diff --git a/test/language/statements/class/static-init-invalid-arguments.js b/test/language/statements/class/static-init-invalid-arguments.js new file mode 100644 index 0000000000..1f791bfc3e --- /dev/null +++ b/test/language/statements/class/static-init-invalid-arguments.js @@ -0,0 +1,23 @@ +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-class-definitions-static-semantics-early-errors +description: Block cannot use `arguments` as an identifier +info: | + ClassStaticBlockBody : ClassStaticBlockStatementList + + - It is a Syntax Error if ContainsArguments of ClassStaticBlockStatementList + is true. +negative: + phase: parse + type: SyntaxError +features: [class-static-block] +---*/ + +$DONOTEVALUATE(); + +class C { + static { + (class { [argument\u0073]() {} }); + } +} diff --git a/test/language/statements/class/static-init-invalid-await.js b/test/language/statements/class/static-init-invalid-await.js new file mode 100644 index 0000000000..06e511551c --- /dev/null +++ b/test/language/statements/class/static-init-invalid-await.js @@ -0,0 +1,33 @@ +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-class-definitions +description: The "Await" parsing context does not apply to the block's statement list +info: | + Syntax + + [...] + + ClassStaticBlockStatementList : + StatementList[~Yield, +Await, ~Return]opt + + ## 15.7.1 Static Semantics: Early Errors + + ClassStaticBlockBody : ClassStaticBlockStatementList + + - It is a Syntax Error if ContainsAwait of ClassStaticBlockStatementList is true. +negative: + phase: parse + type: SyntaxError +features: [class-static-block] +---*/ + +$DONOTEVALUATE(); + +async function f() { + class C { + static { + await 0; + } + } +} diff --git a/test/language/statements/class/static-init-invalid-label-dup.js b/test/language/statements/class/static-init-invalid-label-dup.js new file mode 100644 index 0000000000..352c37ed47 --- /dev/null +++ b/test/language/statements/class/static-init-invalid-label-dup.js @@ -0,0 +1,24 @@ +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-class-definitions-static-semantics-early-errors +description: Block cannot declare duplicate labels +info: | + ClassStaticBlockBody : ClassStaticBlockStatementList + + - It is a Syntax Error if ContainsDuplicateLabels of + ClassStaticBlockStatementList with argument « » is true. +negative: + phase: parse + type: SyntaxError +features: [class-static-block] +---*/ + +$DONOTEVALUATE(); + +class C { + static { + x: x: 0; + } +} + diff --git a/test/language/statements/class/static-init-invalid-lex-dup.js b/test/language/statements/class/static-init-invalid-lex-dup.js new file mode 100644 index 0000000000..59312e49cd --- /dev/null +++ b/test/language/statements/class/static-init-invalid-lex-dup.js @@ -0,0 +1,24 @@ +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-class-definitions-static-semantics-early-errors +description: Block cannot declare duplicate lexically-scoped bindings +info: | + ClassStaticBlockBody : ClassStaticBlockStatementList + + - It is a Syntax Error if the LexicallyDeclaredNames of + ClassStaticBlockStatementList contains any duplicate entries. +negative: + phase: parse + type: SyntaxError +features: [class-static-block] +---*/ + +$DONOTEVALUATE(); + +class C { + static { + let x; + let x; + } +} diff --git a/test/language/statements/class/static-init-invalid-lex-var.js b/test/language/statements/class/static-init-invalid-lex-var.js new file mode 100644 index 0000000000..2e78d2762c --- /dev/null +++ b/test/language/statements/class/static-init-invalid-lex-var.js @@ -0,0 +1,25 @@ +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-class-definitions-static-semantics-early-errors +description: Block cannot declare a lexically-scoped binding and function-scoped binding with the same name. +info: | + ClassStaticBlockBody : ClassStaticBlockStatementList + + - It is a Syntax Error if any element of the LexicallyDeclaredNames of + ClassStaticBlockStatementList also occurs in the VarDeclaredNames of + ClassStaticBlockStatementList. +negative: + phase: parse + type: SyntaxError +features: [class-static-block] +---*/ + +$DONOTEVALUATE(); + +class C { + static { + let x; + var x; + } +} diff --git a/test/language/statements/class/static-init-invalid-return.js b/test/language/statements/class/static-init-invalid-return.js new file mode 100644 index 0000000000..dda7713132 --- /dev/null +++ b/test/language/statements/class/static-init-invalid-return.js @@ -0,0 +1,27 @@ +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-class-definitions +description: The "Return" parsing context does not apply to the block's statement list +info: | + Syntax + + [...] + + ClassStaticBlockStatementList : + StatementList[~Yield, +Await, ~Return]opt +negative: + phase: parse + type: SyntaxError +features: [class-static-block] +---*/ + +$DONOTEVALUATE(); + +function f() { + class C { + static { + return; + } + } +} diff --git a/test/language/statements/class/static-init-invalid-super-call.js b/test/language/statements/class/static-init-invalid-super-call.js new file mode 100644 index 0000000000..66e6bf136b --- /dev/null +++ b/test/language/statements/class/static-init-invalid-super-call.js @@ -0,0 +1,22 @@ +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-class-definitions-static-semantics-early-errors +description: Block cannot contain SuperCall +info: | + ClassStaticBlock : static { ClassStaticBlockBody } + + - It is a Syntax Error if HasDirectSuper of ClassStaticBlock is true. +negative: + phase: parse + type: SyntaxError +features: [class-static-block] +---*/ + +$DONOTEVALUATE(); + +class C { + static { + super(); + } +} diff --git a/test/language/statements/class/static-init-invalid-undefined-break-target.js b/test/language/statements/class/static-init-invalid-undefined-break-target.js new file mode 100644 index 0000000000..fa11b904bf --- /dev/null +++ b/test/language/statements/class/static-init-invalid-undefined-break-target.js @@ -0,0 +1,25 @@ +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-class-definitions-static-semantics-early-errors +description: Block cannot reference an undefined `break` target +info: | + ClassStaticBlockBody : ClassStaticBlockStatementList + + - It is a Syntax Error if ContainsUndefinedBreakTarget of + ClassStaticBlockStatementList with argument « » is true. +negative: + phase: parse + type: SyntaxError +features: [class-static-block] +---*/ + +$DONOTEVALUATE(); + +class C { + static { + x: while (false) { + break y; + } + } +} diff --git a/test/language/statements/class/static-init-invalid-undefined-continue-target.js b/test/language/statements/class/static-init-invalid-undefined-continue-target.js new file mode 100644 index 0000000000..389245a0e0 --- /dev/null +++ b/test/language/statements/class/static-init-invalid-undefined-continue-target.js @@ -0,0 +1,25 @@ +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-class-definitions-static-semantics-early-errors +description: Block cannot reference an undefined `continue` target +info: | + ClassStaticBlockBody : ClassStaticBlockStatementList + + - It is a Syntax Error if ContainsUndefinedContinueTarget of + ClassStaticBlockStatementList with arguments « » and « » is true. +negative: + phase: parse + type: SyntaxError +features: [class-static-block] +---*/ + +$DONOTEVALUATE(); + +class C { + static { + x: while (false) { + continue y; + } + } +} diff --git a/test/language/statements/class/static-init-invalid-yield.js b/test/language/statements/class/static-init-invalid-yield.js new file mode 100644 index 0000000000..60ab392512 --- /dev/null +++ b/test/language/statements/class/static-init-invalid-yield.js @@ -0,0 +1,27 @@ +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-class-definitions +description: The "Yield" parsing context does not apply to the block's statement list +info: | + Syntax + + [...] + + ClassStaticBlockStatementList : + StatementList[~Yield, +Await, ~Return]opt +negative: + phase: parse + type: SyntaxError +features: [class-static-block] +---*/ + +$DONOTEVALUATE(); + +function * g() { + class C { + static { + yield; + } + } +} diff --git a/test/language/statements/class/static-init-scope-lex-close.js b/test/language/statements/class/static-init-scope-lex-close.js new file mode 100644 index 0000000000..f7a21511a5 --- /dev/null +++ b/test/language/statements/class/static-init-scope-lex-close.js @@ -0,0 +1,27 @@ +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-runtime-semantics-classstaticblockdefinitionevaluation +description: Destruction of environment record for variable-scoped bindings +info: | + ClassStaticBlock : static { ClassStaticBlockBody } + + 1. Let lex be the running execution context's LexicalEnvironment. + 2. Let privateScope be the running execution context's PrivateEnvironment. + 3. Let body be OrdinaryFunctionCreate(Method, « », ClassStaticBlockBody, lex, privateScope). +features: [class-static-block] +---*/ + +var test262 = 'outer scope'; +var probe; + +class C { + static { + let test262 = 'first block'; + } + static { + probe = test262; + } +} + +assert.sameValue(probe, 'outer scope'); diff --git a/test/language/statements/class/static-init-scope-lex-derived.js b/test/language/statements/class/static-init-scope-lex-derived.js new file mode 100644 index 0000000000..664ad0990f --- /dev/null +++ b/test/language/statements/class/static-init-scope-lex-derived.js @@ -0,0 +1,23 @@ +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-runtime-semantics-classstaticblockdefinitionevaluation +description: Derivation of environment record for lexically-scoped bindings +info: | + ClassStaticBlock : static { ClassStaticBlockBody } + + 1. Let lex be the running execution context's LexicalEnvironment. + 2. Let privateScope be the running execution context's PrivateEnvironment. + 3. Let body be OrdinaryFunctionCreate(Method, « », ClassStaticBlockBody, lex, privateScope). +features: [class-static-block] +---*/ + +let probe; + +class C { + static { + probe = C; + } +} + +assert.sameValue(probe, C); diff --git a/test/language/statements/class/static-init-scope-lex-open.js b/test/language/statements/class/static-init-scope-lex-open.js new file mode 100644 index 0000000000..cc74cd5321 --- /dev/null +++ b/test/language/statements/class/static-init-scope-lex-open.js @@ -0,0 +1,31 @@ +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-runtime-semantics-classstaticblockdefinitionevaluation +description: Creation of new environment record for lexically-scoped bindings +info: | + ClassStaticBlock : static { ClassStaticBlockBody } + + 1. Let lex be the running execution context's LexicalEnvironment. + 2. Let privateScope be the running execution context's PrivateEnvironment. + 3. Let body be OrdinaryFunctionCreate(Method, « », ClassStaticBlockBody, lex, privateScope). +features: [class-static-block] +---*/ + +let test262 = 'outer scope'; +let probe1, probe2; + +class C { + static { + let test262 = 'first block'; + probe1 = test262; + } + static { + let test262 = 'second block'; + probe2 = test262; + } +} + +assert.sameValue(test262, 'outer scope'); +assert.sameValue(probe1, 'first block'); +assert.sameValue(probe2, 'second block'); diff --git a/test/language/statements/class/static-init-scope-private.js b/test/language/statements/class/static-init-scope-private.js new file mode 100644 index 0000000000..849698fb1d --- /dev/null +++ b/test/language/statements/class/static-init-scope-private.js @@ -0,0 +1,25 @@ +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-runtime-semantics-classstaticblockdefinitionevaluation +description: Shares environment record for privately-scoped bindings +info: | + ClassStaticBlock : static { ClassStaticBlockBody } + + 1. Let lex be the running execution context's LexicalEnvironment. + 2. Let privateScope be the running execution context's PrivateEnvironment. + 3. Let body be OrdinaryFunctionCreate(Method, « », ClassStaticBlockBody, lex, privateScope). +features: [class-fields-private, class-static-block] +---*/ + +var probe; + +class C { + static #test262 = 'private'; + + static { + probe = C.#test262; + } +} + +assert.sameValue(probe, 'private'); diff --git a/test/language/statements/class/static-init-scope-var-close.js b/test/language/statements/class/static-init-scope-var-close.js new file mode 100644 index 0000000000..adc4f299e4 --- /dev/null +++ b/test/language/statements/class/static-init-scope-var-close.js @@ -0,0 +1,27 @@ +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-runtime-semantics-classstaticblockdefinitionevaluation +description: Destruction of environment record for variable-scoped bindings +info: | + ClassStaticBlock : static { ClassStaticBlockBody } + + 1. Let lex be the running execution context's LexicalEnvironment. + 2. Let privateScope be the running execution context's PrivateEnvironment. + 3. Let body be OrdinaryFunctionCreate(Method, « », ClassStaticBlockBody, lex, privateScope). +features: [class-static-block] +---*/ + +var test262 = 'outer scope'; +var probe; + +class C { + static { + var test262 = 'first block'; + } + static { + probe = test262; + } +} + +assert.sameValue(probe, 'outer scope'); diff --git a/test/language/statements/class/static-init-scope-var-derived.js b/test/language/statements/class/static-init-scope-var-derived.js new file mode 100644 index 0000000000..d2cf286e59 --- /dev/null +++ b/test/language/statements/class/static-init-scope-var-derived.js @@ -0,0 +1,24 @@ +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-runtime-semantics-classstaticblockdefinitionevaluation +description: Derivation of environment record for variable-scoped bindings +info: | + ClassStaticBlock : static { ClassStaticBlockBody } + + 1. Let lex be the running execution context's LexicalEnvironment. + 2. Let privateScope be the running execution context's PrivateEnvironment. + 3. Let body be OrdinaryFunctionCreate(Method, « », ClassStaticBlockBody, lex, privateScope). +features: [class-static-block] +---*/ + +var test262 = 'outer scope'; +var probe; + +class C { + static { + probe = test262; + } +} + +assert.sameValue(probe, 'outer scope'); diff --git a/test/language/statements/class/static-init-scope-var-open.js b/test/language/statements/class/static-init-scope-var-open.js new file mode 100644 index 0000000000..b8152112c1 --- /dev/null +++ b/test/language/statements/class/static-init-scope-var-open.js @@ -0,0 +1,31 @@ +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-runtime-semantics-classstaticblockdefinitionevaluation +description: Creation of new environment record for variable-scoped bindings +info: | + ClassStaticBlock : static { ClassStaticBlockBody } + + 1. Let lex be the running execution context's LexicalEnvironment. + 2. Let privateScope be the running execution context's PrivateEnvironment. + 3. Let body be OrdinaryFunctionCreate(Method, « », ClassStaticBlockBody, lex, privateScope). +features: [class-static-block] +---*/ + +var test262 = 'outer scope'; +var probe1, probe2; + +class C { + static { + var test262 = 'first block'; + probe1 = test262; + } + static { + var test262 = 'second block'; + probe2 = test262; + } +} + +assert.sameValue(test262, 'outer scope'); +assert.sameValue(probe1, 'first block'); +assert.sameValue(probe2, 'second block'); diff --git a/test/language/statements/class/static-init-sequence.js b/test/language/statements/class/static-init-sequence.js new file mode 100644 index 0000000000..335dc9dd17 --- /dev/null +++ b/test/language/statements/class/static-init-sequence.js @@ -0,0 +1,38 @@ +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-runtime-semantics-classelementevaluation +description: Static blocks are evaluated in the order they appear in the source text, interleaved with static fields +info: | + 5.1.14 Runtime Semantics: ClassDefinitionEvaluation + + [...] + 34. For each element elementRecord of staticElements in List order, do + a. If elementRecord is a ClassFieldDefinition Record, then + i. Let status be the result of performing DefineField(F, + elementRecord). + b. Else, + i. Assert: fieldRecord is a ClassStaticBlockDefinition Record. + ii. Let status be the result of performing EvaluateStaticBlock(F, + elementRecord). + [...] +features: [class-static-fields-public, class-static-block] +---*/ + +var sequence = []; + +class C { + static x = sequence.push('first field'); + static { + sequence.push('first block'); + } + static x = sequence.push('second field'); + static { + sequence.push('second block'); + } +} + +assert.sameValue(sequence[0], 'first field'); +assert.sameValue(sequence[1], 'first block'); +assert.sameValue(sequence[2], 'second field'); +assert.sameValue(sequence[3], 'second block'); diff --git a/test/language/statements/class/static-init-statement-list-optional.js b/test/language/statements/class/static-init-statement-list-optional.js new file mode 100644 index 0000000000..038f1bf287 --- /dev/null +++ b/test/language/statements/class/static-init-statement-list-optional.js @@ -0,0 +1,18 @@ +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-class-definitions +description: The block's statement list is optional +info: | + Syntax + + [...] + + ClassStaticBlockStatementList : + StatementList[~Yield, +Await, ~Return]opt +features: [class-static-block] +---*/ + +class C { + static {} +} diff --git a/test/language/statements/class/static-init-super-property.js b/test/language/statements/class/static-init-super-property.js new file mode 100644 index 0000000000..ebfc5f6083 --- /dev/null +++ b/test/language/statements/class/static-init-super-property.js @@ -0,0 +1,24 @@ +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-runtime-semantics-classstaticblockdefinitionevaluation +description: The home object for a class static initialization block is the parent class +info: | + ClassStaticBlock : static { ClassStaticBlockBody } + + [...] + 4. Perform MakeMethod(body, homeObject). +features: [class-static-block] +---*/ + +function Parent() {} +Parent.test262 = 'test262'; +var value; + +class C extends Parent { + static { + value = super.test262; + } +} + +assert.sameValue(value, 'test262'); diff --git a/test/language/statements/const/static-init-await-binding-invalid.js b/test/language/statements/const/static-init-await-binding-invalid.js new file mode 100644 index 0000000000..f3ddd3778c --- /dev/null +++ b/test/language/statements/const/static-init-await-binding-invalid.js @@ -0,0 +1,26 @@ +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-class-definitions-static-semantics-early-errors +description: BindingIdentifier may not be `await` within class static blocks +info: | + BindingIdentifier : Identifier + + [...] + - It is a Syntax Error if the code matched by this production is nested, + directly or indirectly (but not crossing function or static initialization + block boundaries), within a ClassStaticBlock and the StringValue of + Identifier is "await". +negative: + phase: parse + type: SyntaxError +features: [class-static-block] +---*/ + +$DONOTEVALUATE(); + +class C { + static { + const await = 0; + } +} diff --git a/test/language/statements/const/static-init-await-binding-valid.js b/test/language/statements/const/static-init-await-binding-valid.js new file mode 100644 index 0000000000..6459278270 --- /dev/null +++ b/test/language/statements/const/static-init-await-binding-valid.js @@ -0,0 +1,18 @@ +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-class-definitions-static-semantics-early-errors +description: The `await` keyword is interpreted as an identifier within arrow function bodies +info: | + ClassStaticBlockBody : ClassStaticBlockStatementList + + [...] + - It is a Syntax Error if ContainsAwait of ClassStaticBlockStatementList is true. +features: [class-static-block] +---*/ + +class C { + static { + (() => { const await = 0; }); + } +} diff --git a/test/language/statements/continue/static-init-with-label.js b/test/language/statements/continue/static-init-with-label.js new file mode 100644 index 0000000000..ef9e5cc84d --- /dev/null +++ b/test/language/statements/continue/static-init-with-label.js @@ -0,0 +1,28 @@ +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-continue-statement +description: IterationStatement search does not traverse static initialization block boundaries (label specified) +info: | + 4.1.1 Static Semantics: Early Errors + ContinueStatement : continue ; + ContinueStatement : continue LabelIdentifier ; + + - It is a Syntax Error if this ContinueStatement is not nested, directly or + indirectly (but not crossing function or static initialization block + boundaries), within an IterationStatement. +negative: + phase: parse + type: SyntaxError +features: [class-static-block] +---*/ + +$DONOTEVALUATE(); + +label: while(false) { + class C { + static { + continue label; + } + } +} diff --git a/test/language/statements/continue/static-init-without-label.js b/test/language/statements/continue/static-init-without-label.js new file mode 100644 index 0000000000..ac22593153 --- /dev/null +++ b/test/language/statements/continue/static-init-without-label.js @@ -0,0 +1,28 @@ +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-continue-statement +description: IterationStatement search does not traverse static initialization block boundaries (no label specified) +info: | + 4.1.1 Static Semantics: Early Errors + ContinueStatement : continue ; + ContinueStatement : continue LabelIdentifier ; + + - It is a Syntax Error if this ContinueStatement is not nested, directly or + indirectly (but not crossing function or static initialization block + boundaries), within an IterationStatement. +negative: + phase: parse + type: SyntaxError +features: [class-static-block] +---*/ + +$DONOTEVALUATE(); + +label: while(false) { + class C { + static { + continue; + } + } +} diff --git a/test/language/statements/function/static-init-await-binding-invalid.js b/test/language/statements/function/static-init-await-binding-invalid.js new file mode 100644 index 0000000000..96c04d8f6d --- /dev/null +++ b/test/language/statements/function/static-init-await-binding-invalid.js @@ -0,0 +1,27 @@ +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-class-definitions-static-semantics-early-errors +description: BindingIdentifier may not be `await` within class static blocks +info: | + BindingIdentifier : Identifier + + [...] + - It is a Syntax Error if the code matched by this production is nested, + directly or indirectly (but not crossing function or static initialization + block boundaries), within a ClassStaticBlock and the StringValue of + Identifier is "await". +negative: + phase: parse + type: SyntaxError +features: [class-static-block] +---*/ + +$DONOTEVALUATE(); + +class C { + static { + function await() {} + } +} + diff --git a/test/language/statements/function/static-init-await-binding-valid.js b/test/language/statements/function/static-init-await-binding-valid.js new file mode 100644 index 0000000000..fb08682640 --- /dev/null +++ b/test/language/statements/function/static-init-await-binding-valid.js @@ -0,0 +1,18 @@ +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-class-definitions-static-semantics-early-errors +description: The `await` keyword is interpreted as an identifier within arrow function bodies +info: | + ClassStaticBlockBody : ClassStaticBlockStatementList + + [...] + - It is a Syntax Error if ContainsAwait of ClassStaticBlockStatementList is true. +features: [class-static-block] +---*/ + +class C { + static { + (() => { function await() {} }); + } +} diff --git a/test/language/statements/labeled/static-init-invalid-await.js b/test/language/statements/labeled/static-init-invalid-await.js new file mode 100644 index 0000000000..e6b38ae742 --- /dev/null +++ b/test/language/statements/labeled/static-init-invalid-await.js @@ -0,0 +1,25 @@ +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-class-definitions-static-semantics-early-errors +description: Restriction on `await` +info: | + LabelIdentifier : Identifier + + - It is a Syntax Error if the code matched by this production is nested, + directly or indirectly (but not crossing function or static initialization + block boundaries), within a ClassStaticBlock and the StringValue of + Identifier is "await". +negative: + phase: parse + type: SyntaxError +features: [class-static-block] +---*/ + +$DONOTEVALUATE(); + +class C { + static { + await: 0; + } +} diff --git a/test/language/statements/let/static-init-await-binding-invalid.js b/test/language/statements/let/static-init-await-binding-invalid.js new file mode 100644 index 0000000000..0bff5e1869 --- /dev/null +++ b/test/language/statements/let/static-init-await-binding-invalid.js @@ -0,0 +1,26 @@ +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-class-definitions-static-semantics-early-errors +description: BindingIdentifier may not be `await` within class static blocks +info: | + BindingIdentifier : Identifier + + [...] + - It is a Syntax Error if the code matched by this production is nested, + directly or indirectly (but not crossing function or static initialization + block boundaries), within a ClassStaticBlock and the StringValue of + Identifier is "await". +negative: + phase: parse + type: SyntaxError +features: [class-static-block] +---*/ + +$DONOTEVALUATE(); + +class C { + static { + let await; + } +} diff --git a/test/language/statements/let/static-init-await-binding-valid.js b/test/language/statements/let/static-init-await-binding-valid.js new file mode 100644 index 0000000000..95789d6263 --- /dev/null +++ b/test/language/statements/let/static-init-await-binding-valid.js @@ -0,0 +1,18 @@ +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-class-definitions-static-semantics-early-errors +description: The `await` keyword is interpreted as an identifier within arrow function bodies +info: | + ClassStaticBlockBody : ClassStaticBlockStatementList + + [...] + - It is a Syntax Error if ContainsAwait of ClassStaticBlockStatementList is true. +features: [class-static-block] +---*/ + +class C { + static { + (() => { let await; }); + } +} diff --git a/test/language/statements/try/static-init-await-binding-invalid.js b/test/language/statements/try/static-init-await-binding-invalid.js new file mode 100644 index 0000000000..32faff64a6 --- /dev/null +++ b/test/language/statements/try/static-init-await-binding-invalid.js @@ -0,0 +1,26 @@ +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-class-definitions-static-semantics-early-errors +description: BindingIdentifier may not be `await` within class static blocks +info: | + BindingIdentifier : Identifier + + [...] + - It is a Syntax Error if the code matched by this production is nested, + directly or indirectly (but not crossing function or static initialization + block boundaries), within a ClassStaticBlock and the StringValue of + Identifier is "await". +negative: + phase: parse + type: SyntaxError +features: [class-static-block] +---*/ + +$DONOTEVALUATE(); + +class C { + static { + try {} catch (await) {} + } +} diff --git a/test/language/statements/try/static-init-await-binding-valid.js b/test/language/statements/try/static-init-await-binding-valid.js new file mode 100644 index 0000000000..e72b12d143 --- /dev/null +++ b/test/language/statements/try/static-init-await-binding-valid.js @@ -0,0 +1,18 @@ +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-class-definitions-static-semantics-early-errors +description: The `await` keyword is interpreted as an identifier within arrow function bodies +info: | + ClassStaticBlockBody : ClassStaticBlockStatementList + + [...] + - It is a Syntax Error if ContainsAwait of ClassStaticBlockStatementList is true. +features: [class-static-block] +---*/ + +class C { + static { + (() => { try {} catch (await) {} }); + } +} diff --git a/test/language/statements/variable/dstr/ary-ptrn-elem-id-static-init-await-invalid.js b/test/language/statements/variable/dstr/ary-ptrn-elem-id-static-init-await-invalid.js new file mode 100644 index 0000000000..685732720d --- /dev/null +++ b/test/language/statements/variable/dstr/ary-ptrn-elem-id-static-init-await-invalid.js @@ -0,0 +1,26 @@ +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-class-definitions-static-semantics-early-errors +description: BindingIdentifier may not be `await` within class static blocks +info: | + BindingIdentifier : Identifier + + [...] + - It is a Syntax Error if the code matched by this production is nested, + directly or indirectly (but not crossing function or static initialization + block boundaries), within a ClassStaticBlock and the StringValue of + Identifier is "await". +negative: + phase: parse + type: SyntaxError +features: [class-static-block] +---*/ + +$DONOTEVALUATE(); + +class C { + static { + var [await] = []; + } +} diff --git a/test/language/statements/variable/dstr/ary-ptrn-elem-id-static-init-await-valid.js b/test/language/statements/variable/dstr/ary-ptrn-elem-id-static-init-await-valid.js new file mode 100644 index 0000000000..d6f2c5d93e --- /dev/null +++ b/test/language/statements/variable/dstr/ary-ptrn-elem-id-static-init-await-valid.js @@ -0,0 +1,18 @@ +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-class-definitions-static-semantics-early-errors +description: The `await` keyword is interpreted as an identifier within arrow function bodies +info: | + ClassStaticBlockBody : ClassStaticBlockStatementList + + [...] + - It is a Syntax Error if ContainsAwait of ClassStaticBlockStatementList is true. +features: [class-static-block] +---*/ + +class C { + static { + (() => { var [await] = []; }); + } +} diff --git a/test/language/statements/variable/dstr/obj-ptrn-elem-id-static-init-await-invalid.js b/test/language/statements/variable/dstr/obj-ptrn-elem-id-static-init-await-invalid.js new file mode 100644 index 0000000000..377791ab94 --- /dev/null +++ b/test/language/statements/variable/dstr/obj-ptrn-elem-id-static-init-await-invalid.js @@ -0,0 +1,26 @@ +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-class-definitions-static-semantics-early-errors +description: BindingIdentifier may not be `await` within class static blocks +info: | + BindingIdentifier : Identifier + + [...] + - It is a Syntax Error if the code matched by this production is nested, + directly or indirectly (but not crossing function or static initialization + block boundaries), within a ClassStaticBlock and the StringValue of + Identifier is "await". +negative: + phase: parse + type: SyntaxError +features: [class-static-block] +---*/ + +$DONOTEVALUATE(); + +class C { + static { + var {await} = {}; + } +} diff --git a/test/language/statements/variable/dstr/obj-ptrn-elem-id-static-init-await-valid.js b/test/language/statements/variable/dstr/obj-ptrn-elem-id-static-init-await-valid.js new file mode 100644 index 0000000000..f71e056790 --- /dev/null +++ b/test/language/statements/variable/dstr/obj-ptrn-elem-id-static-init-await-valid.js @@ -0,0 +1,18 @@ +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-class-definitions-static-semantics-early-errors +description: The `await` keyword is interpreted as an identifier within arrow function bodies +info: | + ClassStaticBlockBody : ClassStaticBlockStatementList + + [...] + - It is a Syntax Error if ContainsAwait of ClassStaticBlockStatementList is true. +features: [class-static-block] +---*/ + +class C { + static { + (() => { var {await} = {}; }); + } +} diff --git a/test/language/statements/variable/static-init-await-binding-invalid.js b/test/language/statements/variable/static-init-await-binding-invalid.js new file mode 100644 index 0000000000..b6319b0009 --- /dev/null +++ b/test/language/statements/variable/static-init-await-binding-invalid.js @@ -0,0 +1,26 @@ +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-class-definitions-static-semantics-early-errors +description: BindingIdentifier may not be `await` within class static blocks +info: | + BindingIdentifier : Identifier + + [...] + - It is a Syntax Error if the code matched by this production is nested, + directly or indirectly (but not crossing function or static initialization + block boundaries), within a ClassStaticBlock and the StringValue of + Identifier is "await". +negative: + phase: parse + type: SyntaxError +features: [class-static-block] +---*/ + +$DONOTEVALUATE(); + +class C { + static { + var await; + } +} diff --git a/test/language/statements/variable/static-init-await-binding-valid.js b/test/language/statements/variable/static-init-await-binding-valid.js new file mode 100644 index 0000000000..eef43047c3 --- /dev/null +++ b/test/language/statements/variable/static-init-await-binding-valid.js @@ -0,0 +1,18 @@ +// Copyright (C) 2021 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-class-definitions-static-semantics-early-errors +description: The `await` keyword is interpreted as an identifier within arrow function bodies +info: | + ClassStaticBlockBody : ClassStaticBlockStatementList + + [...] + - It is a Syntax Error if ContainsAwait of ClassStaticBlockStatementList is true. +features: [class-static-block] +---*/ + +class C { + static { + (() => { var await; }); + } +}