Fixes #189 : Fix parsing edge cases in yield statements
Update tests diagnostics and expected generated ASTs For backwards compatibility, continue to make `yield from expr` have an ArrayElement as a child node. To maintain the invariant that all Nodes must have at least one child, make $yieldExpression->arrayElement be null when parsing `yield;` Aside: `yield &$a;` is (and should be) parsed as the binary operator `(yield) & ($a)`. This is surprising, but makes sense, being the only sane parse tree. - Add a unit test that `yield & &$a;` is invalid. There is no way to parse that. Verified with the PHP module nikic/php-ast ```php var_export(ast_dump( ast\parse_code('<?php function test() { yield & $x; }', 50) )); ```
This commit is contained in:
Родитель
faca5af49c
Коммит
816ec34fb6
|
@ -226,7 +226,7 @@ public function getEndPosition ( )
|
||||||
> TODO: add doc comment
|
> TODO: add doc comment
|
||||||
|
|
||||||
```php
|
```php
|
||||||
public static function getTokenKindNameFromValue ( $kindName )
|
public static function getTokenKindNameFromValue ( $kind )
|
||||||
```
|
```
|
||||||
### Token::jsonSerialize
|
### Token::jsonSerialize
|
||||||
> TODO: add doc comment
|
> TODO: add doc comment
|
||||||
|
|
|
@ -2098,7 +2098,23 @@ class Parser {
|
||||||
TokenKind::YieldFromKeyword,
|
TokenKind::YieldFromKeyword,
|
||||||
TokenKind::YieldKeyword
|
TokenKind::YieldKeyword
|
||||||
);
|
);
|
||||||
$yieldExpression->arrayElement = $this->parseArrayElement($yieldExpression);
|
if ($yieldExpression->yieldOrYieldFromKeyword->kind === TokenKind::YieldFromKeyword) {
|
||||||
|
// Don't use parseArrayElement. E.g. `yield from &$varName` or `yield from $key => $varName` are both syntax errors
|
||||||
|
$arrayElement = new ArrayElement();
|
||||||
|
$arrayElement->parent = $yieldExpression;
|
||||||
|
$arrayElement->elementValue = $this->parseExpression($arrayElement);
|
||||||
|
$yieldExpression->arrayElement = $arrayElement;
|
||||||
|
} else {
|
||||||
|
// This is always an ArrayElement for backwards compatibilitiy.
|
||||||
|
// TODO: Can this be changed to a non-ArrayElement in a future release?
|
||||||
|
if ($this->isExpressionStart($this->getCurrentToken())) {
|
||||||
|
// Both `yield expr;` and `yield;` are possible.
|
||||||
|
$yieldExpression->arrayElement = $this->parseArrayElement($yieldExpression);
|
||||||
|
} else {
|
||||||
|
$yieldExpression->arrayElement = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return $yieldExpression;
|
return $yieldExpression;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
// TODO `return yield` should fail
|
// `return yield;` is valid code in PHP 7 (invalid in PHP 5),
|
||||||
|
// since generators can also return values. It is parsed as `return (yield);`
|
||||||
function gen() {
|
function gen() {
|
||||||
return yield;
|
return yield;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1 @@
|
||||||
[
|
[]
|
||||||
{
|
|
||||||
"kind": 0,
|
|
||||||
"message": "'Expression' expected.",
|
|
||||||
"start": 75,
|
|
||||||
"length": 0
|
|
||||||
}
|
|
||||||
]
|
|
|
@ -53,18 +53,7 @@
|
||||||
"kind": "YieldKeyword",
|
"kind": "YieldKeyword",
|
||||||
"textLength": 5
|
"textLength": 5
|
||||||
},
|
},
|
||||||
"arrayElement": {
|
"arrayElement": null
|
||||||
"ArrayElement": {
|
|
||||||
"elementKey": null,
|
|
||||||
"arrowToken": null,
|
|
||||||
"byRef": null,
|
|
||||||
"elementValue": {
|
|
||||||
"error": "MissingToken",
|
|
||||||
"kind": "Expression",
|
|
||||||
"textLength": 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"semicolon": {
|
"semicolon": {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
// TODO should fail
|
// This fails with "'Expression' expected."
|
||||||
function gen() {
|
function gen() {
|
||||||
return yield from;
|
return yield from;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
{
|
{
|
||||||
"kind": 0,
|
"kind": 0,
|
||||||
"message": "'Expression' expected.",
|
"message": "'Expression' expected.",
|
||||||
"start": 65,
|
"start": 89,
|
||||||
"length": 0
|
"length": 0
|
||||||
}
|
}
|
||||||
]
|
]
|
|
@ -1,6 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
// should fail
|
// should not fail.
|
||||||
|
// This is parsed as the binary bitwise and operator (yield) & ($a);
|
||||||
function gen() {
|
function gen() {
|
||||||
yield &$a;
|
yield &$a;
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,27 +44,26 @@
|
||||||
{
|
{
|
||||||
"ExpressionStatement": {
|
"ExpressionStatement": {
|
||||||
"expression": {
|
"expression": {
|
||||||
"YieldExpression": {
|
"BinaryExpression": {
|
||||||
"yieldOrYieldFromKeyword": {
|
"leftOperand": {
|
||||||
"kind": "YieldKeyword",
|
"YieldExpression": {
|
||||||
"textLength": 5
|
"yieldOrYieldFromKeyword": {
|
||||||
},
|
"kind": "YieldKeyword",
|
||||||
"arrayElement": {
|
"textLength": 5
|
||||||
"ArrayElement": {
|
|
||||||
"elementKey": null,
|
|
||||||
"arrowToken": null,
|
|
||||||
"byRef": {
|
|
||||||
"kind": "AmpersandToken",
|
|
||||||
"textLength": 1
|
|
||||||
},
|
},
|
||||||
"elementValue": {
|
"arrayElement": null
|
||||||
"Variable": {
|
}
|
||||||
"dollar": null,
|
},
|
||||||
"name": {
|
"operator": {
|
||||||
"kind": "VariableName",
|
"kind": "AmpersandToken",
|
||||||
"textLength": 2
|
"textLength": 1
|
||||||
}
|
},
|
||||||
}
|
"rightOperand": {
|
||||||
|
"Variable": {
|
||||||
|
"dollar": null,
|
||||||
|
"name": {
|
||||||
|
"kind": "VariableName",
|
||||||
|
"textLength": 2
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1 +1,8 @@
|
||||||
[]
|
[
|
||||||
|
{
|
||||||
|
"kind": 0,
|
||||||
|
"message": "'Expression' expected.",
|
||||||
|
"start": 53,
|
||||||
|
"length": 0
|
||||||
|
}
|
||||||
|
]
|
|
@ -53,16 +53,26 @@
|
||||||
"ArrayElement": {
|
"ArrayElement": {
|
||||||
"elementKey": null,
|
"elementKey": null,
|
||||||
"arrowToken": null,
|
"arrowToken": null,
|
||||||
"byRef": {
|
"byRef": null,
|
||||||
"kind": "AmpersandToken",
|
|
||||||
"textLength": 1
|
|
||||||
},
|
|
||||||
"elementValue": {
|
"elementValue": {
|
||||||
"Variable": {
|
"BinaryExpression": {
|
||||||
"dollar": null,
|
"leftOperand": {
|
||||||
"name": {
|
"error": "MissingToken",
|
||||||
"kind": "VariableName",
|
"kind": "Expression",
|
||||||
"textLength": 2
|
"textLength": 0
|
||||||
|
},
|
||||||
|
"operator": {
|
||||||
|
"kind": "AmpersandToken",
|
||||||
|
"textLength": 1
|
||||||
|
},
|
||||||
|
"rightOperand": {
|
||||||
|
"Variable": {
|
||||||
|
"dollar": null,
|
||||||
|
"name": {
|
||||||
|
"kind": "VariableName",
|
||||||
|
"textLength": 2
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
// This is invalid. But (yield) & ($x) would be valid in PHP 7.
|
||||||
|
function example($x) {
|
||||||
|
yield & &$x;
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"kind": 0,
|
||||||
|
"message": "'Expression' expected.",
|
||||||
|
"start": 105,
|
||||||
|
"length": 0
|
||||||
|
}
|
||||||
|
]
|
|
@ -0,0 +1,125 @@
|
||||||
|
{
|
||||||
|
"SourceFileNode": {
|
||||||
|
"statementList": [
|
||||||
|
{
|
||||||
|
"InlineHtml": {
|
||||||
|
"scriptSectionEndTag": null,
|
||||||
|
"text": null,
|
||||||
|
"scriptSectionStartTag": {
|
||||||
|
"kind": "ScriptSectionStartTag",
|
||||||
|
"textLength": 6
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"FunctionDeclaration": {
|
||||||
|
"functionKeyword": {
|
||||||
|
"kind": "FunctionKeyword",
|
||||||
|
"textLength": 8
|
||||||
|
},
|
||||||
|
"byRefToken": null,
|
||||||
|
"name": {
|
||||||
|
"kind": "Name",
|
||||||
|
"textLength": 7
|
||||||
|
},
|
||||||
|
"openParen": {
|
||||||
|
"kind": "OpenParenToken",
|
||||||
|
"textLength": 1
|
||||||
|
},
|
||||||
|
"parameters": {
|
||||||
|
"ParameterDeclarationList": {
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"Parameter": {
|
||||||
|
"questionToken": null,
|
||||||
|
"typeDeclaration": null,
|
||||||
|
"byRefToken": null,
|
||||||
|
"dotDotDotToken": null,
|
||||||
|
"variableName": {
|
||||||
|
"kind": "VariableName",
|
||||||
|
"textLength": 2
|
||||||
|
},
|
||||||
|
"equalsToken": null,
|
||||||
|
"default": null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"closeParen": {
|
||||||
|
"kind": "CloseParenToken",
|
||||||
|
"textLength": 1
|
||||||
|
},
|
||||||
|
"colonToken": null,
|
||||||
|
"questionToken": null,
|
||||||
|
"returnType": null,
|
||||||
|
"compoundStatementOrSemicolon": {
|
||||||
|
"CompoundStatementNode": {
|
||||||
|
"openBrace": {
|
||||||
|
"kind": "OpenBraceToken",
|
||||||
|
"textLength": 1
|
||||||
|
},
|
||||||
|
"statements": [
|
||||||
|
{
|
||||||
|
"ExpressionStatement": {
|
||||||
|
"expression": {
|
||||||
|
"BinaryExpression": {
|
||||||
|
"leftOperand": {
|
||||||
|
"BinaryExpression": {
|
||||||
|
"leftOperand": {
|
||||||
|
"YieldExpression": {
|
||||||
|
"yieldOrYieldFromKeyword": {
|
||||||
|
"kind": "YieldKeyword",
|
||||||
|
"textLength": 5
|
||||||
|
},
|
||||||
|
"arrayElement": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"operator": {
|
||||||
|
"kind": "AmpersandToken",
|
||||||
|
"textLength": 1
|
||||||
|
},
|
||||||
|
"rightOperand": {
|
||||||
|
"error": "MissingToken",
|
||||||
|
"kind": "Expression",
|
||||||
|
"textLength": 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"operator": {
|
||||||
|
"kind": "AmpersandToken",
|
||||||
|
"textLength": 1
|
||||||
|
},
|
||||||
|
"rightOperand": {
|
||||||
|
"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,6 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
// This is parsed as (yield) && ($x).
|
||||||
|
function example($x) {
|
||||||
|
yield &&$x;
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
[]
|
|
@ -0,0 +1,112 @@
|
||||||
|
{
|
||||||
|
"SourceFileNode": {
|
||||||
|
"statementList": [
|
||||||
|
{
|
||||||
|
"InlineHtml": {
|
||||||
|
"scriptSectionEndTag": null,
|
||||||
|
"text": null,
|
||||||
|
"scriptSectionStartTag": {
|
||||||
|
"kind": "ScriptSectionStartTag",
|
||||||
|
"textLength": 6
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"FunctionDeclaration": {
|
||||||
|
"functionKeyword": {
|
||||||
|
"kind": "FunctionKeyword",
|
||||||
|
"textLength": 8
|
||||||
|
},
|
||||||
|
"byRefToken": null,
|
||||||
|
"name": {
|
||||||
|
"kind": "Name",
|
||||||
|
"textLength": 7
|
||||||
|
},
|
||||||
|
"openParen": {
|
||||||
|
"kind": "OpenParenToken",
|
||||||
|
"textLength": 1
|
||||||
|
},
|
||||||
|
"parameters": {
|
||||||
|
"ParameterDeclarationList": {
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"Parameter": {
|
||||||
|
"questionToken": null,
|
||||||
|
"typeDeclaration": null,
|
||||||
|
"byRefToken": null,
|
||||||
|
"dotDotDotToken": null,
|
||||||
|
"variableName": {
|
||||||
|
"kind": "VariableName",
|
||||||
|
"textLength": 2
|
||||||
|
},
|
||||||
|
"equalsToken": null,
|
||||||
|
"default": null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"closeParen": {
|
||||||
|
"kind": "CloseParenToken",
|
||||||
|
"textLength": 1
|
||||||
|
},
|
||||||
|
"colonToken": null,
|
||||||
|
"questionToken": null,
|
||||||
|
"returnType": null,
|
||||||
|
"compoundStatementOrSemicolon": {
|
||||||
|
"CompoundStatementNode": {
|
||||||
|
"openBrace": {
|
||||||
|
"kind": "OpenBraceToken",
|
||||||
|
"textLength": 1
|
||||||
|
},
|
||||||
|
"statements": [
|
||||||
|
{
|
||||||
|
"ExpressionStatement": {
|
||||||
|
"expression": {
|
||||||
|
"BinaryExpression": {
|
||||||
|
"leftOperand": {
|
||||||
|
"YieldExpression": {
|
||||||
|
"yieldOrYieldFromKeyword": {
|
||||||
|
"kind": "YieldKeyword",
|
||||||
|
"textLength": 5
|
||||||
|
},
|
||||||
|
"arrayElement": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"operator": {
|
||||||
|
"kind": "AmpersandAmpersandToken",
|
||||||
|
"textLength": 2
|
||||||
|
},
|
||||||
|
"rightOperand": {
|
||||||
|
"Variable": {
|
||||||
|
"dollar": null,
|
||||||
|
"name": {
|
||||||
|
"kind": "VariableName",
|
||||||
|
"textLength": 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"semicolon": {
|
||||||
|
"kind": "SemicolonToken",
|
||||||
|
"textLength": 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"closeBrace": {
|
||||||
|
"kind": "CloseBraceToken",
|
||||||
|
"textLength": 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"endOfFileToken": {
|
||||||
|
"kind": "EndOfFileToken",
|
||||||
|
"textLength": 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
// TODO technically should fail
|
// Fails with the message "';' expected.", "Unexpected '=>'"
|
||||||
function gen() {
|
function gen() {
|
||||||
yield from 1 => 2;
|
yield from 1 => 2;
|
||||||
}
|
}
|
|
@ -1 +1,14 @@
|
||||||
[]
|
[
|
||||||
|
{
|
||||||
|
"kind": 0,
|
||||||
|
"message": "';' expected.",
|
||||||
|
"start": 101,
|
||||||
|
"length": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"kind": 0,
|
||||||
|
"message": "Unexpected '=>'",
|
||||||
|
"start": 102,
|
||||||
|
"length": 2
|
||||||
|
}
|
||||||
|
]
|
|
@ -51,18 +51,8 @@
|
||||||
},
|
},
|
||||||
"arrayElement": {
|
"arrayElement": {
|
||||||
"ArrayElement": {
|
"ArrayElement": {
|
||||||
"elementKey": {
|
"elementKey": null,
|
||||||
"NumericLiteral": {
|
"arrowToken": null,
|
||||||
"children": {
|
|
||||||
"kind": "IntegerLiteralToken",
|
|
||||||
"textLength": 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"arrowToken": {
|
|
||||||
"kind": "DoubleArrowToken",
|
|
||||||
"textLength": 2
|
|
||||||
},
|
|
||||||
"byRef": null,
|
"byRef": null,
|
||||||
"elementValue": {
|
"elementValue": {
|
||||||
"NumericLiteral": {
|
"NumericLiteral": {
|
||||||
|
@ -76,6 +66,28 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"semicolon": {
|
||||||
|
"error": "MissingToken",
|
||||||
|
"kind": "SemicolonToken",
|
||||||
|
"textLength": 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"error": "SkippedToken",
|
||||||
|
"kind": "DoubleArrowToken",
|
||||||
|
"textLength": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ExpressionStatement": {
|
||||||
|
"expression": {
|
||||||
|
"NumericLiteral": {
|
||||||
|
"children": {
|
||||||
|
"kind": "IntegerLiteralToken",
|
||||||
|
"textLength": 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"semicolon": {
|
"semicolon": {
|
||||||
"kind": "SemicolonToken",
|
"kind": "SemicolonToken",
|
||||||
"textLength": 1
|
"textLength": 1
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
// TODO technically should fail
|
// Fails with the messages "';' expected.", "Unexpected '=>'"
|
||||||
function gen() {
|
function gen() {
|
||||||
yield from $i => $a;
|
yield from $i => $a;
|
||||||
}
|
}
|
|
@ -1 +1,14 @@
|
||||||
[]
|
[
|
||||||
|
{
|
||||||
|
"kind": 0,
|
||||||
|
"message": "';' expected.",
|
||||||
|
"start": 103,
|
||||||
|
"length": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"kind": 0,
|
||||||
|
"message": "Unexpected '=>'",
|
||||||
|
"start": 104,
|
||||||
|
"length": 2
|
||||||
|
}
|
||||||
|
]
|
|
@ -51,19 +51,8 @@
|
||||||
},
|
},
|
||||||
"arrayElement": {
|
"arrayElement": {
|
||||||
"ArrayElement": {
|
"ArrayElement": {
|
||||||
"elementKey": {
|
"elementKey": null,
|
||||||
"Variable": {
|
"arrowToken": null,
|
||||||
"dollar": null,
|
|
||||||
"name": {
|
|
||||||
"kind": "VariableName",
|
|
||||||
"textLength": 2
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"arrowToken": {
|
|
||||||
"kind": "DoubleArrowToken",
|
|
||||||
"textLength": 2
|
|
||||||
},
|
|
||||||
"byRef": null,
|
"byRef": null,
|
||||||
"elementValue": {
|
"elementValue": {
|
||||||
"Variable": {
|
"Variable": {
|
||||||
|
@ -78,6 +67,29 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"semicolon": {
|
||||||
|
"error": "MissingToken",
|
||||||
|
"kind": "SemicolonToken",
|
||||||
|
"textLength": 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"error": "SkippedToken",
|
||||||
|
"kind": "DoubleArrowToken",
|
||||||
|
"textLength": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ExpressionStatement": {
|
||||||
|
"expression": {
|
||||||
|
"Variable": {
|
||||||
|
"dollar": null,
|
||||||
|
"name": {
|
||||||
|
"kind": "VariableName",
|
||||||
|
"textLength": 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"semicolon": {
|
"semicolon": {
|
||||||
"kind": "SemicolonToken",
|
"kind": "SemicolonToken",
|
||||||
"textLength": 1
|
"textLength": 1
|
||||||
|
|
|
@ -1,8 +1 @@
|
||||||
[
|
[]
|
||||||
{
|
|
||||||
"kind": 0,
|
|
||||||
"message": "'Expression' expected.",
|
|
||||||
"start": 33,
|
|
||||||
"length": 0
|
|
||||||
}
|
|
||||||
]
|
|
|
@ -49,18 +49,7 @@
|
||||||
"kind": "YieldKeyword",
|
"kind": "YieldKeyword",
|
||||||
"textLength": 5
|
"textLength": 5
|
||||||
},
|
},
|
||||||
"arrayElement": {
|
"arrayElement": null
|
||||||
"ArrayElement": {
|
|
||||||
"elementKey": null,
|
|
||||||
"arrowToken": null,
|
|
||||||
"byRef": null,
|
|
||||||
"elementValue": {
|
|
||||||
"error": "MissingToken",
|
|
||||||
"kind": "Expression",
|
|
||||||
"textLength": 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"semicolon": {
|
"semicolon": {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
// TODO should fail
|
// Fails with the message "'Expression' expected."
|
||||||
function gen() {
|
function gen() {
|
||||||
yield from;
|
yield from;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
{
|
{
|
||||||
"kind": 0,
|
"kind": 0,
|
||||||
"message": "'Expression' expected.",
|
"message": "'Expression' expected.",
|
||||||
"start": 58,
|
"start": 89,
|
||||||
"length": 0
|
"length": 0
|
||||||
}
|
}
|
||||||
]
|
]
|
|
@ -1,6 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
// TODO `return yield` should fail
|
// TODO `return yield` should fail in php5
|
||||||
function gen() {
|
function gen() {
|
||||||
return yield a();
|
return yield a();
|
||||||
}
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче