diff --git a/src/parser/class.js b/src/parser/class.js index fad28269a..8676ce25d 100644 --- a/src/parser/class.js +++ b/src/parser/class.js @@ -119,6 +119,7 @@ module.exports = { this.raiseError("Cannot use asymmetric visibility on constants"); } const constants = this.read_constant_list(flags, attrs, locStart); + attrs = []; if (this.expect(";")) { this.next(); } diff --git a/src/parser/statement.js b/src/parser/statement.js index 4bdb56177..0d15d8652 100644 --- a/src/parser/statement.js +++ b/src/parser/statement.js @@ -171,10 +171,11 @@ module.exports = { // optional flags case this.tok.T_ABSTRACT: case this.tok.T_FINAL: + case this.tok.T_READ_ONLY: case this.tok.T_CLASS: - return this.read_class_declaration_statement(); + return this.read_class_declaration_statement(attrs); case this.tok.T_INTERFACE: - return this.read_interface_declaration_statement(); + return this.read_interface_declaration_statement(attrs); case this.tok.T_TRAIT: return this.read_trait_declaration_statement(attrs); case this.tok.T_ENUM: diff --git a/test/snapshot/__snapshots__/location.test.js.snap b/test/snapshot/__snapshots__/location.test.js.snap index c76790e11..891454f18 100644 --- a/test/snapshot/__snapshots__/location.test.js.snap +++ b/test/snapshot/__snapshots__/location.test.js.snap @@ -4180,44 +4180,7 @@ Program { }, "properties": [ Property { - "attrGroups": [ - AttrGroup { - "attrs": [ - Attribute { - "args": [], - "kind": "attribute", - "loc": Location { - "end": Position { - "column": 22, - "line": 1, - "offset": 22, - }, - "source": "Deprecated", - "start": Position { - "column": 12, - "line": 1, - "offset": 12, - }, - }, - "name": "Deprecated", - }, - ], - "kind": "attrgroup", - "loc": Location { - "end": Position { - "column": 23, - "line": 1, - "offset": 23, - }, - "source": "#[Deprecated]", - "start": Position { - "column": 10, - "line": 1, - "offset": 10, - }, - }, - }, - ], + "attrGroups": [], "hooks": [], "kind": "property", "loc": Location { diff --git a/test/snapshot/attributes.test.js b/test/snapshot/attributes.test.js index 6f71e9e66..b52b1cef7 100644 --- a/test/snapshot/attributes.test.js +++ b/test/snapshot/attributes.test.js @@ -266,6 +266,49 @@ describe("Parse Attributes", () => { ).toMatchSnapshot(); }); + it("doesnt repeat attributes from a previous class constant", () => { + const ast = parser.parseEval(` + class A { + #[B] + const C = 1; + const D = 2; + public $e; + function f() {} + } + `); + const [c, d, e, f] = ast.children[0].body; + expect(c.attrGroups).toHaveLength(1); + expect(d.attrGroups).toEqual([]); + expect(e.properties[0].attrGroups).toEqual([]); + expect(f.attrGroups).toEqual([]); + }); + + it("can parse attributes on declarations in inner statements", () => { + const ast = parser.parseEval(` + if (true) { + #[A] + class B {} + #[C] + final class D {} + #[E] + interface F {} + #[G] + readonly class H {} + } + `); + expect( + ast.children[0].body.children.map((node) => [ + node.kind, + node.attrGroups.map((group) => group.attrs[0].name), + ]), + ).toEqual([ + ["class", ["A"]], + ["class", ["C"]], + ["interface", ["E"]], + ["class", ["G"]], + ]); + }); + it("parses attributes as comments for PHP < 8", () => { expect( parser.parseEval(