Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Copyright (C) 2026 hexbinoct. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
desc: SyntaxError for a getter whose name is on the next line and that has no parameter list
info: |
ClassElement :
MethodDefinition
static MethodDefinition
FieldDefinition ;
;

MethodDefinition :
get ClassElementName ( ) { FunctionBody }

FieldDefinition :
ClassElementName Initializer _opt

The name after "get" is allowed by the getter production, so no semicolon is
inserted after "get", and the getter is missing its parameter list.

template: syntax/invalid
features: [class-fields-public]
---*/

//- elements
get
x
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// This file was procedurally generated from the following sources:
// - src/class-elements/grammar-get-followed-by-name-on-next-line-without-parameters-error.case
// - src/class-elements/syntax/invalid/cls-expr-elements-invalid-syntax.template
/*---
description: SyntaxError for a getter whose name is on the next line and that has no parameter list (class expression)
esid: prod-ClassElement
features: [class-fields-public, class]
flags: [generated]
negative:
phase: parse
type: SyntaxError
info: |
ClassElement :
MethodDefinition
static MethodDefinition
FieldDefinition ;
;

MethodDefinition :
get ClassElementName ( ) { FunctionBody }

FieldDefinition :
ClassElementName Initializer _opt

The name after "get" is allowed by the getter production, so no semicolon is
inserted after "get", and the getter is missing its parameter list.

---*/


$DONOTEVALUATE();

var C = class {
get
x
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// This file was procedurally generated from the following sources:
// - src/class-elements/grammar-get-followed-by-name-on-next-line-without-parameters-error.case
// - src/class-elements/syntax/invalid/cls-decl-elements-invalid-syntax.template
/*---
description: SyntaxError for a getter whose name is on the next line and that has no parameter list (class declaration)
esid: prod-ClassElement
features: [class-fields-public, class]
flags: [generated]
negative:
phase: parse
type: SyntaxError
info: |
ClassElement :
MethodDefinition
static MethodDefinition
FieldDefinition ;
;

MethodDefinition :
get ClassElementName ( ) { FunctionBody }

FieldDefinition :
ClassElementName Initializer _opt

The name after "get" is allowed by the getter production, so no semicolon is
inserted after "get", and the getter is missing its parameter list.

---*/


$DONOTEVALUATE();

class C {
get
x
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// Copyright (C) 2026 hexbinoct. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: A line terminator between "get" and the name does not end a field named "get"
esid: prod-ClassElement
features: [class, class-methods-private]
info: |
ClassElement :
MethodDefinition
static MethodDefinition
FieldDefinition ;
static FieldDefinition ;
;

MethodDefinition :
get ClassElementName ( ) { FunctionBody }

FieldDefinition :
ClassElementName Initializer _opt

The getter production has no [no LineTerminator here] restriction, so the
name on the next line is allowed and no semicolon is inserted after "get".
---*/

class A {
get
a() { return "a"; }
}

class B {
static get
b() { return "b"; }
}

class C {
get
["c"]() { return "c"; }
}

class D {
get
#d() { return "d"; }
read() { return this.#d; }
}

var a = new A();
assert.sameValue(typeof Object.getOwnPropertyDescriptor(A.prototype, "a").get, "function", "(A) a is a getter on the prototype");
assert.sameValue(a.a, "a", "(A) the getter returns its value");
assert.sameValue(Object.prototype.hasOwnProperty.call(a, "get"), false, "(A) there is no field named get");

assert.sameValue(typeof Object.getOwnPropertyDescriptor(B, "b").get, "function", "(B) b is a static getter");
assert.sameValue(B.b, "b", "(B) the static getter returns its value");
assert.sameValue(Object.prototype.hasOwnProperty.call(B, "get"), false, "(B) there is no static field named get");

var c = new C();
assert.sameValue(typeof Object.getOwnPropertyDescriptor(C.prototype, "c").get, "function", "(C) c is a getter on the prototype");
assert.sameValue(c.c, "c", "(C) the getter returns its value");
assert.sameValue(Object.prototype.hasOwnProperty.call(c, "get"), false, "(C) there is no field named get");

var d = new D();
assert.sameValue(d.read(), "d", "(D) #d is a private getter");
assert.sameValue(Object.prototype.hasOwnProperty.call(d, "get"), false, "(D) there is no field named get");
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// Copyright (C) 2026 hexbinoct. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: A line terminator between a method name and its parameters does not end a field
esid: prod-ClassElement
features: [class]
info: |
ClassElement :
MethodDefinition
FieldDefinition ;
;

MethodDefinition :
ClassElementName ( UniqueFormalParameters ) { FunctionBody }

FieldDefinition :
ClassElementName Initializer _opt

A "(" after a ClassElementName is allowed by MethodDefinition, so no
semicolon is inserted before it, even after a line terminator.
---*/

class A {
m
() { return "m"; }

get
() { return "get"; }

set
(v) { return "set" + v; }
}

var a = new A();
assert.sameValue(a.m(), "m", "m is a method on the prototype");
assert.sameValue(a.get(), "get", "get is a method on the prototype");
assert.sameValue(a.set(1), "set1", "set is a method on the prototype");
assert.sameValue(Object.prototype.hasOwnProperty.call(a, "m"), false, "there is no field named m");
assert.sameValue(Object.prototype.hasOwnProperty.call(a, "get"), false, "there is no field named get");
assert.sameValue(Object.prototype.hasOwnProperty.call(a, "set"), false, "there is no field named set");
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// Copyright (C) 2026 hexbinoct. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: A method can be named "static", with or without the static modifier
esid: prod-ClassElement
features: [class]
info: |
ClassElement :
MethodDefinition
static MethodDefinition
FieldDefinition ;
static FieldDefinition ;
;

MethodDefinition :
ClassElementName ( UniqueFormalParameters ) { FunctionBody }

ClassElementName :
PropertyName

"static" is an IdentifierName, so it can be the name of a method. A "("
after it, on the same line or the next, continues that method definition.
---*/

class A {
static() { return "prototype"; }
static static() { return "constructor"; }
}

class B {
static
() { return "next line"; }
}

assert.sameValue(A.prototype.static(), "prototype", "(A) static is a method on the prototype");
assert.sameValue(A.static(), "constructor", "(A) static is also a static method");
assert.sameValue(new B().static(), "next line", "(B) static is a method on the prototype");
assert.sameValue(Object.prototype.hasOwnProperty.call(B, "static"), false, "(B) static is not a static method");
assert.sameValue(Object.prototype.hasOwnProperty.call(new B(), "static"), false, "(B) there is no field named static");
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// Copyright (C) 2026 hexbinoct. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: A line terminator between "set" and the name does not end a field named "set"
esid: prod-ClassElement
features: [class, class-methods-private]
info: |
ClassElement :
MethodDefinition
static MethodDefinition
FieldDefinition ;
static FieldDefinition ;
;

MethodDefinition :
set ClassElementName ( PropertySetParameterList ) { FunctionBody }

FieldDefinition :
ClassElementName Initializer _opt

The setter production has no [no LineTerminator here] restriction, so the
name on the next line is allowed and no semicolon is inserted after "set".
---*/

var stored;

class A {
set
a(v) { stored = "a" + v; }
}

class B {
static set
b(v) { stored = "b" + v; }
}

class C {
set
["c"](v) { stored = "c" + v; }
}

class D {
set
#d(v) { stored = "d" + v; }
write(v) { this.#d = v; }
}

var a = new A();
assert.sameValue(typeof Object.getOwnPropertyDescriptor(A.prototype, "a").set, "function", "(A) a is a setter on the prototype");
a.a = 1;
assert.sameValue(stored, "a1", "(A) the setter is called");
assert.sameValue(Object.prototype.hasOwnProperty.call(a, "set"), false, "(A) there is no field named set");

assert.sameValue(typeof Object.getOwnPropertyDescriptor(B, "b").set, "function", "(B) b is a static setter");
B.b = 2;
assert.sameValue(stored, "b2", "(B) the static setter is called");
assert.sameValue(Object.prototype.hasOwnProperty.call(B, "set"), false, "(B) there is no static field named set");

var c = new C();
assert.sameValue(typeof Object.getOwnPropertyDescriptor(C.prototype, "c").set, "function", "(C) c is a setter on the prototype");
c.c = 3;
assert.sameValue(stored, "c3", "(C) the setter is called");
assert.sameValue(Object.prototype.hasOwnProperty.call(c, "set"), false, "(C) there is no field named set");

var d = new D();
d.write(4);
assert.sameValue(stored, "d4", "(D) #d is a private setter");
assert.sameValue(Object.prototype.hasOwnProperty.call(d, "set"), false, "(D) there is no field named set");
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// Copyright (C) 2026 hexbinoct. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: A line terminator after "static" does not end a field named "static" when a field name follows
esid: prod-ClassElement
features: [class, class-static-fields-public]
info: |
ClassElement :
MethodDefinition
static MethodDefinition
FieldDefinition ;
static FieldDefinition ;
;

FieldDefinition :
ClassElementName Initializer _opt

The "static" FieldDefinition production has no [no LineTerminator here]
restriction, so a field name on the next line is allowed and no semicolon is
inserted after "static".
---*/

class A {
static
x = 1;

static
y
}

assert.sameValue(A.x, 1, "x is a static field");
assert.sameValue(Object.prototype.hasOwnProperty.call(A, "y"), true, "y is a static field");
assert.sameValue(A.y, undefined, "y has no initializer");

var a = new A();
assert.sameValue(Object.prototype.hasOwnProperty.call(a, "static"), false, "there is no field named static");
assert.sameValue(Object.prototype.hasOwnProperty.call(a, "x"), false, "x is not an instance field");
assert.sameValue(Object.prototype.hasOwnProperty.call(a, "y"), false, "y is not an instance field");
Loading
Loading