diff --git a/src/ast/classconstant.js b/src/ast/classconstant.js index bea667188..c1ef5c267 100644 --- a/src/ast/classconstant.js +++ b/src/ast/classconstant.js @@ -20,26 +20,13 @@ const IS_PRIVATE = "private"; * @extends {ConstantStatement} * @property {string} visibility * @property {boolean} final - * @property {boolean} nullable - * @property {TypeReference|IntersectionType|UnionType|null} type * @property {AttrGroup[]} attrGroups */ const ClassConstant = ConstantStatement.extends( KIND, - function ClassConstant( - kind, - constants, - flags, - nullable, - type, - attrGroups, - docs, - location, - ) { + function ClassConstant(kind, constants, flags, attrGroups, docs, location) { ConstantStatement.apply(this, [kind || KIND, constants, docs, location]); this.parseFlags(flags); - this.nullable = nullable; - this.type = type; this.attrGroups = attrGroups; }, ); diff --git a/src/ast/constant.js b/src/ast/constant.js index 698a7b14e..478f5e8dc 100644 --- a/src/ast/constant.js +++ b/src/ast/constant.js @@ -15,12 +15,16 @@ const KIND = "constant"; * @extends {Node} * @property {string} name * @property {Node|string|number|boolean|null} value + * @property {boolean} nullable + * @property {TypeReference|IntersectionType|UnionType|null} type */ module.exports = Node.extends( KIND, - function Constant(name, value, docs, location) { + function Constant(name, value, nullable, type, docs, location) { Node.apply(this, [KIND, docs, location]); this.name = name; this.value = value; + this.nullable = nullable; + this.type = type; }, ); diff --git a/src/parser/class.js b/src/parser/class.js index 996f5acf3..1fa5d6d50 100644 --- a/src/parser/class.js +++ b/src/parser/class.js @@ -234,10 +234,7 @@ module.exports = { this.next(); } - const [nullable, type] = - this.version >= 830 ? this.read_optional_type() : [false, null]; - - const result = this.node("classconstant"); + const class_constant_node = this.node("classconstant"); const items = this.read_list( /* * Reads a constant declaration @@ -248,29 +245,33 @@ module.exports = { * @return {Constant} [:link:](AST.md#constant) */ function read_constant_declaration() { - const result = this.node("constant"); - let constName = null; + const constant_node = this.node("constant"); + + // eslint-disable-next-line prefer-const + let [nullable, type] = this.read_optional_type(); + let propName = this.node("identifier"); let value = null; - if ( - this.token === this.tok.T_STRING || - (this.version >= 700 && this.is("IDENTIFIER")) - ) { - constName = this.node("identifier"); - const name = this.text(); - this.next(); - constName = constName(name); + + if (type && type.kind === "name") { + propName = propName(type.name); + type = null; } else { - this.expect("IDENTIFIER"); + propName = propName(this.text()); + this.next(); } - if (this.expect("=")) { - value = this.next().read_expr(); + this.expect("="); + value = this.next().read_expr(); + + if (this.version < 803 && type !== null) { + this.raiseError( + "Parse Error: Typed Class Constants requires PHP 8.3+", + ); } - return result(constName, value); + return constant_node(propName, value, nullable, type); }, ",", ); - - return result(null, items, flags, nullable, type, attrs || []); + return class_constant_node(null, items, flags, attrs || []); }, /* * Read member flags diff --git a/test/snapshot/__snapshots__/acid.test.js.snap b/test/snapshot/__snapshots__/acid.test.js.snap index 66955f4bb..b0b278e2c 100644 --- a/test/snapshot/__snapshots__/acid.test.js.snap +++ b/test/snapshot/__snapshots__/acid.test.js.snap @@ -426,19 +426,6 @@ Program { "constants": [ Constant { "kind": "constant", - "loc": Location { - "end": Position { - "column": 28, - "line": 20, - "offset": 360, - }, - "source": "FOOBAR = 'foo & bar'", - "start": Position { - "column": 8, - "line": 20, - "offset": 340, - }, - }, "name": Identifier { "kind": "identifier", "loc": Location { @@ -456,6 +443,20 @@ Program { }, "name": "FOOBAR", }, + "nullable": null, + "type": Location { + "end": Position { + "column": 28, + "line": 20, + "offset": 360, + }, + "source": "FOOBAR = 'foo & bar'", + "start": Position { + "column": 8, + "line": 20, + "offset": 340, + }, + }, "value": String { "isDoubleQuote": false, "kind": "string", @@ -780,15 +781,17 @@ Program { "line": 31, "offset": 550, }, - "source": "FOOBAR", + "source": " ", "start": Position { - "column": 10, + "column": 17, "line": 31, - "offset": 544, + "offset": 551, }, }, "name": "FOOBAR", }, + "nullable": false, + "type": null, "value": String { "isDoubleQuote": false, "kind": "string", @@ -826,8 +829,6 @@ Program { "offset": 544, }, }, - "nullable": false, - "type": null, "visibility": "", }, PropertyStatement { diff --git a/test/snapshot/__snapshots__/ast.test.js.snap b/test/snapshot/__snapshots__/ast.test.js.snap index 91208a884..8e42b7e19 100644 --- a/test/snapshot/__snapshots__/ast.test.js.snap +++ b/test/snapshot/__snapshots__/ast.test.js.snap @@ -253,6 +253,8 @@ Program { "kind": "identifier", "name": "FOO", }, + "nullable": null, + "type": undefined, "value": Number { "kind": "number", "value": "3.14", diff --git a/test/snapshot/__snapshots__/attributes.test.js.snap b/test/snapshot/__snapshots__/attributes.test.js.snap index 36fb1d4f0..86d540a1f 100644 --- a/test/snapshot/__snapshots__/attributes.test.js.snap +++ b/test/snapshot/__snapshots__/attributes.test.js.snap @@ -327,6 +327,8 @@ Program { "kind": "identifier", "name": "B", }, + "nullable": false, + "type": null, "value": Number { "kind": "number", "value": "1", @@ -335,8 +337,6 @@ Program { ], "final": false, "kind": "classconstant", - "nullable": false, - "type": null, "visibility": "", }, ], @@ -518,6 +518,8 @@ Program { "kind": "identifier", "name": "D", }, + "nullable": false, + "type": null, "value": Number { "kind": "number", "value": "0", @@ -526,8 +528,6 @@ Program { ], "final": false, "kind": "classconstant", - "nullable": false, - "type": null, "visibility": "", }, Method { diff --git a/test/snapshot/__snapshots__/class.test.js.snap b/test/snapshot/__snapshots__/class.test.js.snap index 6fd21a3aa..eaa81168a 100644 --- a/test/snapshot/__snapshots__/class.test.js.snap +++ b/test/snapshot/__snapshots__/class.test.js.snap @@ -156,6 +156,8 @@ Program { "kind": "identifier", "name": "A", }, + "nullable": false, + "type": null, "value": Number { "kind": "number", "value": "1.5", @@ -172,8 +174,6 @@ Program { ", }, ], - "nullable": false, - "type": null, "visibility": "", }, Method { @@ -226,6 +226,8 @@ Program { "kind": "identifier", "name": "A", }, + "nullable": false, + "type": null, "value": Number { "kind": "number", "value": "1.5", @@ -242,8 +244,6 @@ Program { ", }, ], - "nullable": false, - "type": null, "visibility": "", }, Method { @@ -1331,6 +1331,8 @@ Program { "kind": "identifier", "name": "FOO", }, + "nullable": false, + "type": null, "value": String { "isDoubleQuote": true, "kind": "string", @@ -1342,8 +1344,6 @@ Program { ], "final": false, "kind": "classconstant", - "nullable": false, - "type": null, "visibility": "", }, PropertyStatement { @@ -1443,6 +1443,8 @@ Program { "kind": "identifier", "name": "list", }, + "nullable": false, + "type": null, "value": String { "isDoubleQuote": true, "kind": "string", @@ -1454,8 +1456,6 @@ Program { ], "final": false, "kind": "classconstant", - "nullable": false, - "type": null, "visibility": "", }, Method { diff --git a/test/snapshot/__snapshots__/classconstant.test.js.snap b/test/snapshot/__snapshots__/classconstant.test.js.snap index 1c41d95b9..c3e4fa7fe 100644 --- a/test/snapshot/__snapshots__/classconstant.test.js.snap +++ b/test/snapshot/__snapshots__/classconstant.test.js.snap @@ -1,5 +1,54 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`classconstant accept the constant name 'list' 1`] = ` +Program { + "children": [ + Class { + "attrGroups": [], + "body": [ + ClassConstant { + "attrGroups": [], + "constants": [ + Constant { + "kind": "constant", + "name": Identifier { + "kind": "identifier", + "name": "list", + }, + "nullable": false, + "type": null, + "value": String { + "isDoubleQuote": true, + "kind": "string", + "raw": ""Hello world!"", + "unicode": false, + "value": "Hello world!", + }, + }, + ], + "final": false, + "kind": "classconstant", + "visibility": "", + }, + ], + "extends": null, + "implements": null, + "isAbstract": false, + "isAnonymous": false, + "isFinal": false, + "isReadonly": false, + "kind": "class", + "name": Identifier { + "kind": "identifier", + "name": "Foo", + }, + }, + ], + "errors": [], + "kind": "program", +} +`; + exports[`classconstant final 1`] = ` Program { "children": [ @@ -15,6 +64,8 @@ Program { "kind": "identifier", "name": "CONSTANT", }, + "nullable": false, + "type": null, "value": String { "isDoubleQuote": true, "kind": "string", @@ -26,8 +77,6 @@ Program { ], "final": true, "kind": "classconstant", - "nullable": false, - "type": null, "visibility": "public", }, ], @@ -64,6 +113,8 @@ Program { "kind": "identifier", "name": "CONSTANT", }, + "nullable": false, + "type": null, "value": String { "isDoubleQuote": true, "kind": "string", @@ -78,6 +129,8 @@ Program { "kind": "identifier", "name": "OTHER_CONSTANT", }, + "nullable": false, + "type": null, "value": String { "isDoubleQuote": true, "kind": "string", @@ -89,8 +142,6 @@ Program { ], "final": false, "kind": "classconstant", - "nullable": false, - "type": null, "visibility": "", }, ], @@ -127,6 +178,8 @@ Program { "kind": "identifier", "name": "CONSTANT", }, + "nullable": false, + "type": null, "value": String { "isDoubleQuote": true, "kind": "string", @@ -138,8 +191,6 @@ Program { ], "final": false, "kind": "classconstant", - "nullable": false, - "type": null, "visibility": "private", }, ], @@ -176,6 +227,8 @@ Program { "kind": "identifier", "name": "CONSTANT", }, + "nullable": false, + "type": null, "value": String { "isDoubleQuote": true, "kind": "string", @@ -187,8 +240,6 @@ Program { ], "final": false, "kind": "classconstant", - "nullable": false, - "type": null, "visibility": "protected", }, ], @@ -225,6 +276,8 @@ Program { "kind": "identifier", "name": "CONSTANT", }, + "nullable": false, + "type": null, "value": String { "isDoubleQuote": true, "kind": "string", @@ -236,8 +289,6 @@ Program { ], "final": false, "kind": "classconstant", - "nullable": false, - "type": null, "visibility": "public", }, ], @@ -274,6 +325,8 @@ Program { "kind": "identifier", "name": "CONSTANT", }, + "nullable": false, + "type": null, "value": String { "isDoubleQuote": true, "kind": "string", @@ -285,8 +338,6 @@ Program { ], "final": false, "kind": "classconstant", - "nullable": false, - "type": null, "visibility": "", }, ], @@ -321,7 +372,128 @@ Program { "kind": "constant", "name": Identifier { "kind": "identifier", - "name": "CONSTANT", + "name": "CON_1", + }, + "nullable": false, + "type": null, + "value": String { + "isDoubleQuote": true, + "kind": "string", + "raw": ""Hello world!"", + "unicode": false, + "value": "Hello world!", + }, + }, + ], + "final": false, + "kind": "classconstant", + "visibility": "public", + }, + ClassConstant { + "attrGroups": [], + "constants": [ + Constant { + "kind": "constant", + "name": Identifier { + "kind": "identifier", + "name": "CON_2", + }, + "nullable": false, + "type": null, + "value": String { + "isDoubleQuote": true, + "kind": "string", + "raw": ""Hello world!"", + "unicode": false, + "value": "Hello world!", + }, + }, + ], + "final": false, + "kind": "classconstant", + "visibility": "", + }, + ClassConstant { + "attrGroups": [], + "constants": [ + Constant { + "kind": "constant", + "name": Identifier { + "kind": "identifier", + "name": "CON_3", + }, + "nullable": false, + "type": TypeReference { + "kind": "typereference", + "name": "string", + "raw": "string", + }, + "value": String { + "isDoubleQuote": true, + "kind": "string", + "raw": ""Hello world!"", + "unicode": false, + "value": "Hello world!", + }, + }, + ], + "final": false, + "kind": "classconstant", + "visibility": "", + }, + ClassConstant { + "attrGroups": [], + "constants": [ + Constant { + "kind": "constant", + "name": Identifier { + "kind": "identifier", + "name": "CON_4", + }, + "nullable": false, + "type": TypeReference { + "kind": "typereference", + "name": "string", + "raw": "string", + }, + "value": String { + "isDoubleQuote": true, + "kind": "string", + "raw": ""Hello world!"", + "unicode": false, + "value": "Hello world!", + }, + }, + ], + "final": false, + "kind": "classconstant", + "visibility": "public", + }, + ClassConstant { + "attrGroups": [], + "constants": [ + Constant { + "kind": "constant", + "name": Identifier { + "kind": "identifier", + "name": "CON_5", + }, + "nullable": false, + "type": UnionType { + "kind": "uniontype", + "name": null, + "types": [ + TypeReference { + "kind": "typereference", + "name": "string", + "raw": "string", + }, + TypeReference { + "kind": "typereference", + "name": "int", + "raw": "int", + }, + ], }, "value": String { "isDoubleQuote": true, @@ -334,14 +506,47 @@ Program { ], "final": false, "kind": "classconstant", - "nullable": false, - "type": TypeReference { - "kind": "typereference", - "name": "string", - "raw": "string", - }, "visibility": "public", }, + ClassConstant { + "attrGroups": [], + "constants": [ + Constant { + "kind": "constant", + "name": Identifier { + "kind": "identifier", + "name": "CON_6", + }, + "nullable": false, + "type": UnionType { + "kind": "uniontype", + "name": null, + "types": [ + TypeReference { + "kind": "typereference", + "name": "string", + "raw": "string", + }, + TypeReference { + "kind": "typereference", + "name": "int", + "raw": "int", + }, + ], + }, + "value": String { + "isDoubleQuote": true, + "kind": "string", + "raw": ""Hello world!"", + "unicode": false, + "value": "Hello world!", + }, + }, + ], + "final": false, + "kind": "classconstant", + "visibility": "", + }, ], "extends": null, "implements": null, @@ -361,4 +566,162 @@ Program { } `; -exports[`classconstant type hinted (unsupported) 1`] = `"Parse Error : syntax error, unexpected 'CONSTANT' (T_STRING), expecting '=' on line 1"`; +exports[`classconstant type hinted (unsupported) 1`] = `"Parse Error: Typed Class Constants requires PHP 8.3+ on line 1"`; + +exports[`classconstant type hinted list of constant with mixed type 1`] = ` +Program { + "children": [ + Class { + "attrGroups": [], + "body": [ + ClassConstant { + "attrGroups": [], + "constants": [ + Constant { + "kind": "constant", + "name": Identifier { + "kind": "identifier", + "name": "PUB1", + }, + "nullable": false, + "type": TypeReference { + "kind": "typereference", + "name": "string", + "raw": "string", + }, + "value": String { + "isDoubleQuote": false, + "kind": "string", + "raw": "'bar'", + "unicode": false, + "value": "bar", + }, + }, + Constant { + "kind": "constant", + "name": Identifier { + "kind": "identifier", + "name": "PUB2", + }, + "nullable": false, + "type": null, + "value": String { + "isDoubleQuote": false, + "kind": "string", + "raw": "'bar2'", + "unicode": false, + "value": "bar2", + }, + }, + Constant { + "kind": "constant", + "name": Identifier { + "kind": "identifier", + "name": "PUB3", + }, + "nullable": false, + "type": TypeReference { + "kind": "typereference", + "name": "int", + "raw": "int", + }, + "value": Number { + "kind": "number", + "value": "1", + }, + }, + ], + "final": false, + "kind": "classconstant", + "visibility": "public", + }, + ClassConstant { + "attrGroups": [], + "constants": [ + Constant { + "kind": "constant", + "name": Identifier { + "kind": "identifier", + "name": "PRI1", + }, + "nullable": false, + "type": null, + "value": String { + "isDoubleQuote": false, + "kind": "string", + "raw": "'baz'", + "unicode": false, + "value": "baz", + }, + }, + Constant { + "kind": "constant", + "name": Identifier { + "kind": "identifier", + "name": "PRI2", + }, + "nullable": false, + "type": TypeReference { + "kind": "typereference", + "name": "string", + "raw": "string", + }, + "value": String { + "isDoubleQuote": false, + "kind": "string", + "raw": "'baz2'", + "unicode": false, + "value": "baz2", + }, + }, + ], + "final": false, + "kind": "classconstant", + "visibility": "private", + }, + ClassConstant { + "attrGroups": [], + "constants": [ + Constant { + "kind": "constant", + "name": Identifier { + "kind": "identifier", + "name": "BOB", + }, + "nullable": false, + "type": TypeReference { + "kind": "typereference", + "name": "string", + "raw": "string", + }, + "value": String { + "isDoubleQuote": false, + "kind": "string", + "raw": "'baz2'", + "unicode": false, + "value": "baz2", + }, + }, + ], + "final": false, + "kind": "classconstant", + "visibility": "private", + }, + ], + "extends": null, + "implements": null, + "isAbstract": false, + "isAnonymous": false, + "isFinal": false, + "isReadonly": false, + "kind": "class", + "name": Identifier { + "kind": "identifier", + "name": "Foo", + }, + }, + ], + "errors": [], + "kind": "program", +} +`; diff --git a/test/snapshot/__snapshots__/constantstatement.test.js.snap b/test/snapshot/__snapshots__/constantstatement.test.js.snap index 294dc9d86..6400f13f5 100644 --- a/test/snapshot/__snapshots__/constantstatement.test.js.snap +++ b/test/snapshot/__snapshots__/constantstatement.test.js.snap @@ -11,6 +11,8 @@ Program { "kind": "identifier", "name": "CONSTANT", }, + "nullable": null, + "type": undefined, "value": String { "isDoubleQuote": true, "kind": "string", @@ -25,6 +27,8 @@ Program { "kind": "identifier", "name": "OTHER_CONSTANT", }, + "nullable": null, + "type": undefined, "value": String { "isDoubleQuote": true, "kind": "string", @@ -53,6 +57,8 @@ Program { "kind": "identifier", "name": "CONSTANT", }, + "nullable": null, + "type": undefined, "value": String { "isDoubleQuote": true, "kind": "string", diff --git a/test/snapshot/__snapshots__/enum.test.js.snap b/test/snapshot/__snapshots__/enum.test.js.snap index 0d32779aa..393202b70 100644 --- a/test/snapshot/__snapshots__/enum.test.js.snap +++ b/test/snapshot/__snapshots__/enum.test.js.snap @@ -23,6 +23,8 @@ Program { "kind": "identifier", "name": "Baz", }, + "nullable": false, + "type": null, "value": StaticLookup { "kind": "staticlookup", "offset": Identifier { @@ -38,8 +40,6 @@ Program { ], "final": false, "kind": "classconstant", - "nullable": false, - "type": null, "visibility": "public", }, ], diff --git a/test/snapshot/__snapshots__/heredoc.test.js.snap b/test/snapshot/__snapshots__/heredoc.test.js.snap index cdf9be706..9bbe61c58 100644 --- a/test/snapshot/__snapshots__/heredoc.test.js.snap +++ b/test/snapshot/__snapshots__/heredoc.test.js.snap @@ -1684,6 +1684,8 @@ Program { "kind": "identifier", "name": "BAR", }, + "nullable": false, + "type": null, "value": Encapsed { "kind": "encapsed", "label": "FOOBAR", @@ -1711,8 +1713,6 @@ FOOBAR", ], "final": false, "kind": "classconstant", - "nullable": false, - "type": null, "visibility": "", }, PropertyStatement { diff --git a/test/snapshot/__snapshots__/interface.test.js.snap b/test/snapshot/__snapshots__/interface.test.js.snap index 14dd6a85c..b5573513f 100644 --- a/test/snapshot/__snapshots__/interface.test.js.snap +++ b/test/snapshot/__snapshots__/interface.test.js.snap @@ -59,6 +59,8 @@ Program { "kind": "identifier", "name": "B", }, + "nullable": false, + "type": null, "value": Number { "kind": "number", "value": "1", @@ -67,8 +69,6 @@ Program { ], "final": false, "kind": "classconstant", - "nullable": false, - "type": null, "visibility": "", }, ], diff --git a/test/snapshot/__snapshots__/location.test.js.snap b/test/snapshot/__snapshots__/location.test.js.snap index 24c92943f..99a5a7b32 100644 --- a/test/snapshot/__snapshots__/location.test.js.snap +++ b/test/snapshot/__snapshots__/location.test.js.snap @@ -3363,19 +3363,6 @@ Program { "constants": [ Constant { "kind": "constant", - "loc": Location { - "end": Position { - "column": 31, - "line": 1, - "offset": 31, - }, - "source": "CONSTANT = "Hello world!"", - "start": Position { - "column": 6, - "line": 1, - "offset": 6, - }, - }, "name": Identifier { "kind": "identifier", "loc": Location { @@ -3393,6 +3380,20 @@ Program { }, "name": "CONSTANT", }, + "nullable": null, + "type": Location { + "end": Position { + "column": 31, + "line": 1, + "offset": 31, + }, + "source": "CONSTANT = "Hello world!"", + "start": Position { + "column": 6, + "line": 1, + "offset": 6, + }, + }, "value": String { "isDoubleQuote": true, "kind": "string", @@ -3456,19 +3457,6 @@ Program { "constants": [ Constant { "kind": "constant", - "loc": Location { - "end": Position { - "column": 31, - "line": 1, - "offset": 31, - }, - "source": "CONSTANT = "Hello world!"", - "start": Position { - "column": 6, - "line": 1, - "offset": 6, - }, - }, "name": Identifier { "kind": "identifier", "loc": Location { @@ -3486,6 +3474,20 @@ Program { }, "name": "CONSTANT", }, + "nullable": null, + "type": Location { + "end": Position { + "column": 31, + "line": 1, + "offset": 31, + }, + "source": "CONSTANT = "Hello world!"", + "start": Position { + "column": 6, + "line": 1, + "offset": 6, + }, + }, "value": String { "isDoubleQuote": true, "kind": "string", @@ -3509,19 +3511,6 @@ Program { }, Constant { "kind": "constant", - "loc": Location { - "end": Position { - "column": 70, - "line": 1, - "offset": 70, - }, - "source": "OTHER_CONSTANT = "Other hello world!"", - "start": Position { - "column": 33, - "line": 1, - "offset": 33, - }, - }, "name": Identifier { "kind": "identifier", "loc": Location { @@ -3539,6 +3528,20 @@ Program { }, "name": "OTHER_CONSTANT", }, + "nullable": null, + "type": Location { + "end": Position { + "column": 70, + "line": 1, + "offset": 70, + }, + "source": "OTHER_CONSTANT = "Other hello world!"", + "start": Position { + "column": 33, + "line": 1, + "offset": 33, + }, + }, "value": String { "isDoubleQuote": true, "kind": "string", diff --git a/test/snapshot/__snapshots__/nowdoc.test.js.snap b/test/snapshot/__snapshots__/nowdoc.test.js.snap index 73ee4fa13..bf0bcada3 100644 --- a/test/snapshot/__snapshots__/nowdoc.test.js.snap +++ b/test/snapshot/__snapshots__/nowdoc.test.js.snap @@ -206,6 +206,8 @@ Program { "kind": "identifier", "name": "BAR", }, + "nullable": false, + "type": null, "value": Nowdoc { "kind": "nowdoc", "label": "FOOBAR", @@ -218,8 +220,6 @@ FOOBAR", ], "final": false, "kind": "classconstant", - "nullable": false, - "type": null, "visibility": "", }, PropertyStatement { diff --git a/test/snapshot/classconstant.test.js b/test/snapshot/classconstant.test.js index 8e5557ede..76108e3c5 100644 --- a/test/snapshot/classconstant.test.js +++ b/test/snapshot/classconstant.test.js @@ -42,17 +42,49 @@ describe("classconstant", () => { it("type hinted (supported)", () => { expect( parser.parseEval( - 'class Foo { public const string CONSTANT = "Hello world!"; }', - { parser: { version: 830 } }, + `class Foo { + public const CON_1 = "Hello world!"; + const CON_2 = "Hello world!"; + const string CON_3 = "Hello world!"; + public const string CON_4 = "Hello world!"; + public const string|int CON_5 = "Hello world!"; + const string|int CON_6 = "Hello world!"; + }`, + { parser: { version: 803 } }, ), ).toMatchSnapshot(); }); + + it("type hinted list of constant with mixed type", () => { + expect( + parser.parseEval( + `class Foo { + public const string PUB1 = 'bar', PUB2 = 'bar2', int PUB3 = 1; + private const PRI1 = 'baz', string PRI2 = 'baz2'; + private const string BOB = 'baz2'; + }`, + { parser: { version: 803 } }, + ), + ).toMatchSnapshot(); + }); + it("type hinted (unsupported)", () => { expect(() => parser.parseEval( - 'class Foo { public const string CONSTANT = "Hello world!"; }', - { parser: { version: 820 } }, + 'class Foo { public const DDCONSTANT = "Hello world!"; public const string CONSTANT = "Hello world!"; }', + { parser: { version: 802 } }, ), ).toThrowErrorMatchingSnapshot(); }); + + it("accept the constant name 'list'", () => { + expect( + parser.parseEval( + `class Foo { + const list = "Hello world!"; + }`, + { parser: { version: 803 } }, + ), + ).toMatchSnapshot(); + }); }); diff --git a/types.d.ts b/types.d.ts index a5ad9c93f..d8bd8e4ad 100644 --- a/types.d.ts +++ b/types.d.ts @@ -161,8 +161,6 @@ declare module "php-parser" { parseFlags(flags: (number | null)[]): void; visibility: string; final: boolean; - nullable: boolean; - type: TypeReference | IntersectionType | UnionType | null; attrGroups: AttrGroup[]; } /** @@ -204,6 +202,8 @@ declare module "php-parser" { class Constant extends Node { name: string; value: Node | string | number | boolean | null; + nullable: boolean; + type: TypeReference | IntersectionType | UnionType | null; } /** * Declares a constants into the current scope