Merge pull request #278 from TysonAndre/parse-property-declaration
Implement support for parsing php 7.4 typed properties
This commit is contained in:
Коммит
db476e97f3
|
@ -14,7 +14,15 @@ class MissingMemberDeclaration extends Node {
|
|||
/** @var Token[] */
|
||||
public $modifiers;
|
||||
|
||||
/** @var Token|null needed along with typeDeclaration for what looked like typed property declarations but was missing VariableName */
|
||||
public $questionToken;
|
||||
|
||||
/** @var QualifiedName|Token|null */
|
||||
public $typeDeclaration;
|
||||
|
||||
const CHILD_NAMES = [
|
||||
'modifiers'
|
||||
'modifiers',
|
||||
'questionToken',
|
||||
'typeDeclaration',
|
||||
];
|
||||
}
|
||||
|
|
|
@ -15,6 +15,12 @@ class PropertyDeclaration extends Node {
|
|||
/** @var Token[] */
|
||||
public $modifiers;
|
||||
|
||||
/** @var Token|null question token for PHP 7.4 type declaration */
|
||||
public $questionToken;
|
||||
|
||||
/** @var QualifiedName|Token|null */
|
||||
public $typeDeclaration;
|
||||
|
||||
/** @var DelimitedList\ExpressionList */
|
||||
public $propertyElements;
|
||||
|
||||
|
@ -23,6 +29,8 @@ class PropertyDeclaration extends Node {
|
|||
|
||||
const CHILD_NAMES = [
|
||||
'modifiers',
|
||||
'questionToken',
|
||||
'typeDeclaration',
|
||||
'propertyElements',
|
||||
'semicolon'
|
||||
];
|
||||
|
|
|
@ -596,6 +596,12 @@ class Parser {
|
|||
case TokenKind::FunctionKeyword:
|
||||
return $this->parseMethodDeclaration($parentNode, $modifiers);
|
||||
|
||||
case TokenKind::QuestionToken:
|
||||
return $this->parseRemainingPropertyDeclarationOrMissingMemberDeclaration(
|
||||
$parentNode,
|
||||
$modifiers,
|
||||
$this->eat1(TokenKind::QuestionToken)
|
||||
);
|
||||
case TokenKind::VariableName:
|
||||
return $this->parsePropertyDeclaration($parentNode, $modifiers);
|
||||
|
||||
|
@ -603,10 +609,7 @@ class Parser {
|
|||
return $this->parseTraitUseClause($parentNode);
|
||||
|
||||
default:
|
||||
$missingClassMemberDeclaration = new MissingMemberDeclaration();
|
||||
$missingClassMemberDeclaration->parent = $parentNode;
|
||||
$missingClassMemberDeclaration->modifiers = $modifiers;
|
||||
return $missingClassMemberDeclaration;
|
||||
return $this->parseRemainingPropertyDeclarationOrMissingMemberDeclaration($parentNode, $modifiers);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -2771,11 +2774,39 @@ class Parser {
|
|||
return $classConstDeclaration;
|
||||
}
|
||||
|
||||
private function parsePropertyDeclaration($parentNode, $modifiers) {
|
||||
/**
|
||||
* @param Node $parentNode
|
||||
* @param Token[] $modifiers
|
||||
* @param Token|null $questionToken
|
||||
*/
|
||||
private function parseRemainingPropertyDeclarationOrMissingMemberDeclaration($parentNode, $modifiers, $questionToken = null)
|
||||
{
|
||||
$typeDeclaration = $this->tryParseParameterTypeDeclaration(null);
|
||||
if ($questionToken !== null && $typeDeclaration === null) {
|
||||
$typeDeclaration = new MissingToken(TokenKind::PropertyType, $this->getCurrentToken()->fullStart);
|
||||
}
|
||||
if ($this->getCurrentToken()->kind !== TokenKind::VariableName) {
|
||||
return $this->makeMissingMemberDeclaration($parentNode, $modifiers, $questionToken, $typeDeclaration);
|
||||
}
|
||||
return $this->parsePropertyDeclaration($parentNode, $modifiers, $questionToken, $typeDeclaration);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Node $parentNode
|
||||
* @param Token[] $modifiers
|
||||
* @param Token|null $questionToken
|
||||
* @param QualifiedName|Token|null $typeDeclaration
|
||||
*/
|
||||
private function parsePropertyDeclaration($parentNode, $modifiers, $questionToken = null, $typeDeclaration = null) {
|
||||
$propertyDeclaration = new PropertyDeclaration();
|
||||
$propertyDeclaration->parent = $parentNode;
|
||||
|
||||
$propertyDeclaration->modifiers = $modifiers;
|
||||
$propertyDeclaration->questionToken = $questionToken; //
|
||||
$propertyDeclaration->typeDeclaration = $typeDeclaration;
|
||||
if ($typeDeclaration instanceof Node) {
|
||||
$typeDeclaration->parent = $propertyDeclaration;
|
||||
}
|
||||
$propertyDeclaration->propertyElements = $this->parseExpressionList($propertyDeclaration);
|
||||
$propertyDeclaration->semicolon = $this->eat1(TokenKind::SemicolonToken);
|
||||
|
||||
|
@ -3029,6 +3060,12 @@ class Parser {
|
|||
case TokenKind::FunctionKeyword:
|
||||
return $this->parseMethodDeclaration($parentNode, $modifiers);
|
||||
|
||||
case TokenKind::QuestionToken:
|
||||
return $this->parseRemainingPropertyDeclarationOrMissingMemberDeclaration(
|
||||
$parentNode,
|
||||
$modifiers,
|
||||
$this->eat1(TokenKind::QuestionToken)
|
||||
);
|
||||
case TokenKind::VariableName:
|
||||
return $this->parsePropertyDeclaration($parentNode, $modifiers);
|
||||
|
||||
|
@ -3036,14 +3073,29 @@ class Parser {
|
|||
return $this->parseTraitUseClause($parentNode);
|
||||
|
||||
default:
|
||||
$missingTraitMemberDeclaration = new MissingMemberDeclaration();
|
||||
$missingTraitMemberDeclaration->parent = $parentNode;
|
||||
$missingTraitMemberDeclaration->modifiers = $modifiers;
|
||||
return $missingTraitMemberDeclaration;
|
||||
return $this->parseRemainingPropertyDeclarationOrMissingMemberDeclaration($parentNode, $modifiers);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Node $parentNode
|
||||
* @param Token[] $modifiers
|
||||
* @param Token $questionToken
|
||||
* @param QualifiedName|Token|null $typeDeclaration
|
||||
*/
|
||||
private function makeMissingMemberDeclaration($parentNode, $modifiers, $questionToken = null, $typeDeclaration = null) {
|
||||
$missingTraitMemberDeclaration = new MissingMemberDeclaration();
|
||||
$missingTraitMemberDeclaration->parent = $parentNode;
|
||||
$missingTraitMemberDeclaration->modifiers = $modifiers;
|
||||
$missingTraitMemberDeclaration->questionToken = $questionToken;
|
||||
$missingTraitMemberDeclaration->typeDeclaration = $typeDeclaration;
|
||||
if ($typeDeclaration instanceof Node) {
|
||||
$typeDeclaration->parent = $missingTraitMemberDeclaration;
|
||||
}
|
||||
return $missingTraitMemberDeclaration;
|
||||
}
|
||||
|
||||
private function parseTraitUseClause($parentNode) {
|
||||
$traitUseClause = new TraitUseClause();
|
||||
$traitUseClause->parent = $parentNode;
|
||||
|
|
|
@ -185,6 +185,7 @@ class TokenKind {
|
|||
const RealReservedWord = 335;
|
||||
const ReturnType = 336;
|
||||
const InlineHtml = 337;
|
||||
const PropertyType = 338;
|
||||
|
||||
// const DollarOpenCurly = 339;
|
||||
const EncapsedAndWhitespace = 400;
|
||||
|
|
|
@ -96,6 +96,10 @@ class ParserInvariantsTest extends LexerInvariantsTest {
|
|||
public function testParentOfNodeHasSameChildNode($filename, Node $sourceFileNode) {
|
||||
foreach ($sourceFileNode->getDescendantNodesAndTokens() as $child) {
|
||||
if ($child instanceof Node) {
|
||||
if (!$child->parent) {
|
||||
$this->fail("Missing parent for " . var_export($child, true));
|
||||
}
|
||||
|
||||
$this->assertContains(
|
||||
$child, $child->parent->getChildNodesAndTokens(),
|
||||
"Invariant: Parent of Node contains same child node."
|
||||
|
|
|
@ -39,6 +39,8 @@
|
|||
"textLength": 6
|
||||
}
|
||||
],
|
||||
"questionToken": null,
|
||||
"typeDeclaration": null,
|
||||
"propertyElements": {
|
||||
"ExpressionList": {
|
||||
"children": [
|
||||
|
|
|
@ -39,6 +39,8 @@
|
|||
"textLength": 6
|
||||
}
|
||||
],
|
||||
"questionToken": null,
|
||||
"typeDeclaration": null,
|
||||
"propertyElements": {
|
||||
"ExpressionList": {
|
||||
"children": [
|
||||
|
|
|
@ -39,6 +39,8 @@
|
|||
"textLength": 6
|
||||
}
|
||||
],
|
||||
"questionToken": null,
|
||||
"typeDeclaration": null,
|
||||
"propertyElements": {
|
||||
"ExpressionList": {
|
||||
"children": [
|
||||
|
|
|
@ -43,6 +43,8 @@
|
|||
"textLength": 6
|
||||
}
|
||||
],
|
||||
"questionToken": null,
|
||||
"typeDeclaration": null,
|
||||
"propertyElements": {
|
||||
"ExpressionList": {
|
||||
"children": [
|
||||
|
|
|
@ -43,6 +43,8 @@
|
|||
"textLength": 6
|
||||
}
|
||||
],
|
||||
"questionToken": null,
|
||||
"typeDeclaration": null,
|
||||
"propertyElements": {
|
||||
"ExpressionList": {
|
||||
"children": [
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
<?php
|
||||
class HasTypedProperties {
|
||||
public static ?int $intProp = null;
|
||||
private stdClass $s;
|
||||
protected static \foo\bar $s;
|
||||
public namespace\stdClass $s;
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
[]
|
|
@ -0,0 +1,259 @@
|
|||
{
|
||||
"SourceFileNode": {
|
||||
"statementList": [
|
||||
{
|
||||
"InlineHtml": {
|
||||
"scriptSectionEndTag": null,
|
||||
"text": null,
|
||||
"scriptSectionStartTag": {
|
||||
"kind": "ScriptSectionStartTag",
|
||||
"textLength": 6
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"ClassDeclaration": {
|
||||
"abstractOrFinalModifier": null,
|
||||
"classKeyword": {
|
||||
"kind": "ClassKeyword",
|
||||
"textLength": 5
|
||||
},
|
||||
"name": {
|
||||
"kind": "Name",
|
||||
"textLength": 18
|
||||
},
|
||||
"classBaseClause": null,
|
||||
"classInterfaceClause": null,
|
||||
"classMembers": {
|
||||
"ClassMembersNode": {
|
||||
"openBrace": {
|
||||
"kind": "OpenBraceToken",
|
||||
"textLength": 1
|
||||
},
|
||||
"classMemberDeclarations": [
|
||||
{
|
||||
"PropertyDeclaration": {
|
||||
"modifiers": [
|
||||
{
|
||||
"kind": "PublicKeyword",
|
||||
"textLength": 6
|
||||
},
|
||||
{
|
||||
"kind": "StaticKeyword",
|
||||
"textLength": 6
|
||||
}
|
||||
],
|
||||
"questionToken": {
|
||||
"kind": "QuestionToken",
|
||||
"textLength": 1
|
||||
},
|
||||
"typeDeclaration": {
|
||||
"kind": "IntReservedWord",
|
||||
"textLength": 3
|
||||
},
|
||||
"propertyElements": {
|
||||
"ExpressionList": {
|
||||
"children": [
|
||||
{
|
||||
"AssignmentExpression": {
|
||||
"leftOperand": {
|
||||
"Variable": {
|
||||
"dollar": null,
|
||||
"name": {
|
||||
"kind": "VariableName",
|
||||
"textLength": 8
|
||||
}
|
||||
}
|
||||
},
|
||||
"operator": {
|
||||
"kind": "EqualsToken",
|
||||
"textLength": 1
|
||||
},
|
||||
"byRef": null,
|
||||
"rightOperand": {
|
||||
"ReservedWord": {
|
||||
"children": {
|
||||
"kind": "NullReservedWord",
|
||||
"textLength": 4
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"semicolon": {
|
||||
"kind": "SemicolonToken",
|
||||
"textLength": 1
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"PropertyDeclaration": {
|
||||
"modifiers": [
|
||||
{
|
||||
"kind": "PrivateKeyword",
|
||||
"textLength": 7
|
||||
}
|
||||
],
|
||||
"questionToken": null,
|
||||
"typeDeclaration": {
|
||||
"QualifiedName": {
|
||||
"globalSpecifier": null,
|
||||
"relativeSpecifier": null,
|
||||
"nameParts": [
|
||||
{
|
||||
"kind": "Name",
|
||||
"textLength": 8
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"propertyElements": {
|
||||
"ExpressionList": {
|
||||
"children": [
|
||||
{
|
||||
"Variable": {
|
||||
"dollar": null,
|
||||
"name": {
|
||||
"kind": "VariableName",
|
||||
"textLength": 2
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"semicolon": {
|
||||
"kind": "SemicolonToken",
|
||||
"textLength": 1
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"PropertyDeclaration": {
|
||||
"modifiers": [
|
||||
{
|
||||
"kind": "ProtectedKeyword",
|
||||
"textLength": 9
|
||||
},
|
||||
{
|
||||
"kind": "StaticKeyword",
|
||||
"textLength": 6
|
||||
}
|
||||
],
|
||||
"questionToken": null,
|
||||
"typeDeclaration": {
|
||||
"QualifiedName": {
|
||||
"globalSpecifier": {
|
||||
"kind": "BackslashToken",
|
||||
"textLength": 1
|
||||
},
|
||||
"relativeSpecifier": null,
|
||||
"nameParts": [
|
||||
{
|
||||
"kind": "Name",
|
||||
"textLength": 3
|
||||
},
|
||||
{
|
||||
"kind": "BackslashToken",
|
||||
"textLength": 1
|
||||
},
|
||||
{
|
||||
"kind": "Name",
|
||||
"textLength": 3
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"propertyElements": {
|
||||
"ExpressionList": {
|
||||
"children": [
|
||||
{
|
||||
"Variable": {
|
||||
"dollar": null,
|
||||
"name": {
|
||||
"kind": "VariableName",
|
||||
"textLength": 2
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"semicolon": {
|
||||
"kind": "SemicolonToken",
|
||||
"textLength": 1
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"PropertyDeclaration": {
|
||||
"modifiers": [
|
||||
{
|
||||
"kind": "PublicKeyword",
|
||||
"textLength": 6
|
||||
}
|
||||
],
|
||||
"questionToken": null,
|
||||
"typeDeclaration": {
|
||||
"QualifiedName": {
|
||||
"globalSpecifier": null,
|
||||
"relativeSpecifier": {
|
||||
"RelativeSpecifier": {
|
||||
"namespaceKeyword": {
|
||||
"kind": "NamespaceKeyword",
|
||||
"textLength": 9
|
||||
},
|
||||
"backslash": {
|
||||
"kind": "BackslashToken",
|
||||
"textLength": 1
|
||||
}
|
||||
}
|
||||
},
|
||||
"nameParts": [
|
||||
{
|
||||
"kind": "Name",
|
||||
"textLength": 8
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"propertyElements": {
|
||||
"ExpressionList": {
|
||||
"children": [
|
||||
{
|
||||
"Variable": {
|
||||
"dollar": null,
|
||||
"name": {
|
||||
"kind": "VariableName",
|
||||
"textLength": 2
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"semicolon": {
|
||||
"kind": "SemicolonToken",
|
||||
"textLength": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"closeBrace": {
|
||||
"kind": "CloseBraceToken",
|
||||
"textLength": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"endOfFileToken": {
|
||||
"kind": "EndOfFileToken",
|
||||
"textLength": 0
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
<?php
|
||||
class Foo {
|
||||
public int function x() {}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
[]
|
|
@ -0,0 +1,103 @@
|
|||
{
|
||||
"SourceFileNode": {
|
||||
"statementList": [
|
||||
{
|
||||
"InlineHtml": {
|
||||
"scriptSectionEndTag": null,
|
||||
"text": null,
|
||||
"scriptSectionStartTag": {
|
||||
"kind": "ScriptSectionStartTag",
|
||||
"textLength": 6
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"ClassDeclaration": {
|
||||
"abstractOrFinalModifier": null,
|
||||
"classKeyword": {
|
||||
"kind": "ClassKeyword",
|
||||
"textLength": 5
|
||||
},
|
||||
"name": {
|
||||
"kind": "Name",
|
||||
"textLength": 3
|
||||
},
|
||||
"classBaseClause": null,
|
||||
"classInterfaceClause": null,
|
||||
"classMembers": {
|
||||
"ClassMembersNode": {
|
||||
"openBrace": {
|
||||
"kind": "OpenBraceToken",
|
||||
"textLength": 1
|
||||
},
|
||||
"classMemberDeclarations": [
|
||||
{
|
||||
"MissingMemberDeclaration": {
|
||||
"modifiers": [
|
||||
{
|
||||
"kind": "PublicKeyword",
|
||||
"textLength": 6
|
||||
}
|
||||
],
|
||||
"questionToken": null,
|
||||
"typeDeclaration": {
|
||||
"kind": "IntReservedWord",
|
||||
"textLength": 3
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"MethodDeclaration": {
|
||||
"modifiers": [],
|
||||
"functionKeyword": {
|
||||
"kind": "FunctionKeyword",
|
||||
"textLength": 8
|
||||
},
|
||||
"byRefToken": null,
|
||||
"name": {
|
||||
"kind": "Name",
|
||||
"textLength": 1
|
||||
},
|
||||
"openParen": {
|
||||
"kind": "OpenParenToken",
|
||||
"textLength": 1
|
||||
},
|
||||
"parameters": null,
|
||||
"closeParen": {
|
||||
"kind": "CloseParenToken",
|
||||
"textLength": 1
|
||||
},
|
||||
"colonToken": null,
|
||||
"questionToken": null,
|
||||
"returnType": null,
|
||||
"compoundStatementOrSemicolon": {
|
||||
"CompoundStatementNode": {
|
||||
"openBrace": {
|
||||
"kind": "OpenBraceToken",
|
||||
"textLength": 1
|
||||
},
|
||||
"statements": [],
|
||||
"closeBrace": {
|
||||
"kind": "CloseBraceToken",
|
||||
"textLength": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"closeBrace": {
|
||||
"kind": "CloseBraceToken",
|
||||
"textLength": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"endOfFileToken": {
|
||||
"kind": "EndOfFileToken",
|
||||
"textLength": 0
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
<?php
|
||||
class X {
|
||||
public static ?function x() {}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
[
|
||||
{
|
||||
"kind": 0,
|
||||
"message": "'PropertyType' expected.",
|
||||
"start": 35,
|
||||
"length": 0
|
||||
}
|
||||
]
|
|
@ -0,0 +1,111 @@
|
|||
{
|
||||
"SourceFileNode": {
|
||||
"statementList": [
|
||||
{
|
||||
"InlineHtml": {
|
||||
"scriptSectionEndTag": null,
|
||||
"text": null,
|
||||
"scriptSectionStartTag": {
|
||||
"kind": "ScriptSectionStartTag",
|
||||
"textLength": 6
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"ClassDeclaration": {
|
||||
"abstractOrFinalModifier": null,
|
||||
"classKeyword": {
|
||||
"kind": "ClassKeyword",
|
||||
"textLength": 5
|
||||
},
|
||||
"name": {
|
||||
"kind": "Name",
|
||||
"textLength": 1
|
||||
},
|
||||
"classBaseClause": null,
|
||||
"classInterfaceClause": null,
|
||||
"classMembers": {
|
||||
"ClassMembersNode": {
|
||||
"openBrace": {
|
||||
"kind": "OpenBraceToken",
|
||||
"textLength": 1
|
||||
},
|
||||
"classMemberDeclarations": [
|
||||
{
|
||||
"MissingMemberDeclaration": {
|
||||
"modifiers": [
|
||||
{
|
||||
"kind": "PublicKeyword",
|
||||
"textLength": 6
|
||||
},
|
||||
{
|
||||
"kind": "StaticKeyword",
|
||||
"textLength": 6
|
||||
}
|
||||
],
|
||||
"questionToken": {
|
||||
"kind": "QuestionToken",
|
||||
"textLength": 1
|
||||
},
|
||||
"typeDeclaration": {
|
||||
"error": "MissingToken",
|
||||
"kind": "PropertyType",
|
||||
"textLength": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"MethodDeclaration": {
|
||||
"modifiers": [],
|
||||
"functionKeyword": {
|
||||
"kind": "FunctionKeyword",
|
||||
"textLength": 8
|
||||
},
|
||||
"byRefToken": null,
|
||||
"name": {
|
||||
"kind": "Name",
|
||||
"textLength": 1
|
||||
},
|
||||
"openParen": {
|
||||
"kind": "OpenParenToken",
|
||||
"textLength": 1
|
||||
},
|
||||
"parameters": null,
|
||||
"closeParen": {
|
||||
"kind": "CloseParenToken",
|
||||
"textLength": 1
|
||||
},
|
||||
"colonToken": null,
|
||||
"questionToken": null,
|
||||
"returnType": null,
|
||||
"compoundStatementOrSemicolon": {
|
||||
"CompoundStatementNode": {
|
||||
"openBrace": {
|
||||
"kind": "OpenBraceToken",
|
||||
"textLength": 1
|
||||
},
|
||||
"statements": [],
|
||||
"closeBrace": {
|
||||
"kind": "CloseBraceToken",
|
||||
"textLength": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"closeBrace": {
|
||||
"kind": "CloseBraceToken",
|
||||
"textLength": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"endOfFileToken": {
|
||||
"kind": "EndOfFileToken",
|
||||
"textLength": 0
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
<?php
|
||||
class Foo {
|
||||
public ?$x=2;
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
[
|
||||
{
|
||||
"kind": 0,
|
||||
"message": "'PropertyType' expected.",
|
||||
"start": 30,
|
||||
"length": 0
|
||||
}
|
||||
]
|
|
@ -0,0 +1,104 @@
|
|||
{
|
||||
"SourceFileNode": {
|
||||
"statementList": [
|
||||
{
|
||||
"InlineHtml": {
|
||||
"scriptSectionEndTag": null,
|
||||
"text": null,
|
||||
"scriptSectionStartTag": {
|
||||
"kind": "ScriptSectionStartTag",
|
||||
"textLength": 6
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"ClassDeclaration": {
|
||||
"abstractOrFinalModifier": null,
|
||||
"classKeyword": {
|
||||
"kind": "ClassKeyword",
|
||||
"textLength": 5
|
||||
},
|
||||
"name": {
|
||||
"kind": "Name",
|
||||
"textLength": 3
|
||||
},
|
||||
"classBaseClause": null,
|
||||
"classInterfaceClause": null,
|
||||
"classMembers": {
|
||||
"ClassMembersNode": {
|
||||
"openBrace": {
|
||||
"kind": "OpenBraceToken",
|
||||
"textLength": 1
|
||||
},
|
||||
"classMemberDeclarations": [
|
||||
{
|
||||
"PropertyDeclaration": {
|
||||
"modifiers": [
|
||||
{
|
||||
"kind": "PublicKeyword",
|
||||
"textLength": 6
|
||||
}
|
||||
],
|
||||
"questionToken": {
|
||||
"kind": "QuestionToken",
|
||||
"textLength": 1
|
||||
},
|
||||
"typeDeclaration": {
|
||||
"error": "MissingToken",
|
||||
"kind": "PropertyType",
|
||||
"textLength": 0
|
||||
},
|
||||
"propertyElements": {
|
||||
"ExpressionList": {
|
||||
"children": [
|
||||
{
|
||||
"AssignmentExpression": {
|
||||
"leftOperand": {
|
||||
"Variable": {
|
||||
"dollar": null,
|
||||
"name": {
|
||||
"kind": "VariableName",
|
||||
"textLength": 2
|
||||
}
|
||||
}
|
||||
},
|
||||
"operator": {
|
||||
"kind": "EqualsToken",
|
||||
"textLength": 1
|
||||
},
|
||||
"byRef": null,
|
||||
"rightOperand": {
|
||||
"NumericLiteral": {
|
||||
"children": {
|
||||
"kind": "IntegerLiteralToken",
|
||||
"textLength": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"semicolon": {
|
||||
"kind": "SemicolonToken",
|
||||
"textLength": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"closeBrace": {
|
||||
"kind": "CloseBraceToken",
|
||||
"textLength": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"endOfFileToken": {
|
||||
"kind": "EndOfFileToken",
|
||||
"textLength": 0
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
<?php
|
||||
class X {
|
||||
public int $a = 2;
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
[]
|
|
@ -0,0 +1,100 @@
|
|||
{
|
||||
"SourceFileNode": {
|
||||
"statementList": [
|
||||
{
|
||||
"InlineHtml": {
|
||||
"scriptSectionEndTag": null,
|
||||
"text": null,
|
||||
"scriptSectionStartTag": {
|
||||
"kind": "ScriptSectionStartTag",
|
||||
"textLength": 6
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"ClassDeclaration": {
|
||||
"abstractOrFinalModifier": null,
|
||||
"classKeyword": {
|
||||
"kind": "ClassKeyword",
|
||||
"textLength": 5
|
||||
},
|
||||
"name": {
|
||||
"kind": "Name",
|
||||
"textLength": 1
|
||||
},
|
||||
"classBaseClause": null,
|
||||
"classInterfaceClause": null,
|
||||
"classMembers": {
|
||||
"ClassMembersNode": {
|
||||
"openBrace": {
|
||||
"kind": "OpenBraceToken",
|
||||
"textLength": 1
|
||||
},
|
||||
"classMemberDeclarations": [
|
||||
{
|
||||
"PropertyDeclaration": {
|
||||
"modifiers": [
|
||||
{
|
||||
"kind": "PublicKeyword",
|
||||
"textLength": 6
|
||||
}
|
||||
],
|
||||
"questionToken": null,
|
||||
"typeDeclaration": {
|
||||
"kind": "IntReservedWord",
|
||||
"textLength": 3
|
||||
},
|
||||
"propertyElements": {
|
||||
"ExpressionList": {
|
||||
"children": [
|
||||
{
|
||||
"AssignmentExpression": {
|
||||
"leftOperand": {
|
||||
"Variable": {
|
||||
"dollar": null,
|
||||
"name": {
|
||||
"kind": "VariableName",
|
||||
"textLength": 2
|
||||
}
|
||||
}
|
||||
},
|
||||
"operator": {
|
||||
"kind": "EqualsToken",
|
||||
"textLength": 1
|
||||
},
|
||||
"byRef": null,
|
||||
"rightOperand": {
|
||||
"NumericLiteral": {
|
||||
"children": {
|
||||
"kind": "IntegerLiteralToken",
|
||||
"textLength": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"semicolon": {
|
||||
"kind": "SemicolonToken",
|
||||
"textLength": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"closeBrace": {
|
||||
"kind": "CloseBraceToken",
|
||||
"textLength": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"endOfFileToken": {
|
||||
"kind": "EndOfFileToken",
|
||||
"textLength": 0
|
||||
}
|
||||
}
|
||||
}
|
Загрузка…
Ссылка в новой задаче