mirror of
https://github.com/phabelio/PHP-Parser.git
synced 2024-11-26 20:14:46 +01:00
Add useConsistentVariableNodes mode
The parameter case is a bit weird, because the subnode is called "name" here, rather than "var". Nothing we can do about that in this version though. The two parser options might be merged. I've kept it separate, because I think this variable representation should become the default (or even only representation) in the future, while I'm less sure about the Identifier thing.
This commit is contained in:
parent
122f449960
commit
a947e731c3
@ -36,12 +36,12 @@ semi_reserved:
|
||||
;
|
||||
|
||||
identifier_ex:
|
||||
T_STRING { $$ = makeIdent($1); }
|
||||
| semi_reserved { $$ = makeIdent($1); }
|
||||
T_STRING { $$ = maybeMakeIdent($1); }
|
||||
| semi_reserved { $$ = maybeMakeIdent($1); }
|
||||
;
|
||||
|
||||
identifier:
|
||||
T_STRING { $$ = makeIdent($1); }
|
||||
T_STRING { $$ = maybeMakeIdent($1); }
|
||||
;
|
||||
|
||||
namespace_name_parts:
|
||||
@ -53,6 +53,10 @@ namespace_name:
|
||||
namespace_name_parts { $$ = Name[$1]; }
|
||||
;
|
||||
|
||||
plain_variable:
|
||||
T_VARIABLE { $$ = maybeMakeVar(parseVar($1)); }
|
||||
;
|
||||
|
||||
top_statement:
|
||||
statement { $$ = $1; }
|
||||
| function_declaration_statement { $$ = $1; }
|
||||
@ -209,8 +213,8 @@ catches:
|
||||
;
|
||||
|
||||
catch:
|
||||
T_CATCH '(' name T_VARIABLE ')' '{' inner_statement_list '}'
|
||||
{ $$ = Stmt\Catch_[array($3), parseVar($4), $7]; }
|
||||
T_CATCH '(' name plain_variable ')' '{' inner_statement_list '}'
|
||||
{ $$ = Stmt\Catch_[array($3), $4, $7]; }
|
||||
;
|
||||
|
||||
optional_finally:
|
||||
@ -372,16 +376,16 @@ non_empty_parameter_list:
|
||||
;
|
||||
|
||||
parameter:
|
||||
optional_param_type optional_ref optional_ellipsis T_VARIABLE
|
||||
{ $$ = Node\Param[parseVar($4), null, $1, $2, $3]; $this->checkParam($$); }
|
||||
| optional_param_type optional_ref optional_ellipsis T_VARIABLE '=' static_scalar
|
||||
{ $$ = Node\Param[parseVar($4), $6, $1, $2, $3]; $this->checkParam($$); }
|
||||
optional_param_type optional_ref optional_ellipsis plain_variable
|
||||
{ $$ = Node\Param[$4, null, $1, $2, $3]; $this->checkParam($$); }
|
||||
| optional_param_type optional_ref optional_ellipsis plain_variable '=' static_scalar
|
||||
{ $$ = Node\Param[$4, $6, $1, $2, $3]; $this->checkParam($$); }
|
||||
;
|
||||
|
||||
type:
|
||||
name { $$ = $1; }
|
||||
| T_ARRAY { $$ = makeIdent('array'); }
|
||||
| T_CALLABLE { $$ = makeIdent('callable'); }
|
||||
| T_ARRAY { $$ = maybeMakeIdent('array'); }
|
||||
| T_CALLABLE { $$ = maybeMakeIdent('callable'); }
|
||||
;
|
||||
|
||||
optional_param_type:
|
||||
@ -428,8 +432,8 @@ static_var_list:
|
||||
;
|
||||
|
||||
static_var:
|
||||
T_VARIABLE { $$ = Stmt\StaticVar[parseVar($1), null]; }
|
||||
| T_VARIABLE '=' static_scalar { $$ = Stmt\StaticVar[parseVar($1), $3]; }
|
||||
plain_variable { $$ = Stmt\StaticVar[$1, null]; }
|
||||
| plain_variable '=' static_scalar { $$ = Stmt\StaticVar[$1, $3]; }
|
||||
;
|
||||
|
||||
class_statement_list:
|
||||
@ -673,7 +677,7 @@ lexical_var_list:
|
||||
;
|
||||
|
||||
lexical_var:
|
||||
optional_ref T_VARIABLE { $$ = Expr\ClosureUse[parseVar($2), $1]; }
|
||||
optional_ref plain_variable { $$ = Expr\ClosureUse[$2, $1]; }
|
||||
;
|
||||
|
||||
function_call:
|
||||
|
@ -36,12 +36,12 @@ semi_reserved:
|
||||
;
|
||||
|
||||
identifier_ex:
|
||||
T_STRING { $$ = makeIdent($1); }
|
||||
| semi_reserved { $$ = makeIdent($1); }
|
||||
T_STRING { $$ = maybeMakeIdent($1); }
|
||||
| semi_reserved { $$ = maybeMakeIdent($1); }
|
||||
;
|
||||
|
||||
identifier:
|
||||
T_STRING { $$ = makeIdent($1); }
|
||||
T_STRING { $$ = maybeMakeIdent($1); }
|
||||
;
|
||||
|
||||
namespace_name_parts:
|
||||
@ -53,6 +53,10 @@ namespace_name:
|
||||
namespace_name_parts { $$ = Name[$1]; }
|
||||
;
|
||||
|
||||
plain_variable:
|
||||
T_VARIABLE { $$ = maybeMakeVar(parseVar($1)); }
|
||||
;
|
||||
|
||||
top_statement:
|
||||
statement { $$ = $1; }
|
||||
| function_declaration_statement { $$ = $1; }
|
||||
@ -210,8 +214,8 @@ name_union:
|
||||
;
|
||||
|
||||
catch:
|
||||
T_CATCH '(' name_union T_VARIABLE ')' '{' inner_statement_list '}'
|
||||
{ $$ = Stmt\Catch_[$3, parseVar($4), $7]; }
|
||||
T_CATCH '(' name_union plain_variable ')' '{' inner_statement_list '}'
|
||||
{ $$ = Stmt\Catch_[$3, $4, $7]; }
|
||||
;
|
||||
|
||||
optional_finally:
|
||||
@ -374,10 +378,10 @@ non_empty_parameter_list:
|
||||
;
|
||||
|
||||
parameter:
|
||||
optional_param_type optional_ref optional_ellipsis T_VARIABLE
|
||||
{ $$ = Node\Param[parseVar($4), null, $1, $2, $3]; $this->checkParam($$); }
|
||||
| optional_param_type optional_ref optional_ellipsis T_VARIABLE '=' expr
|
||||
{ $$ = Node\Param[parseVar($4), $6, $1, $2, $3]; $this->checkParam($$); }
|
||||
optional_param_type optional_ref optional_ellipsis plain_variable
|
||||
{ $$ = Node\Param[$4, null, $1, $2, $3]; $this->checkParam($$); }
|
||||
| optional_param_type optional_ref optional_ellipsis plain_variable '=' expr
|
||||
{ $$ = Node\Param[$4, $6, $1, $2, $3]; $this->checkParam($$); }
|
||||
;
|
||||
|
||||
type_expr:
|
||||
@ -387,8 +391,8 @@ type_expr:
|
||||
|
||||
type:
|
||||
name { $$ = $this->handleBuiltinTypes($1); }
|
||||
| T_ARRAY { $$ = makeIdent('array'); }
|
||||
| T_CALLABLE { $$ = makeIdent('callable'); }
|
||||
| T_ARRAY { $$ = maybeMakeIdent('array'); }
|
||||
| T_CALLABLE { $$ = maybeMakeIdent('callable'); }
|
||||
;
|
||||
|
||||
optional_param_type:
|
||||
@ -432,8 +436,8 @@ static_var_list:
|
||||
;
|
||||
|
||||
static_var:
|
||||
T_VARIABLE { $$ = Stmt\StaticVar[parseVar($1), null]; }
|
||||
| T_VARIABLE '=' expr { $$ = Stmt\StaticVar[parseVar($1), $3]; }
|
||||
plain_variable { $$ = Stmt\StaticVar[$1, null]; }
|
||||
| plain_variable '=' expr { $$ = Stmt\StaticVar[$1, $3]; }
|
||||
;
|
||||
|
||||
class_statement_list:
|
||||
@ -647,7 +651,7 @@ lexical_var_list:
|
||||
;
|
||||
|
||||
lexical_var:
|
||||
optional_ref T_VARIABLE { $$ = Expr\ClosureUse[parseVar($2), $1]; }
|
||||
optional_ref plain_variable { $$ = Expr\ClosureUse[$2, $1]; }
|
||||
;
|
||||
|
||||
function_call:
|
||||
|
@ -210,13 +210,20 @@ function resolveMacros($code) {
|
||||
. 'array_merge($attrs[\'comments\'], $stmts[0]->getAttribute(\'comments\', []))); }';
|
||||
}
|
||||
|
||||
if ('makeIdent' == $name) {
|
||||
if ('maybeMakeIdent' == $name) {
|
||||
assertArgs(1, $args, $name);
|
||||
|
||||
return '($this->useIdentifierNodes ? new Node\Identifier(' . $args[0] . ', '
|
||||
. '$this->startAttributeStack[#1] + $this->endAttributes) : ' . $args[0] . ')';
|
||||
}
|
||||
|
||||
if ('maybeMakeVar' == $name) {
|
||||
assertArgs(1, $args, $name);
|
||||
|
||||
return '($this->useConsistentVariableNodes ? new Expr\Variable(' . $args[0] . ', '
|
||||
. '$this->startAttributeStack[#1] + $this->endAttributes) : ' . $args[0] . ')';
|
||||
}
|
||||
|
||||
return $matches[0];
|
||||
},
|
||||
$code
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -113,20 +113,26 @@ abstract class ParserAbstract implements Parser
|
||||
|
||||
/** @var bool Whether to create Identifier nodes for non-namespaced names */
|
||||
protected $useIdentifierNodes;
|
||||
/** @var bool Whether to consistently use Variable nodes */
|
||||
protected $useConsistentVariableNodes;
|
||||
|
||||
/**
|
||||
* Creates a parser instance.
|
||||
*
|
||||
* Options: If "useIdentifierNodes" is enabled, the parser will create Identifier nodes for
|
||||
* non-namespaced names. Otherwise plain strings will be used.
|
||||
* Options:
|
||||
* * useIdentifierNodes: If this option is enabled, the parser will create Identifier nodes for
|
||||
* non-namespaced names. Otherwise plain strings will be used.
|
||||
* * useConsistentVariableNodes: If this option is enabled, the parser will create Variable
|
||||
* nodes in more places (like function parameters, catch clause variables, etc.)
|
||||
*
|
||||
* @param Lexer $lexer A lexer
|
||||
* @param array $options Options array. Currently only "useIdentifierNodes" is supporter.
|
||||
* @param array $options Options array.
|
||||
*/
|
||||
public function __construct(Lexer $lexer, array $options = array()) {
|
||||
$this->lexer = $lexer;
|
||||
$this->errors = array();
|
||||
$this->useIdentifierNodes = !empty($options['useIdentifierNodes']);
|
||||
$this->useConsistentVariableNodes = !empty($options['useConsistentVariableNodes']);
|
||||
|
||||
if (isset($options['throwOnError'])) {
|
||||
throw new \LogicException(
|
||||
|
@ -16,7 +16,10 @@ class CodeParsingTest extends CodeTestAbstract
|
||||
$modes = [];
|
||||
}
|
||||
|
||||
$parserOptions = ['useIdentifierNodes' => isset($modes['ident'])];
|
||||
$parserOptions = [
|
||||
'useIdentifierNodes' => isset($modes['ident']),
|
||||
'useConsistentVariableNodes' => isset($modes['consistentVars']),
|
||||
];
|
||||
|
||||
$lexer = new Lexer\Emulative(array('usedAttributes' => array(
|
||||
'startLine', 'endLine', 'startFilePos', 'endFilePos', 'comments'
|
||||
|
106
test/code/parser/consistentVarMode.test
Normal file
106
test/code/parser/consistentVarMode.test
Normal file
@ -0,0 +1,106 @@
|
||||
Consistent variable mode
|
||||
-----
|
||||
<?php
|
||||
|
||||
function test($param1, $param2 = 0) {
|
||||
static $foo, $bar = 0;
|
||||
}
|
||||
|
||||
function() use ($foo, &$bar) {};
|
||||
|
||||
try {} catch (Exception $var) {}
|
||||
-----
|
||||
!!consistentVars
|
||||
array(
|
||||
0: Stmt_Function(
|
||||
byRef: false
|
||||
name: test
|
||||
params: array(
|
||||
0: Param(
|
||||
type: null
|
||||
byRef: false
|
||||
variadic: false
|
||||
name: Expr_Variable(
|
||||
name: param1
|
||||
)
|
||||
default: null
|
||||
)
|
||||
1: Param(
|
||||
type: null
|
||||
byRef: false
|
||||
variadic: false
|
||||
name: Expr_Variable(
|
||||
name: param2
|
||||
)
|
||||
default: Scalar_LNumber(
|
||||
value: 0
|
||||
)
|
||||
)
|
||||
)
|
||||
returnType: null
|
||||
stmts: array(
|
||||
0: Stmt_Static(
|
||||
vars: array(
|
||||
0: Stmt_StaticVar(
|
||||
name: Expr_Variable(
|
||||
name: foo
|
||||
)
|
||||
default: null
|
||||
)
|
||||
1: Stmt_StaticVar(
|
||||
name: Expr_Variable(
|
||||
name: bar
|
||||
)
|
||||
default: Scalar_LNumber(
|
||||
value: 0
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
1: Expr_Closure(
|
||||
static: false
|
||||
byRef: false
|
||||
params: array(
|
||||
)
|
||||
uses: array(
|
||||
0: Expr_ClosureUse(
|
||||
var: Expr_Variable(
|
||||
name: foo
|
||||
)
|
||||
byRef: false
|
||||
)
|
||||
1: Expr_ClosureUse(
|
||||
var: Expr_Variable(
|
||||
name: bar
|
||||
)
|
||||
byRef: true
|
||||
)
|
||||
)
|
||||
returnType: null
|
||||
stmts: array(
|
||||
)
|
||||
)
|
||||
2: Stmt_TryCatch(
|
||||
stmts: array(
|
||||
)
|
||||
catches: array(
|
||||
0: Stmt_Catch(
|
||||
types: array(
|
||||
0: Name(
|
||||
parts: array(
|
||||
0: Exception
|
||||
)
|
||||
)
|
||||
)
|
||||
var: Expr_Variable(
|
||||
name: var
|
||||
)
|
||||
stmts: array(
|
||||
)
|
||||
)
|
||||
)
|
||||
finally: null
|
||||
)
|
||||
)
|
Loading…
Reference in New Issue
Block a user