From 45d447e2976807c2ec54ff464462f2b455e3d954 Mon Sep 17 00:00:00 2001 From: Tyson Andre Date: Sun, 14 Jun 2020 13:20:58 -0400 Subject: [PATCH 1/2] Support php 8.0 constructor property promotion https://wiki.php.net/rfc/constructor_promotion Note that PHP 8.0 will parse visibility modifiers on all parameters, but it will be a compile-time error to use them anywhere except a __construct method. Fixes #323 --- src/Node/Parameter.php | 3 + src/Parser.php | 7 +- tests/cases/parser/classMethods3.php.tree | 2 + tests/cases/parser/classMethods4.php.tree | 2 + tests/cases/parser/functions10.php.tree | 2 + tests/cases/parser/functions11.php.tree | 2 + tests/cases/parser/functions12.php.tree | 2 + tests/cases/parser/functions13.php.tree | 2 + tests/cases/parser/functions14.php.tree | 3 + tests/cases/parser/functions15.php.tree | 3 + tests/cases/parser/functions16.php.tree | 1 + tests/cases/parser/functions17.php.tree | 2 + tests/cases/parser/functions18.php.tree | 2 + tests/cases/parser/functions3.php.tree | 2 + tests/cases/parser/functions6.php.tree | 2 + tests/cases/parser/functions7.php.tree | 2 + tests/cases/parser/functions8.php.tree | 2 + tests/cases/parser/functions9.php.tree | 2 + .../parser/interfaceDeclaration10.php.tree | 2 + .../parser/interfaceDeclaration8.php.tree | 2 + .../parser/interfaceDeclaration9.php.tree | 2 + tests/cases/parser/parameterPromotion1.php | 5 + .../cases/parser/parameterPromotion1.php.diag | 1 + .../cases/parser/parameterPromotion1.php.tree | 167 ++++++++++++++++ .../cases/parser/parameterPromotion2.php.diag | 50 +++++ .../cases/parser/parameterPromotion2.php.tree | 179 ++++++++++++++++++ .../cases/parser/unionTypeParameter1.php.tree | 1 + .../cases/parser/unionTypeParameter2.php.tree | 1 + tests/cases/parser/yieldExpression18.php.tree | 1 + tests/cases/parser/yieldExpression19.php.tree | 1 + tests/cases/parser74/arrowFunction.php.tree | 6 + .../parser74/arrowFunctionFallback.php.tree | 5 + .../parser74/arrowFunctionTypes.php.tree | 5 + .../parser74/arrowFunctionUnionTypes.php.tree | 4 + 34 files changed, 474 insertions(+), 1 deletion(-) create mode 100644 tests/cases/parser/parameterPromotion1.php create mode 100644 tests/cases/parser/parameterPromotion1.php.diag create mode 100644 tests/cases/parser/parameterPromotion1.php.tree create mode 100644 tests/cases/parser/parameterPromotion2.php.diag create mode 100644 tests/cases/parser/parameterPromotion2.php.tree diff --git a/src/Node/Parameter.php b/src/Node/Parameter.php index 414c78dd..ca06b460 100644 --- a/src/Node/Parameter.php +++ b/src/Node/Parameter.php @@ -10,6 +10,8 @@ use Microsoft\PhpParser\Token; class Parameter extends Node { + /** @var Token|null */ + public $visibilityToken; /** @var Token|null */ public $questionToken; /** @var QualifiedName|Token|null */ @@ -31,6 +33,7 @@ class Parameter extends Node { public $default; const CHILD_NAMES = [ + 'visibilityToken', 'questionToken', 'typeDeclaration', 'otherTypeDeclarations', diff --git a/src/Parser.php b/src/Parser.php index 0d420d7b..e3b3f929 100644 --- a/src/Parser.php +++ b/src/Parser.php @@ -656,6 +656,7 @@ private function parseParameterFn() { return function ($parentNode) { $parameter = new Parameter(); $parameter->parent = $parentNode; + $parameter->visibilityToken = $this->eatOptional([TokenKind::PublicKeyword, TokenKind::ProtectedKeyword, TokenKind::PrivateKeyword]); $parameter->questionToken = $this->eatOptional1(TokenKind::QuestionToken); $typeDeclarationList = $this->tryParseParameterTypeDeclarationList($parameter); if ($typeDeclarationList) { @@ -1294,10 +1295,14 @@ private function isParameterStartFn() { case TokenKind::AmpersandToken: case TokenKind::VariableName: - return true; // nullable-type case TokenKind::QuestionToken: + + // parameter promotion + case TokenKind::PublicKeyword: + case TokenKind::ProtectedKeyword: + case TokenKind::PrivateKeyword: return true; } diff --git a/tests/cases/parser/classMethods3.php.tree b/tests/cases/parser/classMethods3.php.tree index 04f564c3..b0ad87a4 100644 --- a/tests/cases/parser/classMethods3.php.tree +++ b/tests/cases/parser/classMethods3.php.tree @@ -57,6 +57,7 @@ "children": [ { "Parameter": { + "visibilityToken": null, "questionToken": null, "typeDeclaration": null, "otherTypeDeclarations": null, @@ -76,6 +77,7 @@ }, { "Parameter": { + "visibilityToken": null, "questionToken": null, "typeDeclaration": null, "otherTypeDeclarations": null, diff --git a/tests/cases/parser/classMethods4.php.tree b/tests/cases/parser/classMethods4.php.tree index 4b99e46e..76112f9f 100644 --- a/tests/cases/parser/classMethods4.php.tree +++ b/tests/cases/parser/classMethods4.php.tree @@ -57,6 +57,7 @@ "children": [ { "Parameter": { + "visibilityToken": null, "questionToken": null, "typeDeclaration": null, "otherTypeDeclarations": null, @@ -76,6 +77,7 @@ }, { "Parameter": { + "visibilityToken": null, "questionToken": null, "typeDeclaration": null, "otherTypeDeclarations": null, diff --git a/tests/cases/parser/functions10.php.tree b/tests/cases/parser/functions10.php.tree index 082f4d7d..1ac8a00e 100644 --- a/tests/cases/parser/functions10.php.tree +++ b/tests/cases/parser/functions10.php.tree @@ -31,6 +31,7 @@ "children": [ { "Parameter": { + "visibilityToken": null, "questionToken": null, "typeDeclaration": null, "otherTypeDeclarations": null, @@ -50,6 +51,7 @@ }, { "Parameter": { + "visibilityToken": null, "questionToken": null, "typeDeclaration": null, "otherTypeDeclarations": null, diff --git a/tests/cases/parser/functions11.php.tree b/tests/cases/parser/functions11.php.tree index 7ccbe041..6b3755ac 100644 --- a/tests/cases/parser/functions11.php.tree +++ b/tests/cases/parser/functions11.php.tree @@ -31,6 +31,7 @@ "children": [ { "Parameter": { + "visibilityToken": null, "questionToken": null, "typeDeclaration": null, "otherTypeDeclarations": null, @@ -50,6 +51,7 @@ }, { "Parameter": { + "visibilityToken": null, "questionToken": null, "typeDeclaration": { "QualifiedName": { diff --git a/tests/cases/parser/functions12.php.tree b/tests/cases/parser/functions12.php.tree index b0fb3b09..bef18329 100644 --- a/tests/cases/parser/functions12.php.tree +++ b/tests/cases/parser/functions12.php.tree @@ -31,6 +31,7 @@ "children": [ { "Parameter": { + "visibilityToken": null, "questionToken": null, "typeDeclaration": null, "otherTypeDeclarations": null, @@ -50,6 +51,7 @@ }, { "Parameter": { + "visibilityToken": null, "questionToken": null, "typeDeclaration": { "QualifiedName": { diff --git a/tests/cases/parser/functions13.php.tree b/tests/cases/parser/functions13.php.tree index a41962b5..b6487428 100644 --- a/tests/cases/parser/functions13.php.tree +++ b/tests/cases/parser/functions13.php.tree @@ -31,6 +31,7 @@ "children": [ { "Parameter": { + "visibilityToken": null, "questionToken": null, "typeDeclaration": null, "otherTypeDeclarations": null, @@ -50,6 +51,7 @@ }, { "Parameter": { + "visibilityToken": null, "questionToken": null, "typeDeclaration": { "QualifiedName": { diff --git a/tests/cases/parser/functions14.php.tree b/tests/cases/parser/functions14.php.tree index bb24d95a..aa02bae4 100644 --- a/tests/cases/parser/functions14.php.tree +++ b/tests/cases/parser/functions14.php.tree @@ -31,6 +31,7 @@ "children": [ { "Parameter": { + "visibilityToken": null, "questionToken": null, "typeDeclaration": null, "otherTypeDeclarations": null, @@ -50,6 +51,7 @@ }, { "Parameter": { + "visibilityToken": null, "questionToken": null, "typeDeclaration": { "QualifiedName": { @@ -83,6 +85,7 @@ }, { "Parameter": { + "visibilityToken": null, "questionToken": null, "typeDeclaration": null, "otherTypeDeclarations": null, diff --git a/tests/cases/parser/functions15.php.tree b/tests/cases/parser/functions15.php.tree index 0521c6ca..d5fffc8a 100644 --- a/tests/cases/parser/functions15.php.tree +++ b/tests/cases/parser/functions15.php.tree @@ -31,6 +31,7 @@ "children": [ { "Parameter": { + "visibilityToken": null, "questionToken": null, "typeDeclaration": null, "otherTypeDeclarations": null, @@ -50,6 +51,7 @@ }, { "Parameter": { + "visibilityToken": null, "questionToken": null, "typeDeclaration": { "QualifiedName": { @@ -83,6 +85,7 @@ }, { "Parameter": { + "visibilityToken": null, "questionToken": null, "typeDeclaration": null, "otherTypeDeclarations": null, diff --git a/tests/cases/parser/functions16.php.tree b/tests/cases/parser/functions16.php.tree index 79cf5495..2cdeff84 100644 --- a/tests/cases/parser/functions16.php.tree +++ b/tests/cases/parser/functions16.php.tree @@ -31,6 +31,7 @@ "children": [ { "Parameter": { + "visibilityToken": null, "questionToken": null, "typeDeclaration": null, "otherTypeDeclarations": null, diff --git a/tests/cases/parser/functions17.php.tree b/tests/cases/parser/functions17.php.tree index 3e9cbbb1..4afd0c68 100644 --- a/tests/cases/parser/functions17.php.tree +++ b/tests/cases/parser/functions17.php.tree @@ -31,6 +31,7 @@ "children": [ { "Parameter": { + "visibilityToken": null, "questionToken": { "kind": "QuestionToken", "textLength": 1 @@ -64,6 +65,7 @@ }, { "Parameter": { + "visibilityToken": null, "questionToken": { "kind": "QuestionToken", "textLength": 1 diff --git a/tests/cases/parser/functions18.php.tree b/tests/cases/parser/functions18.php.tree index d953f6c1..95e6e986 100644 --- a/tests/cases/parser/functions18.php.tree +++ b/tests/cases/parser/functions18.php.tree @@ -31,6 +31,7 @@ "children": [ { "Parameter": { + "visibilityToken": null, "questionToken": null, "typeDeclaration": { "QualifiedName": { @@ -61,6 +62,7 @@ }, { "Parameter": { + "visibilityToken": null, "questionToken": null, "typeDeclaration": { "kind": "IntReservedWord", diff --git a/tests/cases/parser/functions3.php.tree b/tests/cases/parser/functions3.php.tree index 7d036b6c..2541c163 100644 --- a/tests/cases/parser/functions3.php.tree +++ b/tests/cases/parser/functions3.php.tree @@ -31,6 +31,7 @@ "children": [ { "Parameter": { + "visibilityToken": null, "questionToken": null, "typeDeclaration": { "QualifiedName": { @@ -61,6 +62,7 @@ }, { "Parameter": { + "visibilityToken": null, "questionToken": null, "typeDeclaration": { "kind": "IntReservedWord", diff --git a/tests/cases/parser/functions6.php.tree b/tests/cases/parser/functions6.php.tree index ac569a5d..976d76f1 100644 --- a/tests/cases/parser/functions6.php.tree +++ b/tests/cases/parser/functions6.php.tree @@ -31,6 +31,7 @@ "children": [ { "Parameter": { + "visibilityToken": null, "questionToken": null, "typeDeclaration": null, "otherTypeDeclarations": null, @@ -61,6 +62,7 @@ }, { "Parameter": { + "visibilityToken": null, "questionToken": null, "typeDeclaration": null, "otherTypeDeclarations": null, diff --git a/tests/cases/parser/functions7.php.tree b/tests/cases/parser/functions7.php.tree index f6b02288..7f59d69d 100644 --- a/tests/cases/parser/functions7.php.tree +++ b/tests/cases/parser/functions7.php.tree @@ -31,6 +31,7 @@ "children": [ { "Parameter": { + "visibilityToken": null, "questionToken": null, "typeDeclaration": null, "otherTypeDeclarations": null, @@ -57,6 +58,7 @@ }, { "Parameter": { + "visibilityToken": null, "questionToken": null, "typeDeclaration": null, "otherTypeDeclarations": null, diff --git a/tests/cases/parser/functions8.php.tree b/tests/cases/parser/functions8.php.tree index ba45959c..6fa1eeef 100644 --- a/tests/cases/parser/functions8.php.tree +++ b/tests/cases/parser/functions8.php.tree @@ -31,6 +31,7 @@ "children": [ { "Parameter": { + "visibilityToken": null, "questionToken": null, "typeDeclaration": null, "otherTypeDeclarations": null, @@ -50,6 +51,7 @@ }, { "Parameter": { + "visibilityToken": null, "questionToken": null, "typeDeclaration": null, "otherTypeDeclarations": null, diff --git a/tests/cases/parser/functions9.php.tree b/tests/cases/parser/functions9.php.tree index f4a2d673..379c5b45 100644 --- a/tests/cases/parser/functions9.php.tree +++ b/tests/cases/parser/functions9.php.tree @@ -31,6 +31,7 @@ "children": [ { "Parameter": { + "visibilityToken": null, "questionToken": null, "typeDeclaration": null, "otherTypeDeclarations": null, @@ -50,6 +51,7 @@ }, { "Parameter": { + "visibilityToken": null, "questionToken": null, "typeDeclaration": null, "otherTypeDeclarations": null, diff --git a/tests/cases/parser/interfaceDeclaration10.php.tree b/tests/cases/parser/interfaceDeclaration10.php.tree index 5c02fcad..3029cf90 100644 --- a/tests/cases/parser/interfaceDeclaration10.php.tree +++ b/tests/cases/parser/interfaceDeclaration10.php.tree @@ -55,6 +55,7 @@ "children": [ { "Parameter": { + "visibilityToken": null, "questionToken": null, "typeDeclaration": null, "otherTypeDeclarations": null, @@ -74,6 +75,7 @@ }, { "Parameter": { + "visibilityToken": null, "questionToken": null, "typeDeclaration": null, "otherTypeDeclarations": null, diff --git a/tests/cases/parser/interfaceDeclaration8.php.tree b/tests/cases/parser/interfaceDeclaration8.php.tree index 68abb02e..ac7005aa 100644 --- a/tests/cases/parser/interfaceDeclaration8.php.tree +++ b/tests/cases/parser/interfaceDeclaration8.php.tree @@ -55,6 +55,7 @@ "children": [ { "Parameter": { + "visibilityToken": null, "questionToken": null, "typeDeclaration": null, "otherTypeDeclarations": null, @@ -74,6 +75,7 @@ }, { "Parameter": { + "visibilityToken": null, "questionToken": null, "typeDeclaration": null, "otherTypeDeclarations": null, diff --git a/tests/cases/parser/interfaceDeclaration9.php.tree b/tests/cases/parser/interfaceDeclaration9.php.tree index f7851d58..54990b7d 100644 --- a/tests/cases/parser/interfaceDeclaration9.php.tree +++ b/tests/cases/parser/interfaceDeclaration9.php.tree @@ -55,6 +55,7 @@ "children": [ { "Parameter": { + "visibilityToken": null, "questionToken": null, "typeDeclaration": null, "otherTypeDeclarations": null, @@ -74,6 +75,7 @@ }, { "Parameter": { + "visibilityToken": null, "questionToken": null, "typeDeclaration": null, "otherTypeDeclarations": null, diff --git a/tests/cases/parser/parameterPromotion1.php b/tests/cases/parser/parameterPromotion1.php new file mode 100644 index 00000000..0c2547fd --- /dev/null +++ b/tests/cases/parser/parameterPromotion1.php @@ -0,0 +1,5 @@ + Date: Sun, 14 Jun 2020 19:53:14 -0400 Subject: [PATCH 2/2] Add missing file --- tests/cases/parser/parameterPromotion2.php | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 tests/cases/parser/parameterPromotion2.php diff --git a/tests/cases/parser/parameterPromotion2.php b/tests/cases/parser/parameterPromotion2.php new file mode 100644 index 00000000..38016023 --- /dev/null +++ b/tests/cases/parser/parameterPromotion2.php @@ -0,0 +1,7 @@ +