From c115f64cb57153357c5baf71d83e4f518d61fbec Mon Sep 17 00:00:00 2001 From: bruno DA SILVA Date: Thu, 2 Jan 2020 14:12:42 +0100 Subject: [PATCH] =?UTF-8?q?N=C2=B02154=20-=20Security=20breach?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- composer.json | 25 +- composer.lock | 63 +- core/config.class.inc.php | 48 +- core/iTopConfigParser.php | 117 + datamodels/2.x/itop-config/config.php | 54 +- .../2.x/itop-config/module.itop-config.php | 5 +- .../src/Validator/ConfigNodesVisitor.php | 143 + .../src/Validator/iTopConfigAstValidator.php | 44 + .../Validator/iTopConfigSyntaxValidator.php | 105 + .../Validator/iTopConfigAstValidatorTest.php | 98 + .../iTopConfigSyntaxValidatorTest.php | 51 + lib/bin/php-parse | 1 + lib/composer/autoload_classmap.php | 216 +- lib/composer/autoload_psr4.php | 1 + lib/composer/autoload_static.php | 221 +- lib/composer/installed.json | 53 + lib/nikic/php-parser/.gitignore | 4 + lib/nikic/php-parser/.travis.yml | 31 + lib/nikic/php-parser/CHANGELOG.md | 422 +++ lib/nikic/php-parser/LICENSE | 31 + lib/nikic/php-parser/README.md | 99 + lib/nikic/php-parser/UPGRADE-1.0.md | 121 + lib/nikic/php-parser/UPGRADE-2.0.md | 74 + lib/nikic/php-parser/UPGRADE-3.0.md | 160 + lib/nikic/php-parser/bin/php-parse | 202 ++ lib/nikic/php-parser/composer.json | 30 + .../php-parser/doc/0_Introduction.markdown | 80 + .../doc/2_Usage_of_basic_components.markdown | 438 +++ ...3_Other_node_tree_representations.markdown | 330 ++ .../php-parser/doc/4_Code_generation.markdown | 84 + .../doc/component/Error_handling.markdown | 75 + .../php-parser/doc/component/Lexer.markdown | 152 + lib/nikic/php-parser/grammar/README.md | 28 + lib/nikic/php-parser/grammar/parser.template | 103 + lib/nikic/php-parser/grammar/php5.y | 1009 ++++++ lib/nikic/php-parser/grammar/php7.y | 965 +++++ .../php-parser/grammar/rebuildParsers.php | 263 ++ lib/nikic/php-parser/grammar/tokens.template | 17 + lib/nikic/php-parser/grammar/tokens.y | 113 + .../php-parser/lib/PhpParser/Autoloader.php | 40 + .../php-parser/lib/PhpParser/Builder.php | 13 + .../lib/PhpParser/Builder/Class_.php | 121 + .../lib/PhpParser/Builder/Declaration.php | 42 + .../lib/PhpParser/Builder/FunctionLike.php | 75 + .../lib/PhpParser/Builder/Function_.php | 49 + .../lib/PhpParser/Builder/Interface_.php | 80 + .../lib/PhpParser/Builder/Method.php | 128 + .../lib/PhpParser/Builder/Namespace_.php | 44 + .../lib/PhpParser/Builder/Param.php | 91 + .../lib/PhpParser/Builder/Property.php | 111 + .../lib/PhpParser/Builder/Trait_.php | 59 + .../php-parser/lib/PhpParser/Builder/Use_.php | 58 + .../lib/PhpParser/BuilderAbstract.php | 175 + .../lib/PhpParser/BuilderFactory.php | 127 + .../php-parser/lib/PhpParser/Comment.php | 140 + .../php-parser/lib/PhpParser/Comment/Doc.php | 7 + lib/nikic/php-parser/lib/PhpParser/Error.php | 166 + .../php-parser/lib/PhpParser/ErrorHandler.php | 13 + .../lib/PhpParser/ErrorHandler/Collecting.php | 46 + .../lib/PhpParser/ErrorHandler/Throwing.php | 18 + lib/nikic/php-parser/lib/PhpParser/Lexer.php | 381 ++ .../lib/PhpParser/Lexer/Emulative.php | 174 + lib/nikic/php-parser/lib/PhpParser/Node.php | 88 + .../php-parser/lib/PhpParser/Node/Arg.php | 34 + .../php-parser/lib/PhpParser/Node/Const_.php | 30 + .../php-parser/lib/PhpParser/Node/Expr.php | 9 + .../lib/PhpParser/Node/Expr/ArrayDimFetch.php | 30 + .../lib/PhpParser/Node/Expr/ArrayItem.php | 34 + .../lib/PhpParser/Node/Expr/Array_.php | 30 + .../lib/PhpParser/Node/Expr/Assign.php | 30 + .../lib/PhpParser/Node/Expr/AssignOp.php | 30 + .../Node/Expr/AssignOp/BitwiseAnd.php | 9 + .../Node/Expr/AssignOp/BitwiseOr.php | 9 + .../Node/Expr/AssignOp/BitwiseXor.php | 9 + .../PhpParser/Node/Expr/AssignOp/Concat.php | 9 + .../lib/PhpParser/Node/Expr/AssignOp/Div.php | 9 + .../PhpParser/Node/Expr/AssignOp/Minus.php | 9 + .../lib/PhpParser/Node/Expr/AssignOp/Mod.php | 9 + .../lib/PhpParser/Node/Expr/AssignOp/Mul.php | 9 + .../lib/PhpParser/Node/Expr/AssignOp/Plus.php | 9 + .../lib/PhpParser/Node/Expr/AssignOp/Pow.php | 9 + .../Node/Expr/AssignOp/ShiftLeft.php | 9 + .../Node/Expr/AssignOp/ShiftRight.php | 9 + .../lib/PhpParser/Node/Expr/AssignRef.php | 30 + .../lib/PhpParser/Node/Expr/BinaryOp.php | 30 + .../Node/Expr/BinaryOp/BitwiseAnd.php | 9 + .../Node/Expr/BinaryOp/BitwiseOr.php | 9 + .../Node/Expr/BinaryOp/BitwiseXor.php | 9 + .../Node/Expr/BinaryOp/BooleanAnd.php | 9 + .../Node/Expr/BinaryOp/BooleanOr.php | 9 + .../PhpParser/Node/Expr/BinaryOp/Coalesce.php | 9 + .../PhpParser/Node/Expr/BinaryOp/Concat.php | 9 + .../lib/PhpParser/Node/Expr/BinaryOp/Div.php | 9 + .../PhpParser/Node/Expr/BinaryOp/Equal.php | 9 + .../PhpParser/Node/Expr/BinaryOp/Greater.php | 9 + .../Node/Expr/BinaryOp/GreaterOrEqual.php | 9 + .../Node/Expr/BinaryOp/Identical.php | 9 + .../Node/Expr/BinaryOp/LogicalAnd.php | 9 + .../Node/Expr/BinaryOp/LogicalOr.php | 9 + .../Node/Expr/BinaryOp/LogicalXor.php | 9 + .../PhpParser/Node/Expr/BinaryOp/Minus.php | 9 + .../lib/PhpParser/Node/Expr/BinaryOp/Mod.php | 9 + .../lib/PhpParser/Node/Expr/BinaryOp/Mul.php | 9 + .../PhpParser/Node/Expr/BinaryOp/NotEqual.php | 9 + .../Node/Expr/BinaryOp/NotIdentical.php | 9 + .../lib/PhpParser/Node/Expr/BinaryOp/Plus.php | 9 + .../lib/PhpParser/Node/Expr/BinaryOp/Pow.php | 9 + .../Node/Expr/BinaryOp/ShiftLeft.php | 9 + .../Node/Expr/BinaryOp/ShiftRight.php | 9 + .../PhpParser/Node/Expr/BinaryOp/Smaller.php | 9 + .../Node/Expr/BinaryOp/SmallerOrEqual.php | 9 + .../Node/Expr/BinaryOp/Spaceship.php | 9 + .../lib/PhpParser/Node/Expr/BitwiseNot.php | 26 + .../lib/PhpParser/Node/Expr/BooleanNot.php | 26 + .../lib/PhpParser/Node/Expr/Cast.php | 26 + .../lib/PhpParser/Node/Expr/Cast/Array_.php | 9 + .../lib/PhpParser/Node/Expr/Cast/Bool_.php | 9 + .../lib/PhpParser/Node/Expr/Cast/Double.php | 9 + .../lib/PhpParser/Node/Expr/Cast/Int_.php | 9 + .../lib/PhpParser/Node/Expr/Cast/Object_.php | 9 + .../lib/PhpParser/Node/Expr/Cast/String_.php | 9 + .../lib/PhpParser/Node/Expr/Cast/Unset_.php | 9 + .../PhpParser/Node/Expr/ClassConstFetch.php | 31 + .../lib/PhpParser/Node/Expr/Clone_.php | 26 + .../lib/PhpParser/Node/Expr/Closure.php | 65 + .../lib/PhpParser/Node/Expr/ClosureUse.php | 30 + .../lib/PhpParser/Node/Expr/ConstFetch.php | 27 + .../lib/PhpParser/Node/Expr/Empty_.php | 26 + .../lib/PhpParser/Node/Expr/Error.php | 27 + .../lib/PhpParser/Node/Expr/ErrorSuppress.php | 26 + .../lib/PhpParser/Node/Expr/Eval_.php | 26 + .../lib/PhpParser/Node/Expr/Exit_.php | 30 + .../lib/PhpParser/Node/Expr/FuncCall.php | 31 + .../lib/PhpParser/Node/Expr/Include_.php | 35 + .../lib/PhpParser/Node/Expr/Instanceof_.php | 31 + .../lib/PhpParser/Node/Expr/Isset_.php | 26 + .../lib/PhpParser/Node/Expr/List_.php | 26 + .../lib/PhpParser/Node/Expr/MethodCall.php | 35 + .../lib/PhpParser/Node/Expr/New_.php | 31 + .../lib/PhpParser/Node/Expr/PostDec.php | 26 + .../lib/PhpParser/Node/Expr/PostInc.php | 26 + .../lib/PhpParser/Node/Expr/PreDec.php | 26 + .../lib/PhpParser/Node/Expr/PreInc.php | 26 + .../lib/PhpParser/Node/Expr/Print_.php | 26 + .../lib/PhpParser/Node/Expr/PropertyFetch.php | 30 + .../lib/PhpParser/Node/Expr/ShellExec.php | 26 + .../lib/PhpParser/Node/Expr/StaticCall.php | 35 + .../Node/Expr/StaticPropertyFetch.php | 31 + .../lib/PhpParser/Node/Expr/Ternary.php | 34 + .../lib/PhpParser/Node/Expr/UnaryMinus.php | 26 + .../lib/PhpParser/Node/Expr/UnaryPlus.php | 26 + .../lib/PhpParser/Node/Expr/Variable.php | 26 + .../lib/PhpParser/Node/Expr/YieldFrom.php | 26 + .../lib/PhpParser/Node/Expr/Yield_.php | 30 + .../lib/PhpParser/Node/FunctionLike.php | 36 + .../php-parser/lib/PhpParser/Node/Name.php | 196 + .../PhpParser/Node/Name/FullyQualified.php | 42 + .../lib/PhpParser/Node/Name/Relative.php | 42 + .../lib/PhpParser/Node/NullableType.php | 26 + .../php-parser/lib/PhpParser/Node/Param.php | 42 + .../php-parser/lib/PhpParser/Node/Scalar.php | 7 + .../lib/PhpParser/Node/Scalar/DNumber.php | 64 + .../lib/PhpParser/Node/Scalar/Encapsed.php | 27 + .../Node/Scalar/EncapsedStringPart.php | 26 + .../lib/PhpParser/Node/Scalar/LNumber.php | 67 + .../lib/PhpParser/Node/Scalar/MagicConst.php | 28 + .../Node/Scalar/MagicConst/Class_.php | 12 + .../PhpParser/Node/Scalar/MagicConst/Dir.php | 12 + .../PhpParser/Node/Scalar/MagicConst/File.php | 12 + .../Node/Scalar/MagicConst/Function_.php | 12 + .../PhpParser/Node/Scalar/MagicConst/Line.php | 12 + .../Node/Scalar/MagicConst/Method.php | 12 + .../Node/Scalar/MagicConst/Namespace_.php | 12 + .../Node/Scalar/MagicConst/Trait_.php | 12 + .../lib/PhpParser/Node/Scalar/String_.php | 153 + .../php-parser/lib/PhpParser/Node/Stmt.php | 9 + .../lib/PhpParser/Node/Stmt/Break_.php | 26 + .../lib/PhpParser/Node/Stmt/Case_.php | 30 + .../lib/PhpParser/Node/Stmt/Catch_.php | 34 + .../lib/PhpParser/Node/Stmt/ClassConst.php | 47 + .../lib/PhpParser/Node/Stmt/ClassLike.php | 44 + .../lib/PhpParser/Node/Stmt/ClassMethod.php | 94 + .../lib/PhpParser/Node/Stmt/Class_.php | 99 + .../lib/PhpParser/Node/Stmt/Const_.php | 26 + .../lib/PhpParser/Node/Stmt/Continue_.php | 26 + .../PhpParser/Node/Stmt/DeclareDeclare.php | 30 + .../lib/PhpParser/Node/Stmt/Declare_.php | 30 + .../lib/PhpParser/Node/Stmt/Do_.php | 30 + .../lib/PhpParser/Node/Stmt/Echo_.php | 26 + .../lib/PhpParser/Node/Stmt/ElseIf_.php | 30 + .../lib/PhpParser/Node/Stmt/Else_.php | 26 + .../lib/PhpParser/Node/Stmt/Finally_.php | 26 + .../lib/PhpParser/Node/Stmt/For_.php | 39 + .../lib/PhpParser/Node/Stmt/Foreach_.php | 43 + .../lib/PhpParser/Node/Stmt/Function_.php | 60 + .../lib/PhpParser/Node/Stmt/Global_.php | 26 + .../lib/PhpParser/Node/Stmt/Goto_.php | 26 + .../lib/PhpParser/Node/Stmt/GroupUse.php | 35 + .../lib/PhpParser/Node/Stmt/HaltCompiler.php | 26 + .../lib/PhpParser/Node/Stmt/If_.php | 39 + .../lib/PhpParser/Node/Stmt/InlineHTML.php | 26 + .../lib/PhpParser/Node/Stmt/Interface_.php | 31 + .../lib/PhpParser/Node/Stmt/Label.php | 26 + .../lib/PhpParser/Node/Stmt/Namespace_.php | 34 + .../lib/PhpParser/Node/Stmt/Nop.php | 13 + .../lib/PhpParser/Node/Stmt/Property.php | 51 + .../PhpParser/Node/Stmt/PropertyProperty.php | 30 + .../lib/PhpParser/Node/Stmt/Return_.php | 26 + .../lib/PhpParser/Node/Stmt/StaticVar.php | 30 + .../lib/PhpParser/Node/Stmt/Static_.php | 26 + .../lib/PhpParser/Node/Stmt/Switch_.php | 30 + .../lib/PhpParser/Node/Stmt/Throw_.php | 26 + .../lib/PhpParser/Node/Stmt/TraitUse.php | 31 + .../Node/Stmt/TraitUseAdaptation.php | 13 + .../Node/Stmt/TraitUseAdaptation/Alias.php | 34 + .../Stmt/TraitUseAdaptation/Precedence.php | 30 + .../lib/PhpParser/Node/Stmt/Trait_.php | 26 + .../lib/PhpParser/Node/Stmt/TryCatch.php | 34 + .../lib/PhpParser/Node/Stmt/Unset_.php | 26 + .../lib/PhpParser/Node/Stmt/UseUse.php | 38 + .../lib/PhpParser/Node/Stmt/Use_.php | 43 + .../lib/PhpParser/Node/Stmt/While_.php | 30 + .../php-parser/lib/PhpParser/NodeAbstract.php | 120 + .../php-parser/lib/PhpParser/NodeDumper.php | 196 + .../lib/PhpParser/NodeTraverser.php | 204 ++ .../lib/PhpParser/NodeTraverserInterface.php | 30 + .../php-parser/lib/PhpParser/NodeVisitor.php | 72 + .../PhpParser/NodeVisitor/NameResolver.php | 272 ++ .../lib/PhpParser/NodeVisitorAbstract.php | 14 + lib/nikic/php-parser/lib/PhpParser/Parser.php | 17 + .../lib/PhpParser/Parser/Multiple.php | 54 + .../php-parser/lib/PhpParser/Parser/Php5.php | 3153 +++++++++++++++++ .../php-parser/lib/PhpParser/Parser/Php7.php | 2872 +++++++++++++++ .../lib/PhpParser/Parser/Tokens.php | 144 + .../lib/PhpParser/ParserAbstract.php | 729 ++++ .../lib/PhpParser/ParserFactory.php | 43 + .../lib/PhpParser/PrettyPrinter/Standard.php | 977 +++++ .../lib/PhpParser/PrettyPrinterAbstract.php | 348 ++ .../php-parser/lib/PhpParser/Serializer.php | 18 + .../lib/PhpParser/Serializer/XML.php | 89 + .../php-parser/lib/PhpParser/Unserializer.php | 18 + .../lib/PhpParser/Unserializer/XML.php | 155 + lib/nikic/php-parser/lib/bootstrap.php | 6 + lib/nikic/php-parser/phpunit.xml.dist | 24 + lib/nikic/php-parser/test_old/run-php-src.sh | 4 + lib/nikic/php-parser/test_old/run.php | 220 ++ test/core/iTopConfigParserTest.php | 179 + 247 files changed, 22350 insertions(+), 91 deletions(-) create mode 100644 core/iTopConfigParser.php create mode 100644 datamodels/2.x/itop-config/src/Validator/ConfigNodesVisitor.php create mode 100644 datamodels/2.x/itop-config/src/Validator/iTopConfigAstValidator.php create mode 100644 datamodels/2.x/itop-config/src/Validator/iTopConfigSyntaxValidator.php create mode 100644 datamodels/2.x/itop-config/test/Validator/iTopConfigAstValidatorTest.php create mode 100644 datamodels/2.x/itop-config/test/Validator/iTopConfigSyntaxValidatorTest.php create mode 120000 lib/bin/php-parse create mode 100644 lib/nikic/php-parser/.gitignore create mode 100644 lib/nikic/php-parser/.travis.yml create mode 100644 lib/nikic/php-parser/CHANGELOG.md create mode 100644 lib/nikic/php-parser/LICENSE create mode 100644 lib/nikic/php-parser/README.md create mode 100644 lib/nikic/php-parser/UPGRADE-1.0.md create mode 100644 lib/nikic/php-parser/UPGRADE-2.0.md create mode 100644 lib/nikic/php-parser/UPGRADE-3.0.md create mode 100755 lib/nikic/php-parser/bin/php-parse create mode 100644 lib/nikic/php-parser/composer.json create mode 100644 lib/nikic/php-parser/doc/0_Introduction.markdown create mode 100644 lib/nikic/php-parser/doc/2_Usage_of_basic_components.markdown create mode 100644 lib/nikic/php-parser/doc/3_Other_node_tree_representations.markdown create mode 100644 lib/nikic/php-parser/doc/4_Code_generation.markdown create mode 100644 lib/nikic/php-parser/doc/component/Error_handling.markdown create mode 100644 lib/nikic/php-parser/doc/component/Lexer.markdown create mode 100644 lib/nikic/php-parser/grammar/README.md create mode 100644 lib/nikic/php-parser/grammar/parser.template create mode 100644 lib/nikic/php-parser/grammar/php5.y create mode 100644 lib/nikic/php-parser/grammar/php7.y create mode 100644 lib/nikic/php-parser/grammar/rebuildParsers.php create mode 100644 lib/nikic/php-parser/grammar/tokens.template create mode 100644 lib/nikic/php-parser/grammar/tokens.y create mode 100644 lib/nikic/php-parser/lib/PhpParser/Autoloader.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Builder.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Builder/Class_.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Builder/Declaration.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Builder/FunctionLike.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Builder/Function_.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Builder/Interface_.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Builder/Method.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Builder/Namespace_.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Builder/Param.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Builder/Property.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Builder/Trait_.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Builder/Use_.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/BuilderAbstract.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/BuilderFactory.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Comment.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Comment/Doc.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Error.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/ErrorHandler.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/ErrorHandler/Collecting.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/ErrorHandler/Throwing.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Lexer.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Lexer/Emulative.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Arg.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Const_.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Expr.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Expr/ArrayDimFetch.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Expr/ArrayItem.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Expr/Array_.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Expr/Assign.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/BitwiseAnd.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/BitwiseOr.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/BitwiseXor.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/Concat.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/Div.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/Minus.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/Mod.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/Mul.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/Plus.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/Pow.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/ShiftLeft.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/ShiftRight.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Expr/AssignRef.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/BitwiseAnd.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/BitwiseOr.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/BitwiseXor.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/BooleanAnd.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/BooleanOr.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Coalesce.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Concat.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Div.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Equal.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Greater.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/GreaterOrEqual.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Identical.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/LogicalAnd.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/LogicalOr.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/LogicalXor.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Minus.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Mod.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Mul.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/NotEqual.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/NotIdentical.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Plus.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Pow.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/ShiftLeft.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/ShiftRight.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Smaller.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/SmallerOrEqual.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Spaceship.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Expr/BitwiseNot.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Expr/BooleanNot.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Expr/Cast.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Expr/Cast/Array_.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Expr/Cast/Bool_.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Expr/Cast/Double.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Expr/Cast/Int_.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Expr/Cast/Object_.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Expr/Cast/String_.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Expr/Cast/Unset_.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Expr/ClassConstFetch.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Expr/Clone_.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Expr/Closure.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Expr/ClosureUse.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Expr/ConstFetch.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Expr/Empty_.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Expr/Error.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Expr/ErrorSuppress.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Expr/Eval_.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Expr/Exit_.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Expr/FuncCall.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Expr/Include_.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Expr/Instanceof_.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Expr/Isset_.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Expr/List_.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Expr/MethodCall.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Expr/New_.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Expr/PostDec.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Expr/PostInc.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Expr/PreDec.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Expr/PreInc.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Expr/Print_.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Expr/PropertyFetch.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Expr/ShellExec.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Expr/StaticCall.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Expr/StaticPropertyFetch.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Expr/Ternary.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Expr/UnaryMinus.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Expr/UnaryPlus.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Expr/Variable.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Expr/YieldFrom.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Expr/Yield_.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/FunctionLike.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Name.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Name/FullyQualified.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Name/Relative.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/NullableType.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Param.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Scalar.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Scalar/DNumber.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Scalar/Encapsed.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Scalar/EncapsedStringPart.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Scalar/LNumber.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Scalar/MagicConst.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Scalar/MagicConst/Class_.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Scalar/MagicConst/Dir.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Scalar/MagicConst/File.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Scalar/MagicConst/Function_.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Scalar/MagicConst/Line.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Scalar/MagicConst/Method.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Scalar/MagicConst/Namespace_.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Scalar/MagicConst/Trait_.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Scalar/String_.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Stmt.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Break_.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Case_.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Catch_.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Stmt/ClassConst.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Stmt/ClassLike.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Stmt/ClassMethod.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Class_.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Const_.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Continue_.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Stmt/DeclareDeclare.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Declare_.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Do_.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Echo_.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Stmt/ElseIf_.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Else_.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Finally_.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Stmt/For_.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Foreach_.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Function_.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Global_.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Goto_.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Stmt/GroupUse.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Stmt/HaltCompiler.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Stmt/If_.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Stmt/InlineHTML.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Interface_.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Label.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Namespace_.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Nop.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Property.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Stmt/PropertyProperty.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Return_.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Stmt/StaticVar.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Static_.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Switch_.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Throw_.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Stmt/TraitUse.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Stmt/TraitUseAdaptation.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Stmt/TraitUseAdaptation/Alias.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Stmt/TraitUseAdaptation/Precedence.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Trait_.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Stmt/TryCatch.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Unset_.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Stmt/UseUse.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Use_.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Node/Stmt/While_.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/NodeAbstract.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/NodeDumper.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/NodeTraverser.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/NodeTraverserInterface.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/NodeVisitor.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/NodeVisitor/NameResolver.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/NodeVisitorAbstract.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Parser.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Parser/Multiple.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Parser/Php5.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Parser/Php7.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Parser/Tokens.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/ParserAbstract.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/ParserFactory.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/PrettyPrinter/Standard.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/PrettyPrinterAbstract.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Serializer.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Serializer/XML.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Unserializer.php create mode 100644 lib/nikic/php-parser/lib/PhpParser/Unserializer/XML.php create mode 100644 lib/nikic/php-parser/lib/bootstrap.php create mode 100644 lib/nikic/php-parser/phpunit.xml.dist create mode 100755 lib/nikic/php-parser/test_old/run-php-src.sh create mode 100644 lib/nikic/php-parser/test_old/run.php create mode 100644 test/core/iTopConfigParserTest.php diff --git a/composer.json b/composer.json index 973e0753f..bcaa784c9 100644 --- a/composer.json +++ b/composer.json @@ -3,26 +3,25 @@ "license": "AGPLv3", "require": { "php": ">=5.6.0", - "ext-soap": "*", + "ext-ctype": "*", + "ext-dom": "*", + "ext-gd": "*", + "ext-iconv": "*", "ext-json": "*", "ext-mysqli": "*", - "ext-dom": "*", - "ext-iconv": "*", - "ext-gd": "*", - "ext-ctype": "*", - + "ext-soap": "*", + "combodo/tcpdf": "6.3.0", + "nikic/php-parser": "^3.1", + "pear/archive_tar": "1.4.7", + "pelago/emogrifier": "2.1.0", "scssphp/scssphp": "1.0.0", "swiftmailer/swiftmailer": "5.4.9", - "pelago/emogrifier": "2.1.0", - "combodo/tcpdf": "6.3.0", - "pear/archive_tar": "1.4.7", - "symfony/console": "3.4.*", "symfony/dotenv": "3.4.*", "symfony/framework-bundle": "3.4.*", + "symfony/polyfill-php70": "1.*", "symfony/twig-bundle": "3.4.*", - "symfony/yaml": "3.4.*", - "symfony/polyfill-php70": "1.*" + "symfony/yaml": "3.4.*" }, "require-dev": { "symfony/stopwatch": "3.4.*", @@ -75,4 +74,4 @@ "require": "3.4.*" } } -} \ No newline at end of file +} diff --git a/composer.lock b/composer.lock index 3b6b08928..66515333f 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "554231903f26fc1944cd123d64adb410", + "content-hash": "9328341521a6423daadfe2851ba35454", "packages": [ { "name": "combodo/tcpdf", @@ -61,6 +61,57 @@ "homepage": "https://github.com/combodo-itop-libs/TCPDF", "time": "2019-08-16T08:14:13+00:00" }, + { + "name": "nikic/php-parser", + "version": "v3.1.5", + "source": { + "type": "git", + "url": "https://github.com/nikic/PHP-Parser.git", + "reference": "bb87e28e7d7b8d9a7fda231d37457c9210faf6ce" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/bb87e28e7d7b8d9a7fda231d37457c9210faf6ce", + "reference": "bb87e28e7d7b8d9a7fda231d37457c9210faf6ce", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": ">=5.5" + }, + "require-dev": { + "phpunit/phpunit": "~4.0|~5.0" + }, + "bin": [ + "bin/php-parse" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "psr-4": { + "PhpParser\\": "lib/PhpParser" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Nikita Popov" + } + ], + "description": "A PHP parser written in PHP", + "keywords": [ + "parser", + "php" + ], + "time": "2018-02-28T20:30:58+00:00" + }, { "name": "paragonie/random_compat", "version": "v2.0.18", @@ -2521,13 +2572,13 @@ "prefer-lowest": false, "platform": { "php": ">=5.6.0", - "ext-soap": "*", + "ext-ctype": "*", + "ext-dom": "*", + "ext-gd": "*", + "ext-iconv": "*", "ext-json": "*", "ext-mysqli": "*", - "ext-dom": "*", - "ext-iconv": "*", - "ext-gd": "*", - "ext-ctype": "*" + "ext-soap": "*" }, "platform-dev": [], "platform-overrides": { diff --git a/core/config.class.inc.php b/core/config.class.inc.php index 24819a8d7..c1b3062f4 100644 --- a/core/config.class.inc.php +++ b/core/config.class.inc.php @@ -1249,6 +1249,10 @@ class Config 'show_in_conf_sample' => false, ), ); + /** + * @var \Combodo\iTop\Config\Parser\iTopConfigParser|null + */ + private $oItopConfigParser; public function IsProperty($sPropCode) { @@ -1889,6 +1893,20 @@ class Config { $sFileName = $this->m_sFile; } + $oHandle = fopen($this->m_sFile, 'r'); + $index = 0; + while (!flock($oHandle, LOCK_SH)) + { + if ($index > 50){ + throw new ConfigException("Could not read to configuration file", array('file' => $this->m_sFile)); + } + usleep(100000); + $index++; + } + + $this->oItopConfigParser = new iTopConfigParser(file_get_contents($this->m_sFile)); + flock($oHandle, LOCK_UN); + $hFile = @fopen($sFileName, 'w'); if ($hFile !== false) { @@ -1969,7 +1987,7 @@ class Config $sSeenAs = $aSettingInfo['value'] ? 'true' : 'false'; break; default: - $sSeenAs = self::PrettyVarExport($aSettingInfo['value'], "\t"); + $sSeenAs = self::PrettyVarExport($this->oItopConfigParser->GetVarValue('MySettings', $sPropCode),$aSettingInfo['value'], "\t"); } fwrite($hFile, "\n"); if (isset($aSettingInfo['description'])) @@ -1984,7 +2002,7 @@ class Config $default = $default ? 'true' : 'false'; } fwrite($hFile, - "\t//\tdefault: ".self::PrettyVarExport($aSettingInfo['default'], "\t//\t\t", true)."\n"); + "\t//\tdefault: ".self::PrettyVarExport($this->oItopConfigParser->GetVarValue('MySettings', $sPropCode), $aSettingInfo['default'], "\t//\t\t", true)."\n"); } fwrite($hFile, "\t'$sPropCode' => $sSeenAs,\n"); } @@ -1999,7 +2017,7 @@ class Config fwrite($hFile, "\t'$sModule' => array (\n"); foreach ($aProperties as $sProperty => $value) { - $sNiceExport = self::PrettyVarExport($value, "\t\t"); + $sNiceExport = self::PrettyVarExport($this->oItopConfigParser->GetVarValue('MyModuleSettings', $sProperty), $value, "\t\t"); fwrite($hFile, "\t\t'$sProperty' => $sNiceExport,\n"); } fwrite($hFile, "\t),\n"); @@ -2012,12 +2030,20 @@ class Config fwrite($hFile, " *\n"); fwrite($hFile, " */\n"); fwrite($hFile, "\$MyModules = array(\n"); - fwrite($hFile, "\t'addons' => array (\n"); - foreach ($this->m_aAddons as $sKey => $sFile) + $aParserValue = $this->oItopConfigParser->GetVarValue('MyModules', 'addons'); + if ($aParserValue['found']) { - fwrite($hFile, "\t\t'$sKey' => '$sFile',\n"); + fwrite($hFile, "\t'addons' => {$aParserValue['value']},\n"); + } + else + { + fwrite($hFile, "\t'addons' => array (\n"); + foreach ($this->m_aAddons as $sKey => $sFile) + { + fwrite($hFile, "\t\t'$sKey' => '$sFile',\n"); + } + fwrite($hFile, "\t),\n"); } - fwrite($hFile, "\t),\n"); fwrite($hFile, ");\n"); fwrite($hFile, '?'.'>'); // Avoid perturbing the syntax highlighting ! @@ -2211,6 +2237,7 @@ class Config /** * Pretty format a var_export'ed value so that (if possible) the identation is preserved on every line * + * @param array $aParserValue * @param mixed $value The value to export * @param string $sIndentation The string to use to indent the text * @param bool $bForceIndentation Forces the identation (enven if it breaks/changes an eval, for example to ouput a @@ -2218,8 +2245,13 @@ class Config * * @return string The indented export string */ - protected static function PrettyVarExport($value, $sIndentation, $bForceIndentation = false) + protected static function PrettyVarExport($aParserValue, $value, $sIndentation, $bForceIndentation = false) { + if ($aParserValue['found']) + { + return $aParserValue['value']; + } + $sExport = var_export($value, true); $sNiceExport = str_replace(array("\r\n", "\n", "\r"), "\n".$sIndentation, trim($sExport)); if (!$bForceIndentation) diff --git a/core/iTopConfigParser.php b/core/iTopConfigParser.php new file mode 100644 index 000000000..74702a6c0 --- /dev/null +++ b/core/iTopConfigParser.php @@ -0,0 +1,117 @@ +create(ParserFactory::PREFER_PHP7); + + $this->browseFile($oParser, $sConfig); + } + + /** + * @return array + */ + public function GetVarsMap() + { + return $this->aVarsMap; + } + + /** + * @param $arrayName + * @param $key + * + * @return array + */ + public function GetVarValue($arrayName, $key) + { + if (!array_key_exists($arrayName, $this->aVarsMap)){ + return array('found' => false); + } + $arrayValue = $this->aVarsMap[$arrayName]; + if (!array_key_exists($key, $arrayValue)){ + return array('found' => false); + } + return array('found' => true, + 'value' => $arrayValue[$key]); + } + + /** + * @param \PhpParser\Parser $oParser + * @param $sConfig + * + * @return \Combodo\iTop\Config\Validator\ConfigNodesVisitor + */ + private function browseFile(\PhpParser\Parser $oParser, $sConfig) + { + $prettyPrinter = new Standard(); + + $this->aVarsMap = array( + 'MySettings' => array(), + 'MyModuleSettings' => array(), + 'MyModules' => array(), + ); + + try + { + $aNodes = $oParser->parse($sConfig); + } + catch (\Error $e) + { + $sMessage = Dict::Format('config-parse-error', $e->getMessage(), $e->getLine()); + $this->oException = new \Exception($sMessage, 0, $e); + } + + foreach ($aNodes as $oAssignation) + { + if (! $oAssignation instanceof Assign) + { + continue; + } + + $sCurrentRootVar = $oAssignation->var->name; + if (!array_key_exists($sCurrentRootVar, $this->aVarsMap)) + { + continue; + } + $aCurrentRootVarMap =& $this->aVarsMap[$sCurrentRootVar]; + + foreach ($oAssignation->expr->items as $oItem) + { + $sValue = $prettyPrinter->prettyPrintExpr($oItem->value); + $aCurrentRootVarMap[$oItem->key->value] = $sValue; + } + } + } +} \ No newline at end of file diff --git a/datamodels/2.x/itop-config/config.php b/datamodels/2.x/itop-config/config.php index bfff5096e..44d30cccd 100644 --- a/datamodels/2.x/itop-config/config.php +++ b/datamodels/2.x/itop-config/config.php @@ -24,54 +24,30 @@ * @license http://opensource.org/licenses/AGPL-3.0 */ +use Combodo\iTop\Config\Validator\iTopConfigAstValidator; +use Combodo\iTop\Config\Validator\iTopConfigSyntaxValidator; + require_once(APPROOT.'application/application.inc.php'); require_once(APPROOT.'application/itopwebpage.class.inc.php'); require_once(APPROOT.'application/startup.inc.php'); require_once(APPROOT.'application/loginwebpage.class.inc.php'); +/** + * @param $sContents + * @param $oP + * + * @throws \Exception + */ function TestConfig($sContents, $oP) { - try - { - ini_set('display_errors', 1); - ob_start(); - // in PHP < 7.0.0 syntax errors are in output - // in PHP >= 7.0.0 syntax errors are thrown as Error - $sSafeContent = preg_replace(array('#^\s*<\?php#', '#\?>\s*$#'), '', $sContents); - eval('if(0){'.trim($sSafeContent).'}'); - $sNoise = trim(ob_get_contents()); - ob_end_clean(); - } - catch (Error $e) - { - // ParseError only thrown in PHP7 - throw new Exception('Error in configuration: '.$e->getMessage().' at line '.$e->getLine()); - } - if (strlen($sNoise) > 0) - { - if (preg_match("/(Error|Parse error|Notice|Warning): (.+) in \S+ : eval\(\)'d code on line (\d+)/i", strip_tags($sNoise), $aMatches)) - { - $sMessage = $aMatches[2]; - $sLine = $aMatches[3]; - $iLine = (int) $sLine; + /// 1- first check if there is no malicious code + $oiTopConfigValidator = new iTopConfigAstValidator(); + $oiTopConfigValidator->validate($sContents); - // Highlight the line - $aLines = explode("\n", $sContents); - $iStart = 0; - for ($i = 0 ; $i < $iLine - 1; $i++) $iStart += strlen($aLines[$i]); - $iEnd = $iStart + strlen($aLines[$iLine - 1]); - $iTotalLines = count($aLines); - - $sMessage = Dict::Format('config-parse-error', $sMessage, $sLine); - throw new Exception($sMessage); - } - else - { - // Note: sNoise is an html output, but so far it was ok for me (e.g. showing the entire call stack) - throw new Exception('Syntax error in configuration file: '.$sNoise.''); - } - } + /// 2 - only after we are sure that there is no malicious cade, we can perform a syntax check! + $oiTopConfigValidator = new iTopConfigSyntaxValidator(); + $oiTopConfigValidator->validate($sContents, true); } /** diff --git a/datamodels/2.x/itop-config/module.itop-config.php b/datamodels/2.x/itop-config/module.itop-config.php index 979fcef20..0f070bbcc 100644 --- a/datamodels/2.x/itop-config/module.itop-config.php +++ b/datamodels/2.x/itop-config/module.itop-config.php @@ -20,7 +20,10 @@ SetupWebPage::AddModule( // 'datamodel' => array( 'model.itop-config.php', - ), + 'src/Validator/ConfigNodesVisitor.php', + 'src/Validator/iTopConfigAstValidator.php', + 'src/Validator/iTopConfigSyntaxValidator.php', +), 'webservice' => array(), 'dictionary' => array( 'en.dict.itop-config.php', diff --git a/datamodels/2.x/itop-config/src/Validator/ConfigNodesVisitor.php b/datamodels/2.x/itop-config/src/Validator/ConfigNodesVisitor.php new file mode 100644 index 000000000..04493fac8 --- /dev/null +++ b/datamodels/2.x/itop-config/src/Validator/ConfigNodesVisitor.php @@ -0,0 +1,143 @@ +aAllowedNodeClasses = array( + Node\Scalar::class, + + Node\Name::class, + + Node\Const_::class, + + Node\Expr\Array_::class, + Node\Expr\ArrayDimFetch::class, + Node\Expr\ArrayItem::class, + Node\Expr\Assign::class, + Node\Expr\AssignOp::class, + Node\Expr\AssignRef::class, + Node\Expr\BinaryOp::class, + Node\Expr\BitwiseNot::class, + Node\Expr\BooleanNot::class, + Node\Expr\Cast::class, + Node\Expr\ClassConstFetch::class, + Node\Expr\ConstFetch::class, + Node\Expr\Instanceof_::class, + Node\Expr\Isset_::class, + Node\Expr\List_::class, + Node\Expr\PostDec::class, + Node\Expr\PostInc::class, + Node\Expr\PreDec::class, + Node\Expr\PreInc::class, + Node\Expr\Print_::class, + Node\Expr\Ternary::class, + Node\Expr\UnaryMinus::class, + Node\Expr\UnaryPlus::class, + Node\Expr\Variable::class, + + Node\Stmt\Const_::class, + Node\Stmt\Global_::class, + ); + } + + /** + * @param \PhpParser\Node $node + * + * @return int|\PhpParser\Node|void|null + * @throws \Exception + */ + public function enterNode(Node $node) + { + $this->ValidateNode($node); + } + + /** + * @param \PhpParser\Node $node + * + * @throws \Exception + */ + public function ValidateNode(Node $node) + { + foreach ($this->aAllowedNodeClasses as $sAllowedNodeClass) + { + if ($node instanceof $sAllowedNodeClass) + { + return; + } + } + + $this->ThrowInvalidConf($node); + } + + /** + * @param \PhpParser\Node $node + * + * @throws \Exception + */ + private function ThrowInvalidConf(Node $node) + { + if (in_array('name', $node->getSubNodeNames())) + { + $sMessage = sprintf( + "Invalid configuration: %s of type %s is forbidden in line %d", + $node->name, + $node->getType(), + $node->getLine() + ); + } + elseif (in_array('class', $node->getSubNodeNames())) + { + + if (in_array('name', $node->class->getSubNodeNames())) + { + $sMessage = sprintf( + "Invalid configuration: usage of the class '%s' (%s) is forbidden in line %d", + is_object($node->class) ? $node->class->name : $node->class, + $node->getType(), + $node->getLine() + ); + } + else + { + $sMessage = sprintf( + "Invalid configuration: usage of %s is forbidden in line %d", + $node->getType(), + $node->getLine() + ); + } + } + elseif ($node->hasAttribute('name')) + { + $sMessage = sprintf( + "Invalid configuration: %s of type %s is forbidden in line %d", + $node->getAttribute('name'), + $node->getType(), + $node->getLine() + ); + } + else + { + $sMessage = sprintf( + "Invalid configuration: %s is forbidden in line %d", + $node->getType(), + $node->getLine() + ); + } + + throw new \Exception($sMessage); + } +} \ No newline at end of file diff --git a/datamodels/2.x/itop-config/src/Validator/iTopConfigAstValidator.php b/datamodels/2.x/itop-config/src/Validator/iTopConfigAstValidator.php new file mode 100644 index 000000000..cba632fb0 --- /dev/null +++ b/datamodels/2.x/itop-config/src/Validator/iTopConfigAstValidator.php @@ -0,0 +1,44 @@ +create(ParserFactory::PREFER_PHP7); + + $oNodeVisitor = new ConfigNodesVisitor(); + + try { + $aInitialNodes = $oParser->parse($sConfig); + } catch (\Error $e) { + $sMessage = 'Invalid configuration: '. \Dict::Format('config-parse-error', $e->getMessage(), $e->getLine()); + throw new \Exception($sMessage, 0, $e); + }catch (\Exception $e) { + $sMessage = 'Invalid configuration: '. \Dict::Format('config-parse-error', $e->getMessage(), $e->getLine()); + throw new \Exception($sMessage, 0, $e); + } + + $oTraverser = new NodeTraverser(); + $oTraverser->addVisitor($oNodeVisitor); + $oTraverser->traverse($aInitialNodes); + } +} \ No newline at end of file diff --git a/datamodels/2.x/itop-config/src/Validator/iTopConfigSyntaxValidator.php b/datamodels/2.x/itop-config/src/Validator/iTopConfigSyntaxValidator.php new file mode 100644 index 000000000..e7492e6c1 --- /dev/null +++ b/datamodels/2.x/itop-config/src/Validator/iTopConfigSyntaxValidator.php @@ -0,0 +1,105 @@ +CheckSyntaxSecure($sConfig); + } + elseif($bAllowUnsecure) + { + $this->CheckSyntaxNotSecure($sConfig); + } + else + { + throw new \Exception('Cannot check configuration syntax: PHP CLI is not accessible.'."\n".implode("\n", $aOutput)); + } + } + + /** + * This will use the php cli linter in order to check the syntax, + * + * The php cli may not be based on the same php version, but since the cron run using the cli, we can assume that it is well configured anyway... + * Also, the config syntax is very limited so there should not be a problem with checking the validity against another php version + * + * @param $sConfig + * @param $iReturnVar + * @param $aOutput + * + * @return array + */ + private function CheckSyntaxSecure($sConfig) + { + $sTempFile = tempnam(sys_get_temp_dir(), 'syntax_check_me_').'.temp.txt'; + file_put_contents($sTempFile, $sConfig); + exec("php -l $sTempFile 2>&1", $aOutput, $iReturnVar); + unlink($sTempFile); + + if ($iReturnVar != 0) + { + throw new \Exception(implode("\n", $aOutput)); + } + } + + /** + * @param $sRawConfig + */ + private function CheckSyntaxNotSecure($sRawConfig) + { + try + { + ini_set('display_errors', 1); + ob_start(); + // in PHP < 7.0.0 syntax errors are in output + // in PHP >= 7.0.0 syntax errors are thrown as Error + $sConfig = preg_replace(array('#^\s*<\?php#', '#\?>\s*$#'), '', $sRawConfig); + eval('if(0){'.trim($sConfig).'}'); + $sNoise = trim(ob_get_contents()); + ob_end_clean(); + } + catch (Error $e) + { + // ParseError only thrown in PHP7 + throw new Exception('Error in configuration: '.$e->getMessage().' at line '.$e->getLine()); + } + if (strlen($sNoise) > 0) + { + if (preg_match("/(Error|Parse error|Notice|Warning): (.+) in \S+ : eval\(\)'d code on line (\d+)/i", strip_tags($sNoise), $aMatches)) + { + $sMessage = $aMatches[2]; + $sLine = $aMatches[3]; + $sMessage = Dict::Format('config-parse-error', $sMessage, $sLine); + throw new Exception($sMessage); + } + else + { + // Note: sNoise is an html output, but so far it was ok for me (e.g. showing the entire call stack) + throw new Exception('Syntax error in configuration file: '.$sNoise.''); + } + } + } +} \ No newline at end of file diff --git a/datamodels/2.x/itop-config/test/Validator/iTopConfigAstValidatorTest.php b/datamodels/2.x/itop-config/test/Validator/iTopConfigAstValidatorTest.php new file mode 100644 index 000000000..9ede0bc19 --- /dev/null +++ b/datamodels/2.x/itop-config/test/Validator/iTopConfigAstValidatorTest.php @@ -0,0 +1,98 @@ +expectException(\Exception::class); + try{ + $oiTopConfigValidator->validate($sConf); + }catch (\Exception $e) + { + $this->assertStringStartsWith('Invalid configuration:', $e->getMessage()); + throw $e; + } + } + + + public function InvalidDataProvider() + { + return array( + 'invalid PHP' => array( + 'sConf' => ' array( + 'sConf' => ' array( + 'sConf' => ' array( + 'sConf' => ' array( + 'sConf' => ' array( + 'sConf' => '' + ), + ); + } + + + /** + * @dataProvider ValidDataProvider + * @doesNotPerformAssertions + * + * @param $sConf + * + * @throws \Exception + */ + public function testValid($sConf) + { + $oiTopConfigValidator = new iTopConfigAstValidator(); + + $oiTopConfigValidator->validate($sConf); + } + + public function ValidDataProvider() + { + return array( + 'simple code' => array( + 'sConf' => '' + ), + 'class constant' => array( + 'sConf' => 'validate("expectException(\Exception::class); + try{ + $oiTopConfigValidator->validate("", false); + }catch (\Exception $e) + { + $this->assertStringStartsWith('PHP Parse error: syntax error, unexpected \'zdadz\' (T_STRING)', $e->getMessage()); + throw $e; + } + } +} diff --git a/lib/bin/php-parse b/lib/bin/php-parse new file mode 120000 index 000000000..062d66a3e --- /dev/null +++ b/lib/bin/php-parse @@ -0,0 +1 @@ +../nikic/php-parser/bin/php-parse \ No newline at end of file diff --git a/lib/composer/autoload_classmap.php b/lib/composer/autoload_classmap.php index 0de1c9b77..ffe03bccb 100644 --- a/lib/composer/autoload_classmap.php +++ b/lib/composer/autoload_classmap.php @@ -362,6 +362,209 @@ return array( 'Pelago\\Emogrifier\\HtmlProcessor\\AbstractHtmlProcessor' => $vendorDir . '/pelago/emogrifier/src/Emogrifier/HtmlProcessor/AbstractHtmlProcessor.php', 'Pelago\\Emogrifier\\HtmlProcessor\\CssToAttributeConverter' => $vendorDir . '/pelago/emogrifier/src/Emogrifier/HtmlProcessor/CssToAttributeConverter.php', 'Pelago\\Emogrifier\\HtmlProcessor\\HtmlNormalizer' => $vendorDir . '/pelago/emogrifier/src/Emogrifier/HtmlProcessor/HtmlNormalizer.php', + 'PhpParser\\Autoloader' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Autoloader.php', + 'PhpParser\\Builder' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Builder.php', + 'PhpParser\\BuilderAbstract' => $vendorDir . '/nikic/php-parser/lib/PhpParser/BuilderAbstract.php', + 'PhpParser\\BuilderFactory' => $vendorDir . '/nikic/php-parser/lib/PhpParser/BuilderFactory.php', + 'PhpParser\\Builder\\Class_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Builder/Class_.php', + 'PhpParser\\Builder\\Declaration' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Builder/Declaration.php', + 'PhpParser\\Builder\\FunctionLike' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Builder/FunctionLike.php', + 'PhpParser\\Builder\\Function_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Builder/Function_.php', + 'PhpParser\\Builder\\Interface_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Builder/Interface_.php', + 'PhpParser\\Builder\\Method' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Builder/Method.php', + 'PhpParser\\Builder\\Namespace_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Builder/Namespace_.php', + 'PhpParser\\Builder\\Param' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Builder/Param.php', + 'PhpParser\\Builder\\Property' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Builder/Property.php', + 'PhpParser\\Builder\\Trait_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Builder/Trait_.php', + 'PhpParser\\Builder\\Use_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Builder/Use_.php', + 'PhpParser\\Comment' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Comment.php', + 'PhpParser\\Comment\\Doc' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Comment/Doc.php', + 'PhpParser\\Error' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Error.php', + 'PhpParser\\ErrorHandler' => $vendorDir . '/nikic/php-parser/lib/PhpParser/ErrorHandler.php', + 'PhpParser\\ErrorHandler\\Collecting' => $vendorDir . '/nikic/php-parser/lib/PhpParser/ErrorHandler/Collecting.php', + 'PhpParser\\ErrorHandler\\Throwing' => $vendorDir . '/nikic/php-parser/lib/PhpParser/ErrorHandler/Throwing.php', + 'PhpParser\\Lexer' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Lexer.php', + 'PhpParser\\Lexer\\Emulative' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Lexer/Emulative.php', + 'PhpParser\\Node' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node.php', + 'PhpParser\\NodeAbstract' => $vendorDir . '/nikic/php-parser/lib/PhpParser/NodeAbstract.php', + 'PhpParser\\NodeDumper' => $vendorDir . '/nikic/php-parser/lib/PhpParser/NodeDumper.php', + 'PhpParser\\NodeTraverser' => $vendorDir . '/nikic/php-parser/lib/PhpParser/NodeTraverser.php', + 'PhpParser\\NodeTraverserInterface' => $vendorDir . '/nikic/php-parser/lib/PhpParser/NodeTraverserInterface.php', + 'PhpParser\\NodeVisitor' => $vendorDir . '/nikic/php-parser/lib/PhpParser/NodeVisitor.php', + 'PhpParser\\NodeVisitorAbstract' => $vendorDir . '/nikic/php-parser/lib/PhpParser/NodeVisitorAbstract.php', + 'PhpParser\\NodeVisitor\\NameResolver' => $vendorDir . '/nikic/php-parser/lib/PhpParser/NodeVisitor/NameResolver.php', + 'PhpParser\\Node\\Arg' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Arg.php', + 'PhpParser\\Node\\Const_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Const_.php', + 'PhpParser\\Node\\Expr' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr.php', + 'PhpParser\\Node\\Expr\\ArrayDimFetch' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/ArrayDimFetch.php', + 'PhpParser\\Node\\Expr\\ArrayItem' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/ArrayItem.php', + 'PhpParser\\Node\\Expr\\Array_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/Array_.php', + 'PhpParser\\Node\\Expr\\Assign' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/Assign.php', + 'PhpParser\\Node\\Expr\\AssignOp' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp.php', + 'PhpParser\\Node\\Expr\\AssignOp\\BitwiseAnd' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/BitwiseAnd.php', + 'PhpParser\\Node\\Expr\\AssignOp\\BitwiseOr' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/BitwiseOr.php', + 'PhpParser\\Node\\Expr\\AssignOp\\BitwiseXor' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/BitwiseXor.php', + 'PhpParser\\Node\\Expr\\AssignOp\\Concat' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/Concat.php', + 'PhpParser\\Node\\Expr\\AssignOp\\Div' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/Div.php', + 'PhpParser\\Node\\Expr\\AssignOp\\Minus' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/Minus.php', + 'PhpParser\\Node\\Expr\\AssignOp\\Mod' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/Mod.php', + 'PhpParser\\Node\\Expr\\AssignOp\\Mul' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/Mul.php', + 'PhpParser\\Node\\Expr\\AssignOp\\Plus' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/Plus.php', + 'PhpParser\\Node\\Expr\\AssignOp\\Pow' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/Pow.php', + 'PhpParser\\Node\\Expr\\AssignOp\\ShiftLeft' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/ShiftLeft.php', + 'PhpParser\\Node\\Expr\\AssignOp\\ShiftRight' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/ShiftRight.php', + 'PhpParser\\Node\\Expr\\AssignRef' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/AssignRef.php', + 'PhpParser\\Node\\Expr\\BinaryOp' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp.php', + 'PhpParser\\Node\\Expr\\BinaryOp\\BitwiseAnd' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/BitwiseAnd.php', + 'PhpParser\\Node\\Expr\\BinaryOp\\BitwiseOr' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/BitwiseOr.php', + 'PhpParser\\Node\\Expr\\BinaryOp\\BitwiseXor' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/BitwiseXor.php', + 'PhpParser\\Node\\Expr\\BinaryOp\\BooleanAnd' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/BooleanAnd.php', + 'PhpParser\\Node\\Expr\\BinaryOp\\BooleanOr' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/BooleanOr.php', + 'PhpParser\\Node\\Expr\\BinaryOp\\Coalesce' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Coalesce.php', + 'PhpParser\\Node\\Expr\\BinaryOp\\Concat' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Concat.php', + 'PhpParser\\Node\\Expr\\BinaryOp\\Div' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Div.php', + 'PhpParser\\Node\\Expr\\BinaryOp\\Equal' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Equal.php', + 'PhpParser\\Node\\Expr\\BinaryOp\\Greater' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Greater.php', + 'PhpParser\\Node\\Expr\\BinaryOp\\GreaterOrEqual' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/GreaterOrEqual.php', + 'PhpParser\\Node\\Expr\\BinaryOp\\Identical' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Identical.php', + 'PhpParser\\Node\\Expr\\BinaryOp\\LogicalAnd' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/LogicalAnd.php', + 'PhpParser\\Node\\Expr\\BinaryOp\\LogicalOr' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/LogicalOr.php', + 'PhpParser\\Node\\Expr\\BinaryOp\\LogicalXor' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/LogicalXor.php', + 'PhpParser\\Node\\Expr\\BinaryOp\\Minus' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Minus.php', + 'PhpParser\\Node\\Expr\\BinaryOp\\Mod' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Mod.php', + 'PhpParser\\Node\\Expr\\BinaryOp\\Mul' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Mul.php', + 'PhpParser\\Node\\Expr\\BinaryOp\\NotEqual' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/NotEqual.php', + 'PhpParser\\Node\\Expr\\BinaryOp\\NotIdentical' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/NotIdentical.php', + 'PhpParser\\Node\\Expr\\BinaryOp\\Plus' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Plus.php', + 'PhpParser\\Node\\Expr\\BinaryOp\\Pow' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Pow.php', + 'PhpParser\\Node\\Expr\\BinaryOp\\ShiftLeft' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/ShiftLeft.php', + 'PhpParser\\Node\\Expr\\BinaryOp\\ShiftRight' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/ShiftRight.php', + 'PhpParser\\Node\\Expr\\BinaryOp\\Smaller' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Smaller.php', + 'PhpParser\\Node\\Expr\\BinaryOp\\SmallerOrEqual' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/SmallerOrEqual.php', + 'PhpParser\\Node\\Expr\\BinaryOp\\Spaceship' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Spaceship.php', + 'PhpParser\\Node\\Expr\\BitwiseNot' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/BitwiseNot.php', + 'PhpParser\\Node\\Expr\\BooleanNot' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/BooleanNot.php', + 'PhpParser\\Node\\Expr\\Cast' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/Cast.php', + 'PhpParser\\Node\\Expr\\Cast\\Array_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/Cast/Array_.php', + 'PhpParser\\Node\\Expr\\Cast\\Bool_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/Cast/Bool_.php', + 'PhpParser\\Node\\Expr\\Cast\\Double' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/Cast/Double.php', + 'PhpParser\\Node\\Expr\\Cast\\Int_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/Cast/Int_.php', + 'PhpParser\\Node\\Expr\\Cast\\Object_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/Cast/Object_.php', + 'PhpParser\\Node\\Expr\\Cast\\String_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/Cast/String_.php', + 'PhpParser\\Node\\Expr\\Cast\\Unset_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/Cast/Unset_.php', + 'PhpParser\\Node\\Expr\\ClassConstFetch' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/ClassConstFetch.php', + 'PhpParser\\Node\\Expr\\Clone_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/Clone_.php', + 'PhpParser\\Node\\Expr\\Closure' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/Closure.php', + 'PhpParser\\Node\\Expr\\ClosureUse' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/ClosureUse.php', + 'PhpParser\\Node\\Expr\\ConstFetch' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/ConstFetch.php', + 'PhpParser\\Node\\Expr\\Empty_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/Empty_.php', + 'PhpParser\\Node\\Expr\\Error' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/Error.php', + 'PhpParser\\Node\\Expr\\ErrorSuppress' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/ErrorSuppress.php', + 'PhpParser\\Node\\Expr\\Eval_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/Eval_.php', + 'PhpParser\\Node\\Expr\\Exit_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/Exit_.php', + 'PhpParser\\Node\\Expr\\FuncCall' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/FuncCall.php', + 'PhpParser\\Node\\Expr\\Include_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/Include_.php', + 'PhpParser\\Node\\Expr\\Instanceof_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/Instanceof_.php', + 'PhpParser\\Node\\Expr\\Isset_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/Isset_.php', + 'PhpParser\\Node\\Expr\\List_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/List_.php', + 'PhpParser\\Node\\Expr\\MethodCall' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/MethodCall.php', + 'PhpParser\\Node\\Expr\\New_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/New_.php', + 'PhpParser\\Node\\Expr\\PostDec' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/PostDec.php', + 'PhpParser\\Node\\Expr\\PostInc' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/PostInc.php', + 'PhpParser\\Node\\Expr\\PreDec' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/PreDec.php', + 'PhpParser\\Node\\Expr\\PreInc' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/PreInc.php', + 'PhpParser\\Node\\Expr\\Print_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/Print_.php', + 'PhpParser\\Node\\Expr\\PropertyFetch' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/PropertyFetch.php', + 'PhpParser\\Node\\Expr\\ShellExec' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/ShellExec.php', + 'PhpParser\\Node\\Expr\\StaticCall' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/StaticCall.php', + 'PhpParser\\Node\\Expr\\StaticPropertyFetch' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/StaticPropertyFetch.php', + 'PhpParser\\Node\\Expr\\Ternary' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/Ternary.php', + 'PhpParser\\Node\\Expr\\UnaryMinus' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/UnaryMinus.php', + 'PhpParser\\Node\\Expr\\UnaryPlus' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/UnaryPlus.php', + 'PhpParser\\Node\\Expr\\Variable' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/Variable.php', + 'PhpParser\\Node\\Expr\\YieldFrom' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/YieldFrom.php', + 'PhpParser\\Node\\Expr\\Yield_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/Yield_.php', + 'PhpParser\\Node\\FunctionLike' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/FunctionLike.php', + 'PhpParser\\Node\\Name' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Name.php', + 'PhpParser\\Node\\Name\\FullyQualified' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Name/FullyQualified.php', + 'PhpParser\\Node\\Name\\Relative' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Name/Relative.php', + 'PhpParser\\Node\\NullableType' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/NullableType.php', + 'PhpParser\\Node\\Param' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Param.php', + 'PhpParser\\Node\\Scalar' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Scalar.php', + 'PhpParser\\Node\\Scalar\\DNumber' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Scalar/DNumber.php', + 'PhpParser\\Node\\Scalar\\Encapsed' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Scalar/Encapsed.php', + 'PhpParser\\Node\\Scalar\\EncapsedStringPart' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Scalar/EncapsedStringPart.php', + 'PhpParser\\Node\\Scalar\\LNumber' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Scalar/LNumber.php', + 'PhpParser\\Node\\Scalar\\MagicConst' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Scalar/MagicConst.php', + 'PhpParser\\Node\\Scalar\\MagicConst\\Class_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Scalar/MagicConst/Class_.php', + 'PhpParser\\Node\\Scalar\\MagicConst\\Dir' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Scalar/MagicConst/Dir.php', + 'PhpParser\\Node\\Scalar\\MagicConst\\File' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Scalar/MagicConst/File.php', + 'PhpParser\\Node\\Scalar\\MagicConst\\Function_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Scalar/MagicConst/Function_.php', + 'PhpParser\\Node\\Scalar\\MagicConst\\Line' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Scalar/MagicConst/Line.php', + 'PhpParser\\Node\\Scalar\\MagicConst\\Method' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Scalar/MagicConst/Method.php', + 'PhpParser\\Node\\Scalar\\MagicConst\\Namespace_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Scalar/MagicConst/Namespace_.php', + 'PhpParser\\Node\\Scalar\\MagicConst\\Trait_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Scalar/MagicConst/Trait_.php', + 'PhpParser\\Node\\Scalar\\String_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Scalar/String_.php', + 'PhpParser\\Node\\Stmt' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Stmt.php', + 'PhpParser\\Node\\Stmt\\Break_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Break_.php', + 'PhpParser\\Node\\Stmt\\Case_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Case_.php', + 'PhpParser\\Node\\Stmt\\Catch_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Catch_.php', + 'PhpParser\\Node\\Stmt\\ClassConst' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Stmt/ClassConst.php', + 'PhpParser\\Node\\Stmt\\ClassLike' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Stmt/ClassLike.php', + 'PhpParser\\Node\\Stmt\\ClassMethod' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Stmt/ClassMethod.php', + 'PhpParser\\Node\\Stmt\\Class_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Class_.php', + 'PhpParser\\Node\\Stmt\\Const_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Const_.php', + 'PhpParser\\Node\\Stmt\\Continue_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Continue_.php', + 'PhpParser\\Node\\Stmt\\DeclareDeclare' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Stmt/DeclareDeclare.php', + 'PhpParser\\Node\\Stmt\\Declare_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Declare_.php', + 'PhpParser\\Node\\Stmt\\Do_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Do_.php', + 'PhpParser\\Node\\Stmt\\Echo_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Echo_.php', + 'PhpParser\\Node\\Stmt\\ElseIf_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Stmt/ElseIf_.php', + 'PhpParser\\Node\\Stmt\\Else_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Else_.php', + 'PhpParser\\Node\\Stmt\\Finally_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Finally_.php', + 'PhpParser\\Node\\Stmt\\For_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Stmt/For_.php', + 'PhpParser\\Node\\Stmt\\Foreach_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Foreach_.php', + 'PhpParser\\Node\\Stmt\\Function_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Function_.php', + 'PhpParser\\Node\\Stmt\\Global_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Global_.php', + 'PhpParser\\Node\\Stmt\\Goto_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Goto_.php', + 'PhpParser\\Node\\Stmt\\GroupUse' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Stmt/GroupUse.php', + 'PhpParser\\Node\\Stmt\\HaltCompiler' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Stmt/HaltCompiler.php', + 'PhpParser\\Node\\Stmt\\If_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Stmt/If_.php', + 'PhpParser\\Node\\Stmt\\InlineHTML' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Stmt/InlineHTML.php', + 'PhpParser\\Node\\Stmt\\Interface_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Interface_.php', + 'PhpParser\\Node\\Stmt\\Label' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Label.php', + 'PhpParser\\Node\\Stmt\\Namespace_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Namespace_.php', + 'PhpParser\\Node\\Stmt\\Nop' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Nop.php', + 'PhpParser\\Node\\Stmt\\Property' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Property.php', + 'PhpParser\\Node\\Stmt\\PropertyProperty' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Stmt/PropertyProperty.php', + 'PhpParser\\Node\\Stmt\\Return_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Return_.php', + 'PhpParser\\Node\\Stmt\\StaticVar' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Stmt/StaticVar.php', + 'PhpParser\\Node\\Stmt\\Static_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Static_.php', + 'PhpParser\\Node\\Stmt\\Switch_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Switch_.php', + 'PhpParser\\Node\\Stmt\\Throw_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Throw_.php', + 'PhpParser\\Node\\Stmt\\TraitUse' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Stmt/TraitUse.php', + 'PhpParser\\Node\\Stmt\\TraitUseAdaptation' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Stmt/TraitUseAdaptation.php', + 'PhpParser\\Node\\Stmt\\TraitUseAdaptation\\Alias' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Stmt/TraitUseAdaptation/Alias.php', + 'PhpParser\\Node\\Stmt\\TraitUseAdaptation\\Precedence' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Stmt/TraitUseAdaptation/Precedence.php', + 'PhpParser\\Node\\Stmt\\Trait_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Trait_.php', + 'PhpParser\\Node\\Stmt\\TryCatch' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Stmt/TryCatch.php', + 'PhpParser\\Node\\Stmt\\Unset_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Unset_.php', + 'PhpParser\\Node\\Stmt\\UseUse' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Stmt/UseUse.php', + 'PhpParser\\Node\\Stmt\\Use_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Use_.php', + 'PhpParser\\Node\\Stmt\\While_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Stmt/While_.php', + 'PhpParser\\Parser' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Parser.php', + 'PhpParser\\ParserAbstract' => $vendorDir . '/nikic/php-parser/lib/PhpParser/ParserAbstract.php', + 'PhpParser\\ParserFactory' => $vendorDir . '/nikic/php-parser/lib/PhpParser/ParserFactory.php', + 'PhpParser\\Parser\\Multiple' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Parser/Multiple.php', + 'PhpParser\\Parser\\Php5' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Parser/Php5.php', + 'PhpParser\\Parser\\Php7' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Parser/Php7.php', + 'PhpParser\\Parser\\Tokens' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Parser/Tokens.php', + 'PhpParser\\PrettyPrinterAbstract' => $vendorDir . '/nikic/php-parser/lib/PhpParser/PrettyPrinterAbstract.php', + 'PhpParser\\PrettyPrinter\\Standard' => $vendorDir . '/nikic/php-parser/lib/PhpParser/PrettyPrinter/Standard.php', + 'PhpParser\\Serializer' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Serializer.php', + 'PhpParser\\Serializer\\XML' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Serializer/XML.php', + 'PhpParser\\Unserializer' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Unserializer.php', + 'PhpParser\\Unserializer\\XML' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Unserializer/XML.php', 'PortalDispatcher' => $baseDir . '/application/portaldispatcher.class.inc.php', 'PortalURLMaker' => $baseDir . '/application/applicationcontext.class.inc.php', 'PrintableDataTable' => $baseDir . '/application/datatable.class.inc.php', @@ -383,9 +586,6 @@ return array( 'Psr\\Log\\LoggerInterface' => $vendorDir . '/psr/log/Psr/Log/LoggerInterface.php', 'Psr\\Log\\LoggerTrait' => $vendorDir . '/psr/log/Psr/Log/LoggerTrait.php', 'Psr\\Log\\NullLogger' => $vendorDir . '/psr/log/Psr/Log/NullLogger.php', - 'Psr\\Log\\Test\\DummyTest' => $vendorDir . '/psr/log/Psr/Log/Test/LoggerInterfaceTest.php', - 'Psr\\Log\\Test\\LoggerInterfaceTest' => $vendorDir . '/psr/log/Psr/Log/Test/LoggerInterfaceTest.php', - 'Psr\\Log\\Test\\TestLogger' => $vendorDir . '/psr/log/Psr/Log/Test/TestLogger.php', 'Psr\\SimpleCache\\CacheException' => $vendorDir . '/psr/simple-cache/src/CacheException.php', 'Psr\\SimpleCache\\CacheInterface' => $vendorDir . '/psr/simple-cache/src/CacheInterface.php', 'Psr\\SimpleCache\\InvalidArgumentException' => $vendorDir . '/psr/simple-cache/src/InvalidArgumentException.php', @@ -625,9 +825,6 @@ return array( 'Symfony\\Bundle\\FrameworkBundle\\Templating\\TemplateNameParser' => $vendorDir . '/symfony/framework-bundle/Templating/TemplateNameParser.php', 'Symfony\\Bundle\\FrameworkBundle\\Templating\\TemplateReference' => $vendorDir . '/symfony/framework-bundle/Templating/TemplateReference.php', 'Symfony\\Bundle\\FrameworkBundle\\Templating\\TimedPhpEngine' => $vendorDir . '/symfony/framework-bundle/Templating/TimedPhpEngine.php', - 'Symfony\\Bundle\\FrameworkBundle\\Test\\ForwardCompatTestTrait' => $vendorDir . '/symfony/framework-bundle/Test/ForwardCompatTestTrait.php', - 'Symfony\\Bundle\\FrameworkBundle\\Test\\KernelTestCase' => $vendorDir . '/symfony/framework-bundle/Test/KernelTestCase.php', - 'Symfony\\Bundle\\FrameworkBundle\\Test\\WebTestCase' => $vendorDir . '/symfony/framework-bundle/Test/WebTestCase.php', 'Symfony\\Bundle\\FrameworkBundle\\Translation\\PhpExtractor' => $vendorDir . '/symfony/framework-bundle/Translation/PhpExtractor.php', 'Symfony\\Bundle\\FrameworkBundle\\Translation\\PhpStringTokenParser' => $vendorDir . '/symfony/framework-bundle/Translation/PhpStringTokenParser.php', 'Symfony\\Bundle\\FrameworkBundle\\Translation\\TranslationLoader' => $vendorDir . '/symfony/framework-bundle/Translation/TranslationLoader.php', @@ -1440,7 +1637,6 @@ return array( 'Symfony\\Component\\VarDumper\\Dumper\\DataDumperInterface' => $vendorDir . '/symfony/var-dumper/Dumper/DataDumperInterface.php', 'Symfony\\Component\\VarDumper\\Dumper\\HtmlDumper' => $vendorDir . '/symfony/var-dumper/Dumper/HtmlDumper.php', 'Symfony\\Component\\VarDumper\\Exception\\ThrowingCasterException' => $vendorDir . '/symfony/var-dumper/Exception/ThrowingCasterException.php', - 'Symfony\\Component\\VarDumper\\Test\\VarDumperTestTrait' => $vendorDir . '/symfony/var-dumper/Test/VarDumperTestTrait.php', 'Symfony\\Component\\VarDumper\\VarDumper' => $vendorDir . '/symfony/var-dumper/VarDumper.php', 'Symfony\\Component\\Yaml\\Command\\LintCommand' => $vendorDir . '/symfony/yaml/Command/LintCommand.php', 'Symfony\\Component\\Yaml\\Dumper' => $vendorDir . '/symfony/yaml/Dumper.php', @@ -1843,11 +2039,6 @@ return array( 'Twig_Test' => $vendorDir . '/twig/twig/lib/Twig/Test.php', 'Twig_TestCallableInterface' => $vendorDir . '/twig/twig/lib/Twig/TestCallableInterface.php', 'Twig_TestInterface' => $vendorDir . '/twig/twig/lib/Twig/TestInterface.php', - 'Twig_Test_Function' => $vendorDir . '/twig/twig/lib/Twig/Test/Function.php', - 'Twig_Test_IntegrationTestCase' => $vendorDir . '/twig/twig/lib/Twig/Test/IntegrationTestCase.php', - 'Twig_Test_Method' => $vendorDir . '/twig/twig/lib/Twig/Test/Method.php', - 'Twig_Test_Node' => $vendorDir . '/twig/twig/lib/Twig/Test/Node.php', - 'Twig_Test_NodeTestCase' => $vendorDir . '/twig/twig/lib/Twig/Test/NodeTestCase.php', 'Twig_Token' => $vendorDir . '/twig/twig/lib/Twig/Token.php', 'Twig_TokenParser' => $vendorDir . '/twig/twig/lib/Twig/TokenParser.php', 'Twig_TokenParserBroker' => $vendorDir . '/twig/twig/lib/Twig/TokenParserBroker.php', @@ -1936,6 +2127,7 @@ return array( 'iScheduledProcess' => $baseDir . '/core/backgroundprocess.inc.php', 'iSelfRegister' => $baseDir . '/core/userrights.class.inc.php', 'iTabbedPage' => $baseDir . '/application/webpage.class.inc.php', + 'iTopConfigParser' => $baseDir . '/core/iTopConfigParser.php', 'iTopMutex' => $baseDir . '/core/mutex.class.inc.php', 'iTopOwnershipLock' => $baseDir . '/core/ownershiplock.class.inc.php', 'iTopOwnershipToken' => $baseDir . '/core/ownershiplock.class.inc.php', diff --git a/lib/composer/autoload_psr4.php b/lib/composer/autoload_psr4.php index c0ba02ab5..20234ce5e 100644 --- a/lib/composer/autoload_psr4.php +++ b/lib/composer/autoload_psr4.php @@ -39,5 +39,6 @@ return array( 'Psr\\Log\\' => array($vendorDir . '/psr/log/Psr/Log'), 'Psr\\Container\\' => array($vendorDir . '/psr/container/src'), 'Psr\\Cache\\' => array($vendorDir . '/psr/cache/src'), + 'PhpParser\\' => array($vendorDir . '/nikic/php-parser/lib/PhpParser'), 'Pelago\\' => array($vendorDir . '/pelago/emogrifier/src'), ); diff --git a/lib/composer/autoload_static.php b/lib/composer/autoload_static.php index 012b2e5cd..7bdfa7d6c 100644 --- a/lib/composer/autoload_static.php +++ b/lib/composer/autoload_static.php @@ -59,6 +59,7 @@ class ComposerStaticInit0018331147de7601e7552f7da8e3bb8b 'Psr\\Log\\' => 8, 'Psr\\Container\\' => 14, 'Psr\\Cache\\' => 10, + 'PhpParser\\' => 10, 'Pelago\\' => 7, ), ); @@ -196,6 +197,10 @@ class ComposerStaticInit0018331147de7601e7552f7da8e3bb8b array ( 0 => __DIR__ . '/..' . '/psr/cache/src', ), + 'PhpParser\\' => + array ( + 0 => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser', + ), 'Pelago\\' => array ( 0 => __DIR__ . '/..' . '/pelago/emogrifier/src', @@ -587,6 +592,209 @@ class ComposerStaticInit0018331147de7601e7552f7da8e3bb8b 'Pelago\\Emogrifier\\HtmlProcessor\\AbstractHtmlProcessor' => __DIR__ . '/..' . '/pelago/emogrifier/src/Emogrifier/HtmlProcessor/AbstractHtmlProcessor.php', 'Pelago\\Emogrifier\\HtmlProcessor\\CssToAttributeConverter' => __DIR__ . '/..' . '/pelago/emogrifier/src/Emogrifier/HtmlProcessor/CssToAttributeConverter.php', 'Pelago\\Emogrifier\\HtmlProcessor\\HtmlNormalizer' => __DIR__ . '/..' . '/pelago/emogrifier/src/Emogrifier/HtmlProcessor/HtmlNormalizer.php', + 'PhpParser\\Autoloader' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Autoloader.php', + 'PhpParser\\Builder' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Builder.php', + 'PhpParser\\BuilderAbstract' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/BuilderAbstract.php', + 'PhpParser\\BuilderFactory' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/BuilderFactory.php', + 'PhpParser\\Builder\\Class_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Builder/Class_.php', + 'PhpParser\\Builder\\Declaration' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Builder/Declaration.php', + 'PhpParser\\Builder\\FunctionLike' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Builder/FunctionLike.php', + 'PhpParser\\Builder\\Function_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Builder/Function_.php', + 'PhpParser\\Builder\\Interface_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Builder/Interface_.php', + 'PhpParser\\Builder\\Method' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Builder/Method.php', + 'PhpParser\\Builder\\Namespace_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Builder/Namespace_.php', + 'PhpParser\\Builder\\Param' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Builder/Param.php', + 'PhpParser\\Builder\\Property' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Builder/Property.php', + 'PhpParser\\Builder\\Trait_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Builder/Trait_.php', + 'PhpParser\\Builder\\Use_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Builder/Use_.php', + 'PhpParser\\Comment' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Comment.php', + 'PhpParser\\Comment\\Doc' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Comment/Doc.php', + 'PhpParser\\Error' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Error.php', + 'PhpParser\\ErrorHandler' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/ErrorHandler.php', + 'PhpParser\\ErrorHandler\\Collecting' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/ErrorHandler/Collecting.php', + 'PhpParser\\ErrorHandler\\Throwing' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/ErrorHandler/Throwing.php', + 'PhpParser\\Lexer' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Lexer.php', + 'PhpParser\\Lexer\\Emulative' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Lexer/Emulative.php', + 'PhpParser\\Node' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node.php', + 'PhpParser\\NodeAbstract' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/NodeAbstract.php', + 'PhpParser\\NodeDumper' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/NodeDumper.php', + 'PhpParser\\NodeTraverser' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/NodeTraverser.php', + 'PhpParser\\NodeTraverserInterface' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/NodeTraverserInterface.php', + 'PhpParser\\NodeVisitor' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/NodeVisitor.php', + 'PhpParser\\NodeVisitorAbstract' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/NodeVisitorAbstract.php', + 'PhpParser\\NodeVisitor\\NameResolver' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/NodeVisitor/NameResolver.php', + 'PhpParser\\Node\\Arg' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Arg.php', + 'PhpParser\\Node\\Const_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Const_.php', + 'PhpParser\\Node\\Expr' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr.php', + 'PhpParser\\Node\\Expr\\ArrayDimFetch' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/ArrayDimFetch.php', + 'PhpParser\\Node\\Expr\\ArrayItem' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/ArrayItem.php', + 'PhpParser\\Node\\Expr\\Array_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/Array_.php', + 'PhpParser\\Node\\Expr\\Assign' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/Assign.php', + 'PhpParser\\Node\\Expr\\AssignOp' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp.php', + 'PhpParser\\Node\\Expr\\AssignOp\\BitwiseAnd' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/BitwiseAnd.php', + 'PhpParser\\Node\\Expr\\AssignOp\\BitwiseOr' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/BitwiseOr.php', + 'PhpParser\\Node\\Expr\\AssignOp\\BitwiseXor' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/BitwiseXor.php', + 'PhpParser\\Node\\Expr\\AssignOp\\Concat' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/Concat.php', + 'PhpParser\\Node\\Expr\\AssignOp\\Div' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/Div.php', + 'PhpParser\\Node\\Expr\\AssignOp\\Minus' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/Minus.php', + 'PhpParser\\Node\\Expr\\AssignOp\\Mod' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/Mod.php', + 'PhpParser\\Node\\Expr\\AssignOp\\Mul' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/Mul.php', + 'PhpParser\\Node\\Expr\\AssignOp\\Plus' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/Plus.php', + 'PhpParser\\Node\\Expr\\AssignOp\\Pow' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/Pow.php', + 'PhpParser\\Node\\Expr\\AssignOp\\ShiftLeft' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/ShiftLeft.php', + 'PhpParser\\Node\\Expr\\AssignOp\\ShiftRight' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/ShiftRight.php', + 'PhpParser\\Node\\Expr\\AssignRef' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/AssignRef.php', + 'PhpParser\\Node\\Expr\\BinaryOp' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp.php', + 'PhpParser\\Node\\Expr\\BinaryOp\\BitwiseAnd' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/BitwiseAnd.php', + 'PhpParser\\Node\\Expr\\BinaryOp\\BitwiseOr' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/BitwiseOr.php', + 'PhpParser\\Node\\Expr\\BinaryOp\\BitwiseXor' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/BitwiseXor.php', + 'PhpParser\\Node\\Expr\\BinaryOp\\BooleanAnd' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/BooleanAnd.php', + 'PhpParser\\Node\\Expr\\BinaryOp\\BooleanOr' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/BooleanOr.php', + 'PhpParser\\Node\\Expr\\BinaryOp\\Coalesce' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Coalesce.php', + 'PhpParser\\Node\\Expr\\BinaryOp\\Concat' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Concat.php', + 'PhpParser\\Node\\Expr\\BinaryOp\\Div' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Div.php', + 'PhpParser\\Node\\Expr\\BinaryOp\\Equal' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Equal.php', + 'PhpParser\\Node\\Expr\\BinaryOp\\Greater' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Greater.php', + 'PhpParser\\Node\\Expr\\BinaryOp\\GreaterOrEqual' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/GreaterOrEqual.php', + 'PhpParser\\Node\\Expr\\BinaryOp\\Identical' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Identical.php', + 'PhpParser\\Node\\Expr\\BinaryOp\\LogicalAnd' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/LogicalAnd.php', + 'PhpParser\\Node\\Expr\\BinaryOp\\LogicalOr' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/LogicalOr.php', + 'PhpParser\\Node\\Expr\\BinaryOp\\LogicalXor' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/LogicalXor.php', + 'PhpParser\\Node\\Expr\\BinaryOp\\Minus' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Minus.php', + 'PhpParser\\Node\\Expr\\BinaryOp\\Mod' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Mod.php', + 'PhpParser\\Node\\Expr\\BinaryOp\\Mul' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Mul.php', + 'PhpParser\\Node\\Expr\\BinaryOp\\NotEqual' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/NotEqual.php', + 'PhpParser\\Node\\Expr\\BinaryOp\\NotIdentical' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/NotIdentical.php', + 'PhpParser\\Node\\Expr\\BinaryOp\\Plus' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Plus.php', + 'PhpParser\\Node\\Expr\\BinaryOp\\Pow' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Pow.php', + 'PhpParser\\Node\\Expr\\BinaryOp\\ShiftLeft' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/ShiftLeft.php', + 'PhpParser\\Node\\Expr\\BinaryOp\\ShiftRight' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/ShiftRight.php', + 'PhpParser\\Node\\Expr\\BinaryOp\\Smaller' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Smaller.php', + 'PhpParser\\Node\\Expr\\BinaryOp\\SmallerOrEqual' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/SmallerOrEqual.php', + 'PhpParser\\Node\\Expr\\BinaryOp\\Spaceship' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Spaceship.php', + 'PhpParser\\Node\\Expr\\BitwiseNot' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/BitwiseNot.php', + 'PhpParser\\Node\\Expr\\BooleanNot' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/BooleanNot.php', + 'PhpParser\\Node\\Expr\\Cast' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/Cast.php', + 'PhpParser\\Node\\Expr\\Cast\\Array_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/Cast/Array_.php', + 'PhpParser\\Node\\Expr\\Cast\\Bool_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/Cast/Bool_.php', + 'PhpParser\\Node\\Expr\\Cast\\Double' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/Cast/Double.php', + 'PhpParser\\Node\\Expr\\Cast\\Int_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/Cast/Int_.php', + 'PhpParser\\Node\\Expr\\Cast\\Object_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/Cast/Object_.php', + 'PhpParser\\Node\\Expr\\Cast\\String_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/Cast/String_.php', + 'PhpParser\\Node\\Expr\\Cast\\Unset_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/Cast/Unset_.php', + 'PhpParser\\Node\\Expr\\ClassConstFetch' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/ClassConstFetch.php', + 'PhpParser\\Node\\Expr\\Clone_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/Clone_.php', + 'PhpParser\\Node\\Expr\\Closure' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/Closure.php', + 'PhpParser\\Node\\Expr\\ClosureUse' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/ClosureUse.php', + 'PhpParser\\Node\\Expr\\ConstFetch' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/ConstFetch.php', + 'PhpParser\\Node\\Expr\\Empty_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/Empty_.php', + 'PhpParser\\Node\\Expr\\Error' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/Error.php', + 'PhpParser\\Node\\Expr\\ErrorSuppress' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/ErrorSuppress.php', + 'PhpParser\\Node\\Expr\\Eval_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/Eval_.php', + 'PhpParser\\Node\\Expr\\Exit_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/Exit_.php', + 'PhpParser\\Node\\Expr\\FuncCall' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/FuncCall.php', + 'PhpParser\\Node\\Expr\\Include_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/Include_.php', + 'PhpParser\\Node\\Expr\\Instanceof_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/Instanceof_.php', + 'PhpParser\\Node\\Expr\\Isset_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/Isset_.php', + 'PhpParser\\Node\\Expr\\List_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/List_.php', + 'PhpParser\\Node\\Expr\\MethodCall' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/MethodCall.php', + 'PhpParser\\Node\\Expr\\New_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/New_.php', + 'PhpParser\\Node\\Expr\\PostDec' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/PostDec.php', + 'PhpParser\\Node\\Expr\\PostInc' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/PostInc.php', + 'PhpParser\\Node\\Expr\\PreDec' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/PreDec.php', + 'PhpParser\\Node\\Expr\\PreInc' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/PreInc.php', + 'PhpParser\\Node\\Expr\\Print_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/Print_.php', + 'PhpParser\\Node\\Expr\\PropertyFetch' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/PropertyFetch.php', + 'PhpParser\\Node\\Expr\\ShellExec' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/ShellExec.php', + 'PhpParser\\Node\\Expr\\StaticCall' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/StaticCall.php', + 'PhpParser\\Node\\Expr\\StaticPropertyFetch' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/StaticPropertyFetch.php', + 'PhpParser\\Node\\Expr\\Ternary' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/Ternary.php', + 'PhpParser\\Node\\Expr\\UnaryMinus' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/UnaryMinus.php', + 'PhpParser\\Node\\Expr\\UnaryPlus' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/UnaryPlus.php', + 'PhpParser\\Node\\Expr\\Variable' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/Variable.php', + 'PhpParser\\Node\\Expr\\YieldFrom' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/YieldFrom.php', + 'PhpParser\\Node\\Expr\\Yield_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/Yield_.php', + 'PhpParser\\Node\\FunctionLike' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/FunctionLike.php', + 'PhpParser\\Node\\Name' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Name.php', + 'PhpParser\\Node\\Name\\FullyQualified' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Name/FullyQualified.php', + 'PhpParser\\Node\\Name\\Relative' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Name/Relative.php', + 'PhpParser\\Node\\NullableType' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/NullableType.php', + 'PhpParser\\Node\\Param' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Param.php', + 'PhpParser\\Node\\Scalar' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Scalar.php', + 'PhpParser\\Node\\Scalar\\DNumber' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Scalar/DNumber.php', + 'PhpParser\\Node\\Scalar\\Encapsed' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Scalar/Encapsed.php', + 'PhpParser\\Node\\Scalar\\EncapsedStringPart' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Scalar/EncapsedStringPart.php', + 'PhpParser\\Node\\Scalar\\LNumber' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Scalar/LNumber.php', + 'PhpParser\\Node\\Scalar\\MagicConst' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Scalar/MagicConst.php', + 'PhpParser\\Node\\Scalar\\MagicConst\\Class_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Scalar/MagicConst/Class_.php', + 'PhpParser\\Node\\Scalar\\MagicConst\\Dir' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Scalar/MagicConst/Dir.php', + 'PhpParser\\Node\\Scalar\\MagicConst\\File' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Scalar/MagicConst/File.php', + 'PhpParser\\Node\\Scalar\\MagicConst\\Function_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Scalar/MagicConst/Function_.php', + 'PhpParser\\Node\\Scalar\\MagicConst\\Line' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Scalar/MagicConst/Line.php', + 'PhpParser\\Node\\Scalar\\MagicConst\\Method' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Scalar/MagicConst/Method.php', + 'PhpParser\\Node\\Scalar\\MagicConst\\Namespace_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Scalar/MagicConst/Namespace_.php', + 'PhpParser\\Node\\Scalar\\MagicConst\\Trait_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Scalar/MagicConst/Trait_.php', + 'PhpParser\\Node\\Scalar\\String_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Scalar/String_.php', + 'PhpParser\\Node\\Stmt' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Stmt.php', + 'PhpParser\\Node\\Stmt\\Break_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Break_.php', + 'PhpParser\\Node\\Stmt\\Case_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Case_.php', + 'PhpParser\\Node\\Stmt\\Catch_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Catch_.php', + 'PhpParser\\Node\\Stmt\\ClassConst' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Stmt/ClassConst.php', + 'PhpParser\\Node\\Stmt\\ClassLike' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Stmt/ClassLike.php', + 'PhpParser\\Node\\Stmt\\ClassMethod' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Stmt/ClassMethod.php', + 'PhpParser\\Node\\Stmt\\Class_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Class_.php', + 'PhpParser\\Node\\Stmt\\Const_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Const_.php', + 'PhpParser\\Node\\Stmt\\Continue_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Continue_.php', + 'PhpParser\\Node\\Stmt\\DeclareDeclare' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Stmt/DeclareDeclare.php', + 'PhpParser\\Node\\Stmt\\Declare_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Declare_.php', + 'PhpParser\\Node\\Stmt\\Do_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Do_.php', + 'PhpParser\\Node\\Stmt\\Echo_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Echo_.php', + 'PhpParser\\Node\\Stmt\\ElseIf_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Stmt/ElseIf_.php', + 'PhpParser\\Node\\Stmt\\Else_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Else_.php', + 'PhpParser\\Node\\Stmt\\Finally_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Finally_.php', + 'PhpParser\\Node\\Stmt\\For_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Stmt/For_.php', + 'PhpParser\\Node\\Stmt\\Foreach_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Foreach_.php', + 'PhpParser\\Node\\Stmt\\Function_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Function_.php', + 'PhpParser\\Node\\Stmt\\Global_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Global_.php', + 'PhpParser\\Node\\Stmt\\Goto_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Goto_.php', + 'PhpParser\\Node\\Stmt\\GroupUse' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Stmt/GroupUse.php', + 'PhpParser\\Node\\Stmt\\HaltCompiler' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Stmt/HaltCompiler.php', + 'PhpParser\\Node\\Stmt\\If_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Stmt/If_.php', + 'PhpParser\\Node\\Stmt\\InlineHTML' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Stmt/InlineHTML.php', + 'PhpParser\\Node\\Stmt\\Interface_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Interface_.php', + 'PhpParser\\Node\\Stmt\\Label' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Label.php', + 'PhpParser\\Node\\Stmt\\Namespace_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Namespace_.php', + 'PhpParser\\Node\\Stmt\\Nop' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Nop.php', + 'PhpParser\\Node\\Stmt\\Property' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Property.php', + 'PhpParser\\Node\\Stmt\\PropertyProperty' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Stmt/PropertyProperty.php', + 'PhpParser\\Node\\Stmt\\Return_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Return_.php', + 'PhpParser\\Node\\Stmt\\StaticVar' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Stmt/StaticVar.php', + 'PhpParser\\Node\\Stmt\\Static_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Static_.php', + 'PhpParser\\Node\\Stmt\\Switch_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Switch_.php', + 'PhpParser\\Node\\Stmt\\Throw_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Throw_.php', + 'PhpParser\\Node\\Stmt\\TraitUse' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Stmt/TraitUse.php', + 'PhpParser\\Node\\Stmt\\TraitUseAdaptation' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Stmt/TraitUseAdaptation.php', + 'PhpParser\\Node\\Stmt\\TraitUseAdaptation\\Alias' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Stmt/TraitUseAdaptation/Alias.php', + 'PhpParser\\Node\\Stmt\\TraitUseAdaptation\\Precedence' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Stmt/TraitUseAdaptation/Precedence.php', + 'PhpParser\\Node\\Stmt\\Trait_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Trait_.php', + 'PhpParser\\Node\\Stmt\\TryCatch' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Stmt/TryCatch.php', + 'PhpParser\\Node\\Stmt\\Unset_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Unset_.php', + 'PhpParser\\Node\\Stmt\\UseUse' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Stmt/UseUse.php', + 'PhpParser\\Node\\Stmt\\Use_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Use_.php', + 'PhpParser\\Node\\Stmt\\While_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Stmt/While_.php', + 'PhpParser\\Parser' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Parser.php', + 'PhpParser\\ParserAbstract' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/ParserAbstract.php', + 'PhpParser\\ParserFactory' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/ParserFactory.php', + 'PhpParser\\Parser\\Multiple' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Parser/Multiple.php', + 'PhpParser\\Parser\\Php5' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Parser/Php5.php', + 'PhpParser\\Parser\\Php7' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Parser/Php7.php', + 'PhpParser\\Parser\\Tokens' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Parser/Tokens.php', + 'PhpParser\\PrettyPrinterAbstract' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/PrettyPrinterAbstract.php', + 'PhpParser\\PrettyPrinter\\Standard' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/PrettyPrinter/Standard.php', + 'PhpParser\\Serializer' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Serializer.php', + 'PhpParser\\Serializer\\XML' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Serializer/XML.php', + 'PhpParser\\Unserializer' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Unserializer.php', + 'PhpParser\\Unserializer\\XML' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Unserializer/XML.php', 'PortalDispatcher' => __DIR__ . '/../..' . '/application/portaldispatcher.class.inc.php', 'PortalURLMaker' => __DIR__ . '/../..' . '/application/applicationcontext.class.inc.php', 'PrintableDataTable' => __DIR__ . '/../..' . '/application/datatable.class.inc.php', @@ -608,9 +816,6 @@ class ComposerStaticInit0018331147de7601e7552f7da8e3bb8b 'Psr\\Log\\LoggerInterface' => __DIR__ . '/..' . '/psr/log/Psr/Log/LoggerInterface.php', 'Psr\\Log\\LoggerTrait' => __DIR__ . '/..' . '/psr/log/Psr/Log/LoggerTrait.php', 'Psr\\Log\\NullLogger' => __DIR__ . '/..' . '/psr/log/Psr/Log/NullLogger.php', - 'Psr\\Log\\Test\\DummyTest' => __DIR__ . '/..' . '/psr/log/Psr/Log/Test/LoggerInterfaceTest.php', - 'Psr\\Log\\Test\\LoggerInterfaceTest' => __DIR__ . '/..' . '/psr/log/Psr/Log/Test/LoggerInterfaceTest.php', - 'Psr\\Log\\Test\\TestLogger' => __DIR__ . '/..' . '/psr/log/Psr/Log/Test/TestLogger.php', 'Psr\\SimpleCache\\CacheException' => __DIR__ . '/..' . '/psr/simple-cache/src/CacheException.php', 'Psr\\SimpleCache\\CacheInterface' => __DIR__ . '/..' . '/psr/simple-cache/src/CacheInterface.php', 'Psr\\SimpleCache\\InvalidArgumentException' => __DIR__ . '/..' . '/psr/simple-cache/src/InvalidArgumentException.php', @@ -850,9 +1055,6 @@ class ComposerStaticInit0018331147de7601e7552f7da8e3bb8b 'Symfony\\Bundle\\FrameworkBundle\\Templating\\TemplateNameParser' => __DIR__ . '/..' . '/symfony/framework-bundle/Templating/TemplateNameParser.php', 'Symfony\\Bundle\\FrameworkBundle\\Templating\\TemplateReference' => __DIR__ . '/..' . '/symfony/framework-bundle/Templating/TemplateReference.php', 'Symfony\\Bundle\\FrameworkBundle\\Templating\\TimedPhpEngine' => __DIR__ . '/..' . '/symfony/framework-bundle/Templating/TimedPhpEngine.php', - 'Symfony\\Bundle\\FrameworkBundle\\Test\\ForwardCompatTestTrait' => __DIR__ . '/..' . '/symfony/framework-bundle/Test/ForwardCompatTestTrait.php', - 'Symfony\\Bundle\\FrameworkBundle\\Test\\KernelTestCase' => __DIR__ . '/..' . '/symfony/framework-bundle/Test/KernelTestCase.php', - 'Symfony\\Bundle\\FrameworkBundle\\Test\\WebTestCase' => __DIR__ . '/..' . '/symfony/framework-bundle/Test/WebTestCase.php', 'Symfony\\Bundle\\FrameworkBundle\\Translation\\PhpExtractor' => __DIR__ . '/..' . '/symfony/framework-bundle/Translation/PhpExtractor.php', 'Symfony\\Bundle\\FrameworkBundle\\Translation\\PhpStringTokenParser' => __DIR__ . '/..' . '/symfony/framework-bundle/Translation/PhpStringTokenParser.php', 'Symfony\\Bundle\\FrameworkBundle\\Translation\\TranslationLoader' => __DIR__ . '/..' . '/symfony/framework-bundle/Translation/TranslationLoader.php', @@ -1665,7 +1867,6 @@ class ComposerStaticInit0018331147de7601e7552f7da8e3bb8b 'Symfony\\Component\\VarDumper\\Dumper\\DataDumperInterface' => __DIR__ . '/..' . '/symfony/var-dumper/Dumper/DataDumperInterface.php', 'Symfony\\Component\\VarDumper\\Dumper\\HtmlDumper' => __DIR__ . '/..' . '/symfony/var-dumper/Dumper/HtmlDumper.php', 'Symfony\\Component\\VarDumper\\Exception\\ThrowingCasterException' => __DIR__ . '/..' . '/symfony/var-dumper/Exception/ThrowingCasterException.php', - 'Symfony\\Component\\VarDumper\\Test\\VarDumperTestTrait' => __DIR__ . '/..' . '/symfony/var-dumper/Test/VarDumperTestTrait.php', 'Symfony\\Component\\VarDumper\\VarDumper' => __DIR__ . '/..' . '/symfony/var-dumper/VarDumper.php', 'Symfony\\Component\\Yaml\\Command\\LintCommand' => __DIR__ . '/..' . '/symfony/yaml/Command/LintCommand.php', 'Symfony\\Component\\Yaml\\Dumper' => __DIR__ . '/..' . '/symfony/yaml/Dumper.php', @@ -2068,11 +2269,6 @@ class ComposerStaticInit0018331147de7601e7552f7da8e3bb8b 'Twig_Test' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Test.php', 'Twig_TestCallableInterface' => __DIR__ . '/..' . '/twig/twig/lib/Twig/TestCallableInterface.php', 'Twig_TestInterface' => __DIR__ . '/..' . '/twig/twig/lib/Twig/TestInterface.php', - 'Twig_Test_Function' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Test/Function.php', - 'Twig_Test_IntegrationTestCase' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Test/IntegrationTestCase.php', - 'Twig_Test_Method' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Test/Method.php', - 'Twig_Test_Node' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Test/Node.php', - 'Twig_Test_NodeTestCase' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Test/NodeTestCase.php', 'Twig_Token' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Token.php', 'Twig_TokenParser' => __DIR__ . '/..' . '/twig/twig/lib/Twig/TokenParser.php', 'Twig_TokenParserBroker' => __DIR__ . '/..' . '/twig/twig/lib/Twig/TokenParserBroker.php', @@ -2161,6 +2357,7 @@ class ComposerStaticInit0018331147de7601e7552f7da8e3bb8b 'iScheduledProcess' => __DIR__ . '/../..' . '/core/backgroundprocess.inc.php', 'iSelfRegister' => __DIR__ . '/../..' . '/core/userrights.class.inc.php', 'iTabbedPage' => __DIR__ . '/../..' . '/application/webpage.class.inc.php', + 'iTopConfigParser' => __DIR__ . '/../..' . '/core/iTopConfigParser.php', 'iTopMutex' => __DIR__ . '/../..' . '/core/mutex.class.inc.php', 'iTopOwnershipLock' => __DIR__ . '/../..' . '/core/ownershiplock.class.inc.php', 'iTopOwnershipToken' => __DIR__ . '/../..' . '/core/ownershiplock.class.inc.php', diff --git a/lib/composer/installed.json b/lib/composer/installed.json index 5364b565e..44e4a82e2 100644 --- a/lib/composer/installed.json +++ b/lib/composer/installed.json @@ -56,6 +56,59 @@ "description": "TCPDF fork adding requirements for iTop: Specific fonts.", "homepage": "https://github.com/combodo-itop-libs/TCPDF" }, + { + "name": "nikic/php-parser", + "version": "v3.1.5", + "version_normalized": "3.1.5.0", + "source": { + "type": "git", + "url": "https://github.com/nikic/PHP-Parser.git", + "reference": "bb87e28e7d7b8d9a7fda231d37457c9210faf6ce" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/bb87e28e7d7b8d9a7fda231d37457c9210faf6ce", + "reference": "bb87e28e7d7b8d9a7fda231d37457c9210faf6ce", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": ">=5.5" + }, + "require-dev": { + "phpunit/phpunit": "~4.0|~5.0" + }, + "time": "2018-02-28T20:30:58+00:00", + "bin": [ + "bin/php-parse" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "PhpParser\\": "lib/PhpParser" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Nikita Popov" + } + ], + "description": "A PHP parser written in PHP", + "keywords": [ + "parser", + "php" + ] + }, { "name": "paragonie/random_compat", "version": "v2.0.18", diff --git a/lib/nikic/php-parser/.gitignore b/lib/nikic/php-parser/.gitignore new file mode 100644 index 000000000..8c7db2a6e --- /dev/null +++ b/lib/nikic/php-parser/.gitignore @@ -0,0 +1,4 @@ +vendor/ +composer.lock +grammar/kmyacc.exe +grammar/y.output diff --git a/lib/nikic/php-parser/.travis.yml b/lib/nikic/php-parser/.travis.yml new file mode 100644 index 000000000..9cd00253e --- /dev/null +++ b/lib/nikic/php-parser/.travis.yml @@ -0,0 +1,31 @@ +language: php +dist: trusty +sudo: false + +cache: + directories: + - $HOME/.composer/cache + +php: + - 5.5 + - 5.6 + - 7.0 + - nightly + - hhvm + +install: + - if [ $TRAVIS_PHP_VERSION = '5.6' ]; then composer require satooshi/php-coveralls '~1.0'; fi + - composer install --prefer-dist + +matrix: + allow_failures: + - php: nightly + fast_finish: true + +script: + - if [ $TRAVIS_PHP_VERSION = '5.6' ]; then vendor/bin/phpunit --coverage-clover build/logs/clover.xml; else vendor/bin/phpunit; fi + - if [ $TRAVIS_PHP_VERSION = '7.0' ]; then test_old/run-php-src.sh; fi + +after_success: + if [ $TRAVIS_PHP_VERSION = '5.6' ]; then php vendor/bin/coveralls; fi + diff --git a/lib/nikic/php-parser/CHANGELOG.md b/lib/nikic/php-parser/CHANGELOG.md new file mode 100644 index 000000000..c2d953393 --- /dev/null +++ b/lib/nikic/php-parser/CHANGELOG.md @@ -0,0 +1,422 @@ +Version 3.1.6-dev +----------------- + +Nothing yet. + +Version 3.1.5 (2018-02-28) +-------------------------- + +### Fixed + +* Fixed duplicate comment assignment in switch statements. (#469) +* Improve compatibility with PHP-Scoper. (#477) + +Version 3.1.4 (2018-01-25) +-------------------------- + +### Fixed + +* Fixed pretty printing of `-(-$x)` and `+(+$x)`. (#459) + +Version 3.1.3 (2017-12-26) +-------------------------- + +### Fixed + +* Improve compatibility with php-scoper, by supporting prefixed namespaces in + `NodeAbstract::getType()`. + +Version 3.1.2 (2017-11-04) +-------------------------- + +### Fixed + +* Comments on empty blocks are now preserved on a `Stmt\Nop` node. (#382) + +### Added + +* Added `kind` attribute for `Stmt\Namespace_` node, which is one of `KIND_SEMICOLON` or + `KIND_BRACED`. (#417) +* Added `setDocComment()` method to namespace builder. (#437) + +Version 3.1.1 (2017-09-02) +-------------------------- + +### Fixed + +* Fixed syntax error on comment after brace-style namespace declaration. (#412) +* Added support for TraitUse statements in trait builder. (#413) + +Version 3.1.0 (2017-07-28) +-------------------------- + +### Added + +* [PHP 7.2] Added support for trailing comma in group use statements. +* [PHP 7.2] Added support for `object` type. This means `object` types will now be represented as a + builtin type (a simple `"object"` string), rather than a class `Name`. + +### Fixed + +* Floating-point numbers are now printed correctly if the LC_NUMERIC locale uses a comma as decimal + separator. + +### Changed + +* `Name::$parts` is no longer deprecated. + +Version 3.0.6 (2017-06-28) +-------------------------- + +### Fixed + +* Fixed the spelling of `Class_::VISIBILITY_MODIFIER_MASK`. The previous spelling of + `Class_::VISIBILITY_MODIFER_MASK` is preserved for backwards compatibility. +* The pretty printing will now preserve comments inside array literals and function calls by + printing the array items / function arguments on separate lines. Array literals and functions that + do not contain comments are not affected. + +### Added + +* Added `Builder\Param::makeVariadic()`. + +### Deprecated + +* The `Node::setLine()` method has been deprecated. + +Version 3.0.5 (2017-03-05) +-------------------------- + +### Fixed + +* Name resolution of `NullableType`s is now performed earlier, so that a fully resolved signature is + available when a function is entered. (#360) +* `Error` nodes are now considered empty, while previously they extended until the token where the + error occurred. This made some nodes larger than expected. (#359) +* Fixed notices being thrown during error recovery in some situations. (#362) + +Version 3.0.4 (2017-02-10) +-------------------------- + +### Fixed + +* Fixed some extensibility issues in pretty printer (`pUseType()` is now public and `pPrec()` calls + into `p()`, instead of directly dispatching to the type-specific printing method). +* Fixed notice in `bin/php-parse` script. + +### Added + +* Error recovery from missing semicolons is now supported in more cases. +* Error recovery from trailing commas in positions where PHP does not support them is now supported. + +Version 3.0.3 (2017-02-03) +-------------------------- + +### Fixed + +* In `"$foo[0]"` the `0` is now parsed as an `LNumber` rather than `String`. (#325) +* Ensure integers and floats are always pretty printed preserving semantics, even if the particular + value can only be manually constructed. +* Throw a `LogicException` when trying to pretty-print an `Error` node. Previously this resulted in + an undefined method exception or fatal error. + +### Added + +* [PHP 7.1] Added support for negative interpolated offsets: `"$foo[-1]"` +* Added `preserveOriginalNames` option to `NameResolver`. If this option is enabled, an + `originalName` attribute, containing the unresolved name, will be added to each resolved name. +* Added `php-parse --with-positions` option, which dumps nodes with position information. + +### Deprecated + +* The XML serializer has been deprecated. In particular, the classes `Serializer\XML`, + `Unserializer\XML`, as well as the interfaces `Serializer` and `Unserializer` are deprecated. + +Version 3.0.2 (2016-12-06) +-------------------------- + +### Fixed + +* Fixed name resolution of nullable types. (#324) +* Fixed pretty-printing of nullable types. + +Version 3.0.1 (2016-12-01) +-------------------------- + +### Fixed + +* Fixed handling of nested `list()`s: If the nested list was unkeyed, it was directly included in + the list items. If it was keyed, it was wrapped in `ArrayItem`. Now nested `List_` nodes are + always wrapped in `ArrayItem`s. (#321) + +Version 3.0.0 (2016-11-30) +-------------------------- + +### Added + +* Added support for dumping node positions in the NodeDumper through the `dumpPositions` option. +* Added error recovery support for `$`, `new`, `Foo::`. + +Version 3.0.0-beta2 (2016-10-29) +-------------------------------- + +This release primarily improves our support for error recovery. + +### Added + +* Added `Node::setDocComment()` method. +* Added `Error::getMessageWithColumnInfo()` method. +* Added support for recovery from lexer errors. +* Added support for recovering from "special" errors (i.e. non-syntax parse errors). +* Added precise location information for lexer errors. +* Added `ErrorHandler` interface, and `ErrorHandler\Throwing` and `ErrorHandler\Collecting` as + specific implementations. These provide a general mechanism for handling error recovery. +* Added optional `ErrorHandler` argument to `Parser::parse()`, `Lexer::startLexing()` and + `NameResolver::__construct()`. +* The `NameResolver` now adds a `namespacedName` attribute on name nodes that cannot be statically + resolved (unqualified unaliased function or constant names in namespaces). + +### Fixed + +* Fixed attribute assignment for `GroupUse` prefix and variables in interpolated strings. + +### Changed + +* The constants on `NameTraverserInterface` have been moved into the `NameTraverser` class. +* Due to the error handling changes, the `Parser` interface and `Lexer` API have changed. +* The emulative lexer now directly postprocesses tokens, instead of using `~__EMU__~` sequences. + This changes the protected API of the lexer. +* The `Name::slice()` method now returns `null` for empty slices, previously `new Name([])` was + used. `Name::concat()` now also supports concatenation with `null`. + +### Removed + +* Removed `Name::append()` and `Name::prepend()`. These mutable methods have been superseded by + the immutable `Name::concat()`. +* Removed `Error::getRawLine()` and `Error::setRawLine()`. These methods have been superseded by + `Error::getStartLine()` and `Error::setStartLine()`. +* Removed support for node cloning in the `NodeTraverser`. +* Removed `$separator` argument from `Name::toString()`. +* Removed `throw_on_error` parser option and `Parser::getErrors()` method. Use the `ErrorHandler` + mechanism instead. + +Version 3.0.0-beta1 (2016-09-16) +-------------------------------- + +### Added + +* [7.1] Function/method and parameter builders now support PHP 7.1 type hints (void, iterable and + nullable types). +* Nodes and Comments now implement `JsonSerializable`. The node kind is stored in a `nodeType` + property. +* The `InlineHTML` node now has an `hasLeadingNewline` attribute, that specifies whether the + preceding closing tag contained a newline. The pretty printer honors this attribute. +* Partial parsing of `$obj->` (with missing property name) is now supported in error recovery mode. +* The error recovery mode is now exposed in the `php-parse` script through the `--with-recovery` + or `-r` flags. + +The following changes are also part of PHP-Parser 2.1.1: + +* The PHP 7 parser will now generate a parse error for `$var =& new Obj` assignments. +* Comments on free-standing code blocks will now be retained as comments on the first statement in + the code block. + +Version 3.0.0-alpha1 (2016-07-25) +--------------------------------- + +### Added + +* [7.1] Added support for `void` and `iterable` types. These will now be represented as strings + (instead of `Name` instances) similar to other builtin types. +* [7.1] Added support for class constant visibility. The `ClassConst` node now has a `flags` subnode + holding the visibility modifier, as well as `isPublic()`, `isProtected()` and `isPrivate()` + methods. The constructor changed to accept the additional subnode. +* [7.1] Added support for nullable types. These are represented using a new `NullableType` node + with a single `type` subnode. +* [7.1] Added support for short array destructuring syntax. This means that `Array` nodes may now + appear as the left-hand-side of assignments and foreach value targets. Additionally the array + items may now contain `null` values if elements are skipped. +* [7.1] Added support for keys in list() destructuring. The `List` subnode `vars` has been renamed + to `items` and now contains `ArrayItem`s instead of plain variables. +* [7.1] Added support for multi-catch. The `Catch` subnode `type` has been renamed to `types` and + is now an array of `Name`s. +* `Name::slice()` now supports lengths and negative offsets. This brings it in line with + `array_slice()` functionality. + +### Changed + +Due to PHP 7.1 support additions described above, the node structure changed as follows: + +* `void` and `iterable` types are now stored as strings if the PHP 7 parser is used. +* The `ClassConst` constructor changed to accept an additional `flags` subnode. +* The `Array` subnode `items` may now contain `null` elements (destructuring). +* The `List` subnode `vars` has been renamed to `items` and now contains `ArrayItem`s instead of + plain variables. +* The `Catch` subnode `type` has been renamed to `types` and is now an array of `Name`s. + +Additionally the following changes were made: + +* The `type` subnode on `Class`, `ClassMethod` and `Property` has been renamed to `flags`. The + `type` subnode has retained for backwards compatibility and is populated to the same value as + `flags`. However, writes to `type` will not update `flags`. +* The `TryCatch` subnode `finallyStmts` has been replaced with a `finally` subnode that holds an + explicit `Finally` node. This allows for more accurate attribute assignment. +* The `Trait` constructor now has the same form as the `Class` and `Interface` constructors: It + takes an array of subnodes. Unlike classes/interfaces, traits can only have a `stmts` subnode. +* The `NodeDumper` now prints class/method/property/constant modifiers, as well as the include and + use type in a textual representation, instead of only showing the number. +* All methods on `PrettyPrinter\Standard` are now protected. Previoulsy most of them were public. + +### Removed + +* Removed support for running on PHP 5.4. It is however still possible to parse PHP 5.2-5.4 code + while running on a newer version. +* The deprecated `Comment::setLine()` and `Comment::setText()` methods have been removed. +* The deprecated `Name::set()`, `Name::setFirst()` and `Name::setLast()` methods have been removed. + +Version 2.1.1 (2016-09-16) +-------------------------- + +### Changed + +* The pretty printer will now escape all control characters in the range `\x00-\x1F` inside double + quoted strings. If no special escape sequence is available, an octal escape will be used. +* The quality of the error recovery has been improved. In particular unterminated expressions should + be handled more gracefully. +* The PHP 7 parser will now generate a parse error for `$var =& new Obj` assignments. +* Comments on free-standing code blocks will no be retained as comments on the first statement in + the code block. + +Version 2.1.0 (2016-04-19) +-------------------------- + +### Fixed + +* Properly support `B""` strings (with uppercase `B`) in a number of places. +* Fixed reformatting of indented parts in a certain non-standard comment style. + +### Added + +* Added `dumpComments` option to node dumper, to enable dumping of comments associated with nodes. +* Added `Stmt\Nop` node, that is used to collect comments located at the end of a block or at the + end of a file (without a following node with which they could otherwise be associated). +* Added `kind` attribute to `Expr\Exit` to distinguish between `exit` and `die`. +* Added `kind` attribute to `Scalar\LNumber` to distinguish between decimal, binary, octal and + hexadecimal numbers. +* Added `kind` attribtue to `Expr\Array` to distinguish between `array()` and `[]`. +* Added `kind` attribute to `Scalar\String` and `Scalar\Encapsed` to distinguish between + single-quoted, double-quoted, heredoc and nowdoc string. +* Added `docLabel` attribute to `Scalar\String` and `Scalar\Encapsed`, if it is a heredoc or + nowdoc string. +* Added start file offset information to `Comment` nodes. +* Added `setReturnType()` method to function and method builders. +* Added `-h` and `--help` options to `php-parse` script. + +### Changed + +* Invalid octal literals now throw a parse error in PHP 7 mode. +* The pretty printer takes all the new attributes mentioned in the previous section into account. +* The protected `AbstractPrettyPrinter::pComments()` method no longer returns a trailing newline. +* The bundled autoloader supports library files being stored in a different directory than + `PhpParser` for easier downstream distribution. + +### Deprecated + +* The `Comment::setLine()` and `Comment::setText()` methods have been deprecated. Construct new + objects instead. + +### Removed + +* The internal (but public) method `Scalar\LNumber::parse()` has been removed. A non-internal + `LNumber::fromString()` method has been added instead. + +Version 2.0.1 (2016-02-28) +-------------------------- + +### Fixed + +* `declare() {}` and `declare();` are not semantically equivalent and will now result in different + ASTs. The format case will have an empty `stmts` array, while the latter will set `stmts` to + `null`. +* Magic constants are now supported as semi-reserved keywords. +* A shebang line like `#!/usr/bin/env php` is now allowed at the start of a namespaced file. + Previously this generated an exception. +* The `prettyPrintFile()` method will not strip a trailing `?>` from the raw data that follows a + `__halt_compiler()` statement. +* The `prettyPrintFile()` method will not strip an opening `slice()` which takes a subslice of a name. + +### Changed + +* `PhpParser\Parser` is now an interface, implemented by `Parser\Php5`, `Parser\Php7` and + `Parser\Multiple`. The `Multiple` parser will try multiple parsers, until one succeeds. +* Token constants are now defined on `PhpParser\Parser\Tokens` rather than `PhpParser\Parser`. +* The `Name->set()`, `Name->append()`, `Name->prepend()` and `Name->setFirst()` methods are + deprecated in favor of `Name::concat()` and `Name->slice()`. +* The `NodeTraverser` no longer clones nodes by default. The old behavior can be restored by + passing `true` to the constructor. +* The constructor for `Scalar` nodes no longer has a default value. E.g. `new LNumber()` should now + be written as `new LNumber(0)`. + +--- + +**This changelog only includes changes from the 2.0 series. For older changes see the +[1.x series changelog](https://github.com/nikic/PHP-Parser/blob/1.x/CHANGELOG.md) and the +[0.9 series changelog](https://github.com/nikic/PHP-Parser/blob/0.9/CHANGELOG.md).** \ No newline at end of file diff --git a/lib/nikic/php-parser/LICENSE b/lib/nikic/php-parser/LICENSE new file mode 100644 index 000000000..920cc5b1f --- /dev/null +++ b/lib/nikic/php-parser/LICENSE @@ -0,0 +1,31 @@ +Copyright (c) 2011-2018 by Nikita Popov. + +Some rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + + * The names of the contributors may not be used to endorse or + promote products derived from this software without specific + prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/lib/nikic/php-parser/README.md b/lib/nikic/php-parser/README.md new file mode 100644 index 000000000..2f62754ce --- /dev/null +++ b/lib/nikic/php-parser/README.md @@ -0,0 +1,99 @@ +PHP Parser +========== + +[![Build Status](https://travis-ci.org/nikic/PHP-Parser.svg?branch=master)](https://travis-ci.org/nikic/PHP-Parser) [![Coverage Status](https://coveralls.io/repos/github/nikic/PHP-Parser/badge.svg?branch=master)](https://coveralls.io/github/nikic/PHP-Parser?branch=master) + +This is a PHP 5.2 to PHP 7.1 parser written in PHP. Its purpose is to simplify static code analysis and +manipulation. + +[**Documentation for version 3.x**][doc_master] (stable; for running on PHP >= 5.5; for parsing PHP 5.2 to PHP 7.1). + +[Documentation for version 2.x][doc_2_x] (stable; for running on PHP >= 5.4; for parsing PHP 5.2 to PHP 7.0). + +[Documentation for version 1.x][doc_1_x] (unsupported; for running on PHP >= 5.3; for parsing PHP 5.2 to PHP 5.6). + +In a Nutshell +------------- + +The parser turns PHP source code into an abstract syntax tree. For example, if you pass the following code into the +parser: + +```php + Expr_AssignOp_BitwiseAnd +Expr_AssignBitwiseOr => Expr_AssignOp_BitwiseOr +Expr_AssignBitwiseXor => Expr_AssignOp_BitwiseXor +Expr_AssignConcat => Expr_AssignOp_Concat +Expr_AssignDiv => Expr_AssignOp_Div +Expr_AssignMinus => Expr_AssignOp_Minus +Expr_AssignMod => Expr_AssignOp_Mod +Expr_AssignMul => Expr_AssignOp_Mul +Expr_AssignPlus => Expr_AssignOp_Plus +Expr_AssignShiftLeft => Expr_AssignOp_ShiftLeft +Expr_AssignShiftRight => Expr_AssignOp_ShiftRight + +Expr_BitwiseAnd => Expr_BinaryOp_BitwiseAnd +Expr_BitwiseOr => Expr_BinaryOp_BitwiseOr +Expr_BitwiseXor => Expr_BinaryOp_BitwiseXor +Expr_BooleanAnd => Expr_BinaryOp_BooleanAnd +Expr_BooleanOr => Expr_BinaryOp_BooleanOr +Expr_Concat => Expr_BinaryOp_Concat +Expr_Div => Expr_BinaryOp_Div +Expr_Equal => Expr_BinaryOp_Equal +Expr_Greater => Expr_BinaryOp_Greater +Expr_GreaterOrEqual => Expr_BinaryOp_GreaterOrEqual +Expr_Identical => Expr_BinaryOp_Identical +Expr_LogicalAnd => Expr_BinaryOp_LogicalAnd +Expr_LogicalOr => Expr_BinaryOp_LogicalOr +Expr_LogicalXor => Expr_BinaryOp_LogicalXor +Expr_Minus => Expr_BinaryOp_Minus +Expr_Mod => Expr_BinaryOp_Mod +Expr_Mul => Expr_BinaryOp_Mul +Expr_NotEqual => Expr_BinaryOp_NotEqual +Expr_NotIdentical => Expr_BinaryOp_NotIdentical +Expr_Plus => Expr_BinaryOp_Plus +Expr_ShiftLeft => Expr_BinaryOp_ShiftLeft +Expr_ShiftRight => Expr_BinaryOp_ShiftRight +Expr_Smaller => Expr_BinaryOp_Smaller +Expr_SmallerOrEqual => Expr_BinaryOp_SmallerOrEqual + +Scalar_ClassConst => Scalar_MagicConst_Class +Scalar_DirConst => Scalar_MagicConst_Dir +Scalar_FileConst => Scalar_MagicConst_File +Scalar_FuncConst => Scalar_MagicConst_Function +Scalar_LineConst => Scalar_MagicConst_Line +Scalar_MethodConst => Scalar_MagicConst_Method +Scalar_NSConst => Scalar_MagicConst_Namespace +Scalar_TraitConst => Scalar_MagicConst_Trait +``` + +These changes may affect custom pretty printers and code comparing the return value of `Node::getType()` to specific +strings. + +### Miscellaneous + + * The classes `Template` and `TemplateLoader` have been removed. You should use some other [code generation][code_gen] + project built on top of PHP-Parser instead. + + * The `PrettyPrinterAbstract::pStmts()` method now emits a leading newline if the statement list is not empty. + Custom pretty printers should remove the explicit newline before `pStmts()` calls. + + Old: + + ```php + public function pStmt_Trait(PHPParser_Node_Stmt_Trait $node) { + return 'trait ' . $node->name + . "\n" . '{' . "\n" . $this->pStmts($node->stmts) . "\n" . '}'; + } + ``` + + New: + + ```php + public function pStmt_Trait(Stmt\Trait_ $node) { + return 'trait ' . $node->name + . "\n" . '{' . $this->pStmts($node->stmts) . "\n" . '}'; + } + ``` + + [code_gen]: https://github.com/nikic/PHP-Parser/wiki/Projects-using-the-PHP-Parser#code-generation \ No newline at end of file diff --git a/lib/nikic/php-parser/UPGRADE-2.0.md b/lib/nikic/php-parser/UPGRADE-2.0.md new file mode 100644 index 000000000..1c61de54f --- /dev/null +++ b/lib/nikic/php-parser/UPGRADE-2.0.md @@ -0,0 +1,74 @@ +Upgrading from PHP-Parser 1.x to 2.0 +==================================== + +### PHP version requirements + +PHP-Parser now requires PHP 5.4 or newer to run. It is however still possible to *parse* PHP 5.2 and +PHP 5.3 source code, while running on a newer version. + +### Creating a parser instance + +Parser instances should now be created through the `ParserFactory`. Old direct instantiation code +will not work, because the parser class was renamed. + +Old: + +```php +use PhpParser\Parser, PhpParser\Lexer; +$parser = new Parser(new Lexer\Emulative); +``` + +New: + +```php +use PhpParser\ParserFactory; +$parser = (new ParserFactory)->create(ParserFactory::PREFER_PHP7); +``` + +The first argument to `ParserFactory` determines how different PHP versions are handled. The +possible values are: + + * `ParserFactory::PREFER_PHP7`: Try to parse code as PHP 7. If this fails, try to parse it as PHP 5. + * `ParserFactory::PREFER_PHP5`: Try to parse code as PHP 5. If this fails, try to parse it as PHP 7. + * `ParserFactory::ONLY_PHP7`: Parse code as PHP 7. + * `ParserFactory::ONLY_PHP5`: Parse code as PHP 5. + +For most practical purposes the difference between `PREFER_PHP7` and `PREFER_PHP5` is mainly whether +a scalar type hint like `string` will be stored as `'string'` (PHP 7) or as `new Name('string')` +(PHP 5). + +To use a custom lexer, pass it as the second argument to the `create()` method: + +```php +use PhpParser\ParserFactory; +$lexer = new MyLexer; +$parser = (new ParserFactory)->create(ParserFactory::PREFER_PHP7, $lexer); +``` + +### Rename of the `PhpParser\Parser` class + +`PhpParser\Parser` is now an interface, which is implemented by `Parser\Php5`, `Parser\Php7` and +`Parser\Multiple`. Parser tokens are now defined in `Parser\Tokens`. If you use the `ParserFactory` +described above to create your parser instance, these changes should have no further impact on you. + +### Removal of legacy aliases + +All legacy aliases for classes have been removed. This includes the old non-namespaced `PHPParser_` +classes, as well as the classes that had to be renamed for PHP 7 support. + +### Deprecations + +The `set()`, `setFirst()`, `append()` and `prepend()` methods of the `Node\Name` class have been +deprecated. Instead `Name::concat()` and `Name->slice()` should be used. + +### Miscellaneous + +* The `NodeTraverser` no longer clones nodes by default. If you want to restore the old behavior, + pass `true` to the constructor. +* The legacy node format has been removed. If you use custom nodes, they are now expected to + implement a `getSubNodeNames()` method. +* The default value for `Scalar` node constructors was removed. This means that something like + `new LNumber()` should be replaced by `new LNumber(0)`. +* String parts of encapsed strings are now represented using `Scalar\EncapsStringPart` nodes, while + previously raw strings were used. This affects the `parts` child of `Scalar\Encaps` and + `Expr\ShellExec`. \ No newline at end of file diff --git a/lib/nikic/php-parser/UPGRADE-3.0.md b/lib/nikic/php-parser/UPGRADE-3.0.md new file mode 100644 index 000000000..9e04f2afd --- /dev/null +++ b/lib/nikic/php-parser/UPGRADE-3.0.md @@ -0,0 +1,160 @@ +Upgrading from PHP-Parser 2.x to 3.0 +==================================== + +The backwards-incompatible changes in this release may be summarized as follows: + + * The specific details of the node representation have changed in some cases, primarily to + accomodate new PHP 7.1 features. + * There have been significant changes to the error recovery implementation. This may affect you, + if you used the error recovery mode or have a custom lexer implementation. + * A number of deprecated methods were removed. + +### PHP version requirements + +PHP-Parser now requires PHP 5.5 or newer to run. It is however still possible to *parse* PHP 5.2, +5.3 and 5.4 source code, while running on a newer version. + +### Changes to the node structure + +The following changes are likely to require code changes if the respective nodes are used: + + * The `List` subnode `vars` has been renamed to `items` and now contains `ArrayItem`s instead of + plain variables. + * The `Catch` subnode `type` has been renamed to `types` and is now an array of `Name`s. + * The `TryCatch` subnode `finallyStmts` has been replaced with a `finally` subnode that holds an + explicit `Finally` node. + * The `type` subnode on `Class`, `ClassMethod` and `Property` has been renamed to `flags`. The + `type` subnode has retained for backwards compatibility and is populated to the same value as + `flags`. However, writes to `type` will not update `flags` and use of `type` is discouraged. + +The following changes are unlikely to require code changes: + + * The `ClassConst` constructor changed to accept an additional `flags` subnode. + * The `Trait` constructor now has the same form as the `Class` and `Interface` constructors: It + takes an array of subnodes. Unlike classes/interfaces, traits can only have a `stmts` subnode. + * The `Array` subnode `items` may now contain `null` elements (due to destructuring). + * `void` and `iterable` types are now stored as strings if the PHP 7 parser is used. Previously + these would have been represented as `Name` instances. + +### Changes to error recovery mode + +Previously, error recovery mode was enabled by setting the `throwOnError` option to `false` when +creating the parser, while collected errors were retrieved using the `getErrors()` method: + +```php +$lexer = ...; +$parser = (new ParserFactory)->create(ParserFactor::ONLY_PHP7, $lexer, [ + 'throwOnError' => true, +]); + +$stmts = $parser->parse($code); +$errors = $parser->getErrors(); +if ($errors) { + handleErrors($errors); +} +processAst($stmts); +``` + +Both the `throwOnError` option and the `getErrors()` method have been removed in PHP-Parser 3.0. +Instead an instance of `ErrorHandler\Collecting` should be passed to the `parse()` method: + +```php +$lexer = ...; +$parser = (new ParserFactory)->create(ParserFactor::ONLY_PHP7, $lexer); + +$errorHandler = new ErrorHandler\Collecting; +$stmts = $parser->parse($code, $errorHandler); +if ($errorHandler->hasErrors()) { + handleErrors($errorHandler->getErrors()); +} +processAst($stmts); +``` + +#### Multiple parser fallback in error recovery mode + +As a result of this change, if a `Multiple` parser is used (e.g. through the `ParserFactory` using +`PREFER_PHP7` or `PREFER_PHP5`), it will now return the result of the first *non-throwing* parse. As +parsing never throws in error recovery mode, the result from the first parser will always be +returned. + +The PHP 7 parser is a superset of the PHP 5 parser, with the exceptions that `=& new` and +`global $$foo->bar` are not supported (other differences are in representation only). The PHP 7 +parser will be able to recover from the error in both cases. For this reason, this change will +likely pass unnoticed if you do not specifically test for this syntax. + +It is possible to restore the precise previous behavior with the following code: + +```php +$lexer = ...; +$parser7 = new Parser\Php7($lexer); +$parser5 = new Parser\Php5($lexer); + +$errors7 = new ErrorHandler\Collecting(); +$stmts7 = $parser7->parse($code, $errors7); +if ($errors7->hasErrors()) { + $errors5 = new ErrorHandler\Collecting(); + $stmts5 = $parser5->parse($code, $errors5); + if (!$errors5->hasErrors()) { + // If PHP 7 parse has errors but PHP 5 parse has no errors, use PHP 5 result + return [$stmts5, $errors5]; + } +} +// If PHP 7 succeeds or both fail use PHP 7 result +return [$stmts7, $errors7]; +``` + +#### Error handling in the lexer + +In order to support recovery from lexer errors, the signature of the `startLexing()` method changed +to optionally accept an `ErrorHandler`: + +```php +// OLD +public function startLexing($code); +// NEW +public function startLexing($code, ErrorHandler $errorHandler = null); +``` + +If you use a custom lexer with overriden `startLexing()` method, it needs to be changed to accept +the extra parameter. The value should be passed on to the parent method. + +#### Error checks in node constructors + +The constructors of certain nodes used to contain additional checks for semantic errors, such as +creating a try block without either catch or finally. These checks have been moved from the node +constructors into the parser. This allows recovery from such errors, as well as representing the +resulting (invalid) AST. + +This means that certain error conditions are no longer checked for manually constructed nodes. + +### Removed methods, arguments, options + +The following methods, arguments or options have been removed: + + * `Comment::setLine()`, `Comment::setText()`: Create new `Comment` instances instead. + * `Name::set()`, `Name::setFirst()`, `Name::setLast()`, `Name::append()`, `Name::prepend()`: + Use `Name::concat()` in combination with `Name::slice()` instead. + * `Error::getRawLine()`, `Error::setRawLine()`. Use `Error::getStartLine()` and + `Error::setStartLine()` instead. + * `Parser::getErrors()`. Use `ErrorHandler\Collecting` instead. + * `$separator` argument of `Name::toString()`. Use `strtr()` instead, if you really need it. + * `$cloneNodes` argument of `NodeTraverser::__construct()`. Explicitly clone nodes in the visitor + instead. + * `throwOnError` parser option. Use `ErrorHandler\Collecting` instead. + +### Miscellaneous + + * The `NameResolver` will now resolve unqualified function and constant names in the global + namespace into fully qualified names. For example `foo()` in the global namespace resolves to + `\foo()`. For names where no static resolution is possible, a `namespacedName` attribute is + added now, containing the namespaced variant of the name. + * All methods on `PrettyPrinter\Standard` are now protected. Previoulsy most of them were public. + The pretty printer should only be invoked using the `prettyPrint()`, `prettyPrintFile()` and + `prettyPrintExpr()` methods. + * The node dumper now prints numeric values that act as enums/flags in a string representation. + If node dumper results are used in tests, updates may be needed to account for this. + * The constants on `NameTraverserInterface` have been moved into the `NameTraverser` class. + * The emulative lexer now directly postprocesses tokens, instead of using `~__EMU__~` sequences. + This changes the protected API of the emulative lexer. + * The `Name::slice()` method now returns `null` for empty slices, previously `new Name([])` was + used. `Name::concat()` now also supports concatenation with `null`. diff --git a/lib/nikic/php-parser/bin/php-parse b/lib/nikic/php-parser/bin/php-parse new file mode 100755 index 000000000..1760e758d --- /dev/null +++ b/lib/nikic/php-parser/bin/php-parse @@ -0,0 +1,202 @@ +#!/usr/bin/env php + array( + 'startLine', 'endLine', 'startFilePos', 'endFilePos', 'comments' +))); +$parser = (new PhpParser\ParserFactory)->create( + PhpParser\ParserFactory::PREFER_PHP7, + $lexer +); +$dumper = new PhpParser\NodeDumper([ + 'dumpComments' => true, + 'dumpPositions' => $attributes['with-positions'], +]); +$prettyPrinter = new PhpParser\PrettyPrinter\Standard; +$serializer = new PhpParser\Serializer\XML; + +$traverser = new PhpParser\NodeTraverser(); +$traverser->addVisitor(new PhpParser\NodeVisitor\NameResolver); + +foreach ($files as $file) { + if (strpos($file, ' Code $code\n"; + } else { + if (!file_exists($file)) { + die("File $file does not exist.\n"); + } + + $code = file_get_contents($file); + echo "====> File $file:\n"; + } + + if ($attributes['with-recovery']) { + $errorHandler = new PhpParser\ErrorHandler\Collecting; + $stmts = $parser->parse($code, $errorHandler); + foreach ($errorHandler->getErrors() as $error) { + $message = formatErrorMessage($error, $code, $attributes['with-column-info']); + echo $message . "\n"; + } + if (null === $stmts) { + continue; + } + } else { + try { + $stmts = $parser->parse($code); + } catch (PhpParser\Error $error) { + $message = formatErrorMessage($error, $code, $attributes['with-column-info']); + die($message . "\n"); + } + } + + foreach ($operations as $operation) { + if ('dump' === $operation) { + echo "==> Node dump:\n"; + echo $dumper->dump($stmts, $code), "\n"; + } elseif ('pretty-print' === $operation) { + echo "==> Pretty print:\n"; + echo $prettyPrinter->prettyPrintFile($stmts), "\n"; + } elseif ('serialize-xml' === $operation) { + echo "==> Serialized XML:\n"; + echo $serializer->serialize($stmts), "\n"; + } elseif ('var-dump' === $operation) { + echo "==> var_dump():\n"; + var_dump($stmts); + } elseif ('resolve-names' === $operation) { + echo "==> Resolved names.\n"; + $stmts = $traverser->traverse($stmts); + } + } +} + +function formatErrorMessage(PhpParser\Error $e, $code, $withColumnInfo) { + if ($withColumnInfo && $e->hasColumnInfo()) { + return $e->getMessageWithColumnInfo($code); + } else { + return $e->getMessage(); + } +} + +function showHelp($error = '') { + if ($error) { + echo $error . "\n\n"; + } + die(<< false, + 'with-positions' => false, + 'with-recovery' => false, + ); + + array_shift($args); + $parseOptions = true; + foreach ($args as $arg) { + if (!$parseOptions) { + $files[] = $arg; + continue; + } + + switch ($arg) { + case '--dump': + case '-d': + $operations[] = 'dump'; + break; + case '--pretty-print': + case '-p': + $operations[] = 'pretty-print'; + break; + case '--serialize-xml': + $operations[] = 'serialize-xml'; + break; + case '--var-dump': + $operations[] = 'var-dump'; + break; + case '--resolve-names': + case '-N'; + $operations[] = 'resolve-names'; + break; + case '--with-column-info': + case '-c'; + $attributes['with-column-info'] = true; + break; + case '--with-positions': + case '-P': + $attributes['with-positions'] = true; + break; + case '--with-recovery': + case '-r': + $attributes['with-recovery'] = true; + break; + case '--help': + case '-h'; + showHelp(); + break; + case '--': + $parseOptions = false; + break; + default: + if ($arg[0] === '-') { + showHelp("Invalid operation $arg."); + } else { + $files[] = $arg; + } + } + } + + return array($operations, $files, $attributes); +} diff --git a/lib/nikic/php-parser/composer.json b/lib/nikic/php-parser/composer.json new file mode 100644 index 000000000..66df90a8f --- /dev/null +++ b/lib/nikic/php-parser/composer.json @@ -0,0 +1,30 @@ +{ + "name": "nikic/php-parser", + "description": "A PHP parser written in PHP", + "keywords": ["php", "parser"], + "type": "library", + "license": "BSD-3-Clause", + "authors": [ + { + "name": "Nikita Popov" + } + ], + "require": { + "php": ">=5.5", + "ext-tokenizer": "*" + }, + "require-dev": { + "phpunit/phpunit": "~4.0|~5.0" + }, + "autoload": { + "psr-4": { + "PhpParser\\": "lib/PhpParser" + } + }, + "bin": ["bin/php-parse"], + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + } +} diff --git a/lib/nikic/php-parser/doc/0_Introduction.markdown b/lib/nikic/php-parser/doc/0_Introduction.markdown new file mode 100644 index 000000000..ca1ceb2ec --- /dev/null +++ b/lib/nikic/php-parser/doc/0_Introduction.markdown @@ -0,0 +1,80 @@ +Introduction +============ + +This project is a PHP 5.2 to PHP 7.1 parser **written in PHP itself**. + +What is this for? +----------------- + +A parser is useful for [static analysis][0], manipulation of code and basically any other +application dealing with code programmatically. A parser constructs an [Abstract Syntax Tree][1] +(AST) of the code and thus allows dealing with it in an abstract and robust way. + +There are other ways of processing source code. One that PHP supports natively is using the +token stream generated by [`token_get_all`][2]. The token stream is much more low level than +the AST and thus has different applications: It allows to also analyze the exact formatting of +a file. On the other hand the token stream is much harder to deal with for more complex analysis. +For example an AST abstracts away the fact that in PHP variables can be written as `$foo`, but also +as `$$bar`, `${'foobar'}` or even `${!${''}=barfoo()}`. You don't have to worry about recognizing +all the different syntaxes from a stream of tokens. + +Another question is: Why would I want to have a PHP parser *written in PHP*? Well, PHP might not be +a language especially suited for fast parsing, but processing the AST is much easier in PHP than it +would be in other, faster languages like C. Furthermore the people most probably wanting to do +programmatic PHP code analysis are incidentally PHP developers, not C developers. + +What can it parse? +------------------ + +The parser supports parsing PHP 5.2-5.6 and PHP 7. + +As the parser is based on the tokens returned by `token_get_all` (which is only able to lex the PHP +version it runs on), additionally a wrapper for emulating tokens from newer versions is provided. +This allows to parse PHP 7.1 source code running on PHP 5.5, for example. This emulation is somewhat +hacky and not perfect, but it should work well on any sane code. + +What output does it produce? +---------------------------- + +The parser produces an [Abstract Syntax Tree][1] (AST) also known as a node tree. How this looks like +can best be seen in an example. The program `create(ParserFactory::PREFER_PHP7); +``` + +The factory accepts a kind argument, that determines how different PHP versions are treated: + +Kind | Behavior +-----|--------- +`ParserFactory::PREFER_PHP7` | Try to parse code as PHP 7. If this fails, try to parse it as PHP 5. +`ParserFactory::PREFER_PHP5` | Try to parse code as PHP 5. If this fails, try to parse it as PHP 7. +`ParserFactory::ONLY_PHP7` | Parse code as PHP 7. +`ParserFactory::ONLY_PHP5` | Parse code as PHP 5. + +Unless you have strong reason to use something else, `PREFER_PHP7` is a reasonable default. + +The `create()` method optionally accepts a `Lexer` instance as the second argument. Some use cases +that require customized lexers are discussed in the [lexer documentation](component/Lexer.markdown). + +Subsequently you can pass PHP code (including the opening `create(ParserFactory::PREFER_PHP7); + +try { + $stmts = $parser->parse($code); + // $stmts is an array of statement nodes +} catch (Error $e) { + echo 'Parse Error: ', $e->getMessage(); +} +``` + +A parser instance can be reused to parse multiple files. + +Node tree +--------- + +If you use the above code with `$code = "subNodeName`. The `Stmt\Echo_` node has only one subnode `exprs`. So in order to access it +in the above example you would write `$stmts[0]->exprs`. If you wanted to access the name of the function +call, you would write `$stmts[0]->exprs[1]->name`. + +All nodes also define a `getType()` method that returns the node type. The type is the class name +without the `PhpParser\Node\` prefix and `\` replaced with `_`. It also does not contain a trailing +`_` for reserved-keyword class names. + +It is possible to associate custom metadata with a node using the `setAttribute()` method. This data +can then be retrieved using `hasAttribute()`, `getAttribute()` and `getAttributes()`. + +By default the lexer adds the `startLine`, `endLine` and `comments` attributes. `comments` is an array +of `PhpParser\Comment[\Doc]` instances. + +The start line can also be accessed using `getLine()`/`setLine()` (instead of `getAttribute('startLine')`). +The last doc comment from the `comments` attribute can be obtained using `getDocComment()`. + +Pretty printer +-------------- + +The pretty printer component compiles the AST back to PHP code. As the parser does not retain formatting +information the formatting is done using a specified scheme. Currently there is only one scheme available, +namely `PhpParser\PrettyPrinter\Standard`. + +```php +use PhpParser\Error; +use PhpParser\ParserFactory; +use PhpParser\PrettyPrinter; + +$code = "create(ParserFactory::PREFER_PHP7); +$prettyPrinter = new PrettyPrinter\Standard; + +try { + // parse + $stmts = $parser->parse($code); + + // change + $stmts[0] // the echo statement + ->exprs // sub expressions + [0] // the first of them (the string node) + ->value // it's value, i.e. 'Hi ' + = 'Hello '; // change to 'Hello ' + + // pretty print + $code = $prettyPrinter->prettyPrint($stmts); + + echo $code; +} catch (Error $e) { + echo 'Parse Error: ', $e->getMessage(); +} +``` + +The above code will output: + + parse()`, then changed and then +again converted to code using `PhpParser\PrettyPrinter\Standard->prettyPrint()`. + +The `prettyPrint()` method pretty prints a statements array. It is also possible to pretty print only a +single expression using `prettyPrintExpr()`. + +The `prettyPrintFile()` method can be used to print an entire file. This will include the opening `create(ParserFactory::PREFER_PHP7); +$traverser = new NodeTraverser; +$prettyPrinter = new PrettyPrinter\Standard; + +// add your visitor +$traverser->addVisitor(new MyNodeVisitor); + +try { + $code = file_get_contents($fileName); + + // parse + $stmts = $parser->parse($code); + + // traverse + $stmts = $traverser->traverse($stmts); + + // pretty print + $code = $prettyPrinter->prettyPrintFile($stmts); + + echo $code; +} catch (PhpParser\Error $e) { + echo 'Parse Error: ', $e->getMessage(); +} +``` + +The corresponding node visitor might look like this: + +```php +use PhpParser\Node; +use PhpParser\NodeVisitorAbstract; + +class MyNodeVisitor extends NodeVisitorAbstract +{ + public function leaveNode(Node $node) { + if ($node instanceof Node\Scalar\String_) { + $node->value = 'foo'; + } + } +} +``` + +The above node visitor would change all string literals in the program to `'foo'`. + +All visitors must implement the `PhpParser\NodeVisitor` interface, which defines the following four +methods: + +```php +public function beforeTraverse(array $nodes); +public function enterNode(\PhpParser\Node $node); +public function leaveNode(\PhpParser\Node $node); +public function afterTraverse(array $nodes); +``` + +The `beforeTraverse()` method is called once before the traversal begins and is passed the nodes the +traverser was called with. This method can be used for resetting values before traversation or +preparing the tree for traversal. + +The `afterTraverse()` method is similar to the `beforeTraverse()` method, with the only difference that +it is called once after the traversal. + +The `enterNode()` and `leaveNode()` methods are called on every node, the former when it is entered, +i.e. before its subnodes are traversed, the latter when it is left. + +All four methods can either return the changed node or not return at all (i.e. `null`) in which +case the current node is not changed. + +The `enterNode()` method can additionally return the value `NodeTraverser::DONT_TRAVERSE_CHILDREN`, +which instructs the traverser to skip all children of the current node. + +The `leaveNode()` method can additionally return the value `NodeTraverser::REMOVE_NODE`, in which +case the current node will be removed from the parent array. Furthermore it is possible to return +an array of nodes, which will be merged into the parent array at the offset of the current node. +I.e. if in `array(A, B, C)` the node `B` should be replaced with `array(X, Y, Z)` the result will +be `array(A, X, Y, Z, C)`. + +Instead of manually implementing the `NodeVisitor` interface you can also extend the `NodeVisitorAbstract` +class, which will define empty default implementations for all the above methods. + +The NameResolver node visitor +----------------------------- + +One visitor is already bundled with the package: `PhpParser\NodeVisitor\NameResolver`. This visitor +helps you work with namespaced code by trying to resolve most names to fully qualified ones. + +For example, consider the following code: + + use A as B; + new B\C(); + +In order to know that `B\C` really is `A\C` you would need to track aliases and namespaces yourself. +The `NameResolver` takes care of that and resolves names as far as possible. + +After running it most names will be fully qualified. The only names that will stay unqualified are +unqualified function and constant names. These are resolved at runtime and thus the visitor can't +know which function they are referring to. In most cases this is a non-issue as the global functions +are meant. + +Also the `NameResolver` adds a `namespacedName` subnode to class, function and constant declarations +that contains the namespaced name instead of only the shortname that is available via `name`. + +Example: Converting namespaced code to pseudo namespaces +-------------------------------------------------------- + +A small example to understand the concept: We want to convert namespaced code to pseudo namespaces +so it works on 5.2, i.e. names like `A\\B` should be converted to `A_B`. Note that such conversions +are fairly complicated if you take PHP's dynamic features into account, so our conversion will +assume that no dynamic features are used. + +We start off with the following base code: + +```php +use PhpParser\ParserFactory; +use PhpParser\PrettyPrinter; +use PhpParser\NodeTraverser; +use PhpParser\NodeVisitor\NameResolver; + +$inDir = '/some/path'; +$outDir = '/some/other/path'; + +$parser = (new ParserFactory)->create(ParserFactory::PREFER_PHP7); +$traverser = new NodeTraverser; +$prettyPrinter = new PrettyPrinter\Standard; + +$traverser->addVisitor(new NameResolver); // we will need resolved names +$traverser->addVisitor(new NamespaceConverter); // our own node visitor + +// iterate over all .php files in the directory +$files = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($inDir)); +$files = new \RegexIterator($files, '/\.php$/'); + +foreach ($files as $file) { + try { + // read the file that should be converted + $code = file_get_contents($file); + + // parse + $stmts = $parser->parse($code); + + // traverse + $stmts = $traverser->traverse($stmts); + + // pretty print + $code = $prettyPrinter->prettyPrintFile($stmts); + + // write the converted file to the target directory + file_put_contents( + substr_replace($file->getPathname(), $outDir, 0, strlen($inDir)), + $code + ); + } catch (PhpParser\Error $e) { + echo 'Parse Error: ', $e->getMessage(); + } +} +``` + +Now lets start with the main code, the `NodeVisitor\NamespaceConverter`. One thing it needs to do +is convert `A\\B` style names to `A_B` style ones. + +```php +use PhpParser\Node; + +class NamespaceConverter extends \PhpParser\NodeVisitorAbstract +{ + public function leaveNode(Node $node) { + if ($node instanceof Node\Name) { + return new Node\Name($node->toString('_')); + } + } +} +``` + +The above code profits from the fact that the `NameResolver` already resolved all names as far as +possible, so we don't need to do that. We only need to create a string with the name parts separated +by underscores instead of backslashes. This is what `$node->toString('_')` does. (If you want to +create a name with backslashes either write `$node->toString()` or `(string) $node`.) Then we create +a new name from the string and return it. Returning a new node replaces the old node. + +Another thing we need to do is change the class/function/const declarations. Currently they contain +only the shortname (i.e. the last part of the name), but they need to contain the complete name including +the namespace prefix: + +```php +use PhpParser\Node; +use PhpParser\Node\Stmt; + +class NodeVisitor_NamespaceConverter extends \PhpParser\NodeVisitorAbstract +{ + public function leaveNode(Node $node) { + if ($node instanceof Node\Name) { + return new Node\Name($node->toString('_')); + } elseif ($node instanceof Stmt\Class_ + || $node instanceof Stmt\Interface_ + || $node instanceof Stmt\Function_) { + $node->name = $node->namespacedName->toString('_'); + } elseif ($node instanceof Stmt\Const_) { + foreach ($node->consts as $const) { + $const->name = $const->namespacedName->toString('_'); + } + } + } +} +``` + +There is not much more to it than converting the namespaced name to string with `_` as separator. + +The last thing we need to do is remove the `namespace` and `use` statements: + +```php +use PhpParser\Node; +use PhpParser\Node\Stmt; + +class NodeVisitor_NamespaceConverter extends \PhpParser\NodeVisitorAbstract +{ + public function leaveNode(Node $node) { + if ($node instanceof Node\Name) { + return new Node\Name($node->toString('_')); + } elseif ($node instanceof Stmt\Class_ + || $node instanceof Stmt\Interface_ + || $node instanceof Stmt\Function_) { + $node->name = $node->namespacedName->toString('_'); + } elseif ($node instanceof Stmt\Const_) { + foreach ($node->consts as $const) { + $const->name = $const->namespacedName->toString('_'); + } + } elseif ($node instanceof Stmt\Namespace_) { + // returning an array merges is into the parent array + return $node->stmts; + } elseif ($node instanceof Stmt\Use_) { + // returning false removed the node altogether + return false; + } + } +} +``` + +That's all. diff --git a/lib/nikic/php-parser/doc/3_Other_node_tree_representations.markdown b/lib/nikic/php-parser/doc/3_Other_node_tree_representations.markdown new file mode 100644 index 000000000..0830f399c --- /dev/null +++ b/lib/nikic/php-parser/doc/3_Other_node_tree_representations.markdown @@ -0,0 +1,330 @@ +Other node tree representations +=============================== + +It is possible to convert the AST into several textual representations, which serve different uses. + +Simple serialization +-------------------- + +It is possible to serialize the node tree using `serialize()` and also unserialize it using +`unserialize()`. The output is not human readable and not easily processable from anything +but PHP, but it is compact and generates quickly. The main application thus is in caching. + +Human readable dumping +---------------------- + +Furthermore it is possible to dump nodes into a human readable format using the `dump` method of +`PhpParser\NodeDumper`. This can be used for debugging. + +```php +$code = <<<'CODE' +create(PhpParser\ParserFactory::PREFER_PHP7); +$nodeDumper = new PhpParser\NodeDumper; + +try { + $stmts = $parser->parse($code); + + echo $nodeDumper->dump($stmts), "\n"; +} catch (PhpParser\Error $e) { + echo 'Parse Error: ', $e->getMessage(); +} +``` + +The above script will have an output looking roughly like this: + +``` +array( + 0: Stmt_Function( + byRef: false + params: array( + 0: Param( + name: msg + default: null + type: null + byRef: false + ) + ) + stmts: array( + 0: Stmt_Echo( + exprs: array( + 0: Expr_Variable( + name: msg + ) + 1: Scalar_String( + value: + + ) + ) + ) + ) + name: printLine + ) + 1: Expr_FuncCall( + name: Name( + parts: array( + 0: printLine + ) + ) + args: array( + 0: Arg( + value: Scalar_String( + value: Hello World!!! + ) + byRef: false + ) + ) + ) +) +``` + +JSON encoding +------------- + +Nodes (and comments) implement the `JsonSerializable` interface. As such, it is possible to JSON +encode the AST directly using `json_encode()`: + +```php +$code = <<<'CODE' +create(PhpParser\ParserFactory::PREFER_PHP7); +$nodeDumper = new PhpParser\NodeDumper; + +try { + $stmts = $parser->parse($code); + + echo json_encode($stmts, JSON_PRETTY_PRINT), "\n"; +} catch (PhpParser\Error $e) { + echo 'Parse Error: ', $e->getMessage(); +} +``` + +This will result in the following output (which includes attributes): + +```json +[ + { + "nodeType": "Stmt_Function", + "byRef": false, + "name": "printLine", + "params": [ + { + "nodeType": "Param", + "type": null, + "byRef": false, + "variadic": false, + "name": "msg", + "default": null, + "attributes": { + "startLine": 3, + "endLine": 3 + } + } + ], + "returnType": null, + "stmts": [ + { + "nodeType": "Stmt_Echo", + "exprs": [ + { + "nodeType": "Expr_Variable", + "name": "msg", + "attributes": { + "startLine": 4, + "endLine": 4 + } + }, + { + "nodeType": "Scalar_String", + "value": "\n", + "attributes": { + "startLine": 4, + "endLine": 4, + "kind": 2 + } + } + ], + "attributes": { + "startLine": 4, + "endLine": 4 + } + } + ], + "attributes": { + "startLine": 3, + "endLine": 5 + } + }, + { + "nodeType": "Expr_FuncCall", + "name": { + "nodeType": "Name", + "parts": [ + "printLine" + ], + "attributes": { + "startLine": 7, + "endLine": 7 + } + }, + "args": [ + { + "nodeType": "Arg", + "value": { + "nodeType": "Scalar_String", + "value": "Hello World!!!", + "attributes": { + "startLine": 7, + "endLine": 7, + "kind": 1 + } + }, + "byRef": false, + "unpack": false, + "attributes": { + "startLine": 7, + "endLine": 7 + } + } + ], + "attributes": { + "startLine": 7, + "endLine": 7 + } + } +] +``` + +There is currently no mechanism to convert JSON back into a node tree. Furthermore, not all ASTs +can be JSON encoded. In particular, JSON only supports UTF-8 strings. + +Serialization to XML +-------------------- + +It is also possible to serialize the node tree to XML using `PhpParser\Serializer\XML->serialize()` +and to unserialize it using `PhpParser\Unserializer\XML->unserialize()`. This is useful for +interfacing with other languages and applications or for doing transformation using XSLT. + +```php +create(PhpParser\ParserFactory::PREFER_PHP7); +$serializer = new PhpParser\Serializer\XML; + +try { + $stmts = $parser->parse($code); + + echo $serializer->serialize($stmts); +} catch (PhpParser\Error $e) { + echo 'Parse Error: ', $e->getMessage(); +} +``` + +Produces: + +```xml + + + + + + + + + + + + msg + + + + + + + + + + + + + + + + + + + + + msg + + + + + + + + + + + + + + + printLine + + + + + + + + printLine + + + + + + + + + + + Hello World!!! + + + + + + + + + + + + +``` \ No newline at end of file diff --git a/lib/nikic/php-parser/doc/4_Code_generation.markdown b/lib/nikic/php-parser/doc/4_Code_generation.markdown new file mode 100644 index 000000000..2c0aa0ede --- /dev/null +++ b/lib/nikic/php-parser/doc/4_Code_generation.markdown @@ -0,0 +1,84 @@ +Code generation +=============== + +It is also possible to generate code using the parser, by first creating an Abstract Syntax Tree and then using the +pretty printer to convert it to PHP code. To simplify code generation, the project comes with builders which allow +creating node trees using a fluid interface, instead of instantiating all nodes manually. Builders are available for +the following syntactic elements: + + * namespaces and use statements + * classes, interfaces and traits + * methods, functions and parameters + * properties + +Here is an example: + +```php +use PhpParser\BuilderFactory; +use PhpParser\PrettyPrinter; +use PhpParser\Node; + +$factory = new BuilderFactory; +$node = $factory->namespace('Name\Space') + ->addStmt($factory->use('Some\Other\Thingy')->as('SomeOtherClass')) + ->addStmt($factory->class('SomeClass') + ->extend('SomeOtherClass') + ->implement('A\Few', '\Interfaces') + ->makeAbstract() // ->makeFinal() + + ->addStmt($factory->method('someMethod') + ->makePublic() + ->makeAbstract() // ->makeFinal() + ->setReturnType('bool') + ->addParam($factory->param('someParam')->setTypeHint('SomeClass')) + ->setDocComment('/** + * This method does something. + * + * @param SomeClass And takes a parameter + */') + ) + + ->addStmt($factory->method('anotherMethod') + ->makeProtected() // ->makePublic() [default], ->makePrivate() + ->addParam($factory->param('someParam')->setDefault('test')) + // it is possible to add manually created nodes + ->addStmt(new Node\Expr\Print_(new Node\Expr\Variable('someParam'))) + ) + + // properties will be correctly reordered above the methods + ->addStmt($factory->property('someProperty')->makeProtected()) + ->addStmt($factory->property('anotherProperty')->makePrivate()->setDefault(array(1, 2, 3))) + ) + + ->getNode() +; + +$stmts = array($node); +$prettyPrinter = new PrettyPrinter\Standard(); +echo $prettyPrinter->prettyPrintFile($stmts); +``` + +This will produce the following output with the standard pretty printer: + +```php + array('comments', 'startLine', 'endLine', 'startFilePos', 'endFilePos'), +)); +$parser = (new PhpParser\ParserFactory)->create(PhpParser\ParserFactory::PREFER_PHP7, $lexer); + +try { + $stmts = $parser->parse($code); + // ... +} catch (PhpParser\Error $e) { + // ... +} +``` + +Before using column information its availability needs to be checked with `$e->hasColumnInfo()`, as the precise +location of an error cannot always be determined. The methods for retrieving column information also have to be passed +the source code of the parsed file. An example for printing an error: + +```php +if ($e->hasColumnInfo()) { + echo $e->getRawMessage() . ' from ' . $e->getStartLine() . ':' . $e->getStartColumn($code) + . ' to ' . $e->getEndLine() . ':' . $e->getEndColumn($code); + // or: + echo $e->getMessageWithColumnInfo(); +} else { + echo $e->getMessage(); +} +``` + +Both line numbers and column numbers are 1-based. EOF errors will be located at the position one past the end of the +file. + +Error recovery +-------------- + +The error behavior of the parser (and other components) is controlled by an `ErrorHandler`. Whenever an error is +encountered, `ErrorHandler::handleError()` is invoked. The default error handling strategy is `ErrorHandler\Throwing`, +which will immediately throw when an error is encountered. + +To instead collect all encountered errors into an array, while trying to continue parsing the rest of the source code, +an instance of `ErrorHandler\Collecting` can be passed to the `Parser::parse()` method. A usage example: + +```php +$parser = (new PhpParser\ParserFactory)->create(PhpParser\ParserFactory::ONLY_PHP7); +$errorHandler = new PhpParser\ErrorHandler\Collecting; + +$stmts = $parser->parse($code, $errorHandler); + +if ($errorHandler->hasErrors()) { + foreach ($errorHandler->getErrors() as $error) { + // $error is an ordinary PhpParser\Error + } +} + +if (null !== $stmts) { + // $stmts is a best-effort partial AST +} +``` + +The `NameResolver` visitor also accepts an `ErrorHandler` as a constructor argument. \ No newline at end of file diff --git a/lib/nikic/php-parser/doc/component/Lexer.markdown b/lib/nikic/php-parser/doc/component/Lexer.markdown new file mode 100644 index 000000000..b22942dd1 --- /dev/null +++ b/lib/nikic/php-parser/doc/component/Lexer.markdown @@ -0,0 +1,152 @@ +Lexer component documentation +============================= + +The lexer is responsible for providing tokens to the parser. The project comes with two lexers: `PhpParser\Lexer` and +`PhpParser\Lexer\Emulative`. The latter is an extension of the former, which adds the ability to emulate tokens of +newer PHP versions and thus allows parsing of new code on older versions. + +This documentation discusses options available for the default lexers and explains how lexers can be extended. + +Lexer options +------------- + +The two default lexers accept an `$options` array in the constructor. Currently only the `'usedAttributes'` option is +supported, which allows you to specify which attributes will be added to the AST nodes. The attributes can then be +accessed using `$node->getAttribute()`, `$node->setAttribute()`, `$node->hasAttribute()` and `$node->getAttributes()` +methods. A sample options array: + +```php +$lexer = new PhpParser\Lexer(array( + 'usedAttributes' => array( + 'comments', 'startLine', 'endLine' + ) +)); +``` + +The attributes used in this example match the default behavior of the lexer. The following attributes are supported: + + * `comments`: Array of `PhpParser\Comment` or `PhpParser\Comment\Doc` instances, representing all comments that occurred + between the previous non-discarded token and the current one. Use of this attribute is required for the + `$node->getDocComment()` method to work. The attribute is also needed if you wish the pretty printer to retain + comments present in the original code. + * `startLine`: Line in which the node starts. This attribute is required for the `$node->getLine()` to work. It is also + required if syntax errors should contain line number information. + * `endLine`: Line in which the node ends. + * `startTokenPos`: Offset into the token array of the first token in the node. + * `endTokenPos`: Offset into the token array of the last token in the node. + * `startFilePos`: Offset into the code string of the first character that is part of the node. + * `endFilePos`: Offset into the code string of the last character that is part of the node. + +### Using token positions + +The token offset information is useful if you wish to examine the exact formatting used for a node. For example the AST +does not distinguish whether a property was declared using `public` or using `var`, but you can retrieve this +information based on the token position: + +```php +function isDeclaredUsingVar(array $tokens, PhpParser\Node\Stmt\Property $prop) { + $i = $prop->getAttribute('startTokenPos'); + return $tokens[$i][0] === T_VAR; +} +``` + +In order to make use of this function, you will have to provide the tokens from the lexer to your node visitor using +code similar to the following: + +```php +class MyNodeVisitor extends PhpParser\NodeVisitorAbstract { + private $tokens; + public function setTokens(array $tokens) { + $this->tokens = $tokens; + } + + public function leaveNode(PhpParser\Node $node) { + if ($node instanceof PhpParser\Node\Stmt\Property) { + var_dump(isDeclaredUsingVar($this->tokens, $node)); + } + } +} + +$lexer = new PhpParser\Lexer(array( + 'usedAttributes' => array( + 'comments', 'startLine', 'endLine', 'startTokenPos', 'endTokenPos' + ) +)); +$parser = (new PhpParser\ParserFactory)->create(PhpParser\ParserFactory::PREFER_PHP7, $lexer); + +$visitor = new MyNodeVisitor(); +$traverser = new PhpParser\NodeTraverser(); +$traverser->addVisitor($visitor); + +try { + $stmts = $parser->parse($code); + $visitor->setTokens($lexer->getTokens()); + $stmts = $traverser->traverse($stmts); +} catch (PhpParser\Error $e) { + echo 'Parse Error: ', $e->getMessage(); +} +``` + +The same approach can also be used to perform specific modifications in the code, without changing the formatting in +other places (which is the case when using the pretty printer). + +Lexer extension +--------------- + +A lexer has to define the following public interface: + + void startLexing(string $code, ErrorHandler $errorHandler = null); + array getTokens(); + string handleHaltCompiler(); + int getNextToken(string &$value = null, array &$startAttributes = null, array &$endAttributes = null); + +The `startLexing()` method is invoked with the source code that is to be lexed (including the opening tag) whenever the +`parse()` method of the parser is called. It can be used to reset state or preprocess the source code or tokens. The +passes `ErrorHandler` should be used to report lexing errors. + +The `getTokens()` method returns the current token array, in the usual `token_get_all()` format. This method is not +used by the parser (which uses `getNextToken()`), but is useful in combination with the token position attributes. + +The `handleHaltCompiler()` method is called whenever a `T_HALT_COMPILER` token is encountered. It has to return the +remaining string after the construct (not including `();`). + +The `getNextToken()` method returns the ID of the next token (as defined by the `Parser::T_*` constants). If no more +tokens are available it must return `0`, which is the ID of the `EOF` token. Furthermore the string content of the +token should be written into the by-reference `$value` parameter (which will then be available as `$n` in the parser). + +### Attribute handling + +The other two by-ref variables `$startAttributes` and `$endAttributes` define which attributes will eventually be +assigned to the generated nodes: The parser will take the `$startAttributes` from the first token which is part of the +node and the `$endAttributes` from the last token that is part of the node. + +E.g. if the tokens `T_FUNCTION T_STRING ... '{' ... '}'` constitute a node, then the `$startAttributes` from the +`T_FUNCTION` token will be taken and the `$endAttributes` from the `'}'` token. + +An application of custom attributes is storing the exact original formatting of literals: While the parser does retain +some information about the formatting of integers (like decimal vs. hexadecimal) or strings (like used quote type), it +does not preserve the exact original formatting (e.g. leading zeros for integers or escape sequences in strings). This +can be remedied by storing the original value in an attribute: + +```php +use PhpParser\Lexer; +use PhpParser\Parser\Tokens; + +class KeepOriginalValueLexer extends Lexer // or Lexer\Emulative +{ + public function getNextToken(&$value = null, &$startAttributes = null, &$endAttributes = null) { + $tokenId = parent::getNextToken($value, $startAttributes, $endAttributes); + + if ($tokenId == Tokens::T_CONSTANT_ENCAPSED_STRING // non-interpolated string + || $tokenId == Tokens::T_ENCAPSED_AND_WHITESPACE // interpolated string + || $tokenId == Tokens::T_LNUMBER // integer + || $tokenId == Tokens::T_DNUMBER // floating point number + ) { + // could also use $startAttributes, doesn't really matter here + $endAttributes['originalValue'] = $value; + } + + return $tokenId; + } +} +``` diff --git a/lib/nikic/php-parser/grammar/README.md b/lib/nikic/php-parser/grammar/README.md new file mode 100644 index 000000000..3f1698a68 --- /dev/null +++ b/lib/nikic/php-parser/grammar/README.md @@ -0,0 +1,28 @@ +What do all those files mean? +============================= + + * `php5.y`: PHP 5 grammar written in a pseudo language + * `php7.y`: PHP 7 grammar written in a pseudo language + * `tokens.y`: Tokens definition shared between PHP 5 and PHP 7 grammars + * `parser.template`: A `kmyacc` parser prototype file for PHP + * `tokens.template`: A `kmyacc` prototype file for the `Tokens` class + * `rebuildParsers.php`: Preprocesses the grammar and builds the parser using `kmyacc` + +.phpy pseudo language +===================== + +The `.y` file is a normal grammer in `kmyacc` (`yacc`) style, with some transformations +applied to it: + + * Nodes are created using the syntax `Name[..., ...]`. This is transformed into + `new Name(..., ..., attributes())` + * Some function-like constructs are resolved (see `rebuildParsers.php` for a list) + +Building the parser +=================== + +In order to rebuild the parser, you need [moriyoshi's fork of kmyacc](https://github.com/moriyoshi/kmyacc-forked). +After you compiled/installed it, run the `rebuildParsers.php` script. + +By default only the `Parser.php` is built. If you want to additionally emit debug symbols and create `y.output`, run the +script with `--debug`. If you want to retain the preprocessed grammar pass `--keep-tmp-grammar`. diff --git a/lib/nikic/php-parser/grammar/parser.template b/lib/nikic/php-parser/grammar/parser.template new file mode 100644 index 000000000..fff893ff4 --- /dev/null +++ b/lib/nikic/php-parser/grammar/parser.template @@ -0,0 +1,103 @@ +semValue +#semval($,%t) $this->semValue +#semval(%n) $this->stackPos-(%l-%n) +#semval(%n,%t) $this->stackPos-(%l-%n) + +namespace PhpParser\Parser; + +use PhpParser\Error; +use PhpParser\Node; +use PhpParser\Node\Expr; +use PhpParser\Node\Name; +use PhpParser\Node\Scalar; +use PhpParser\Node\Stmt; +#include; + +/* This is an automatically GENERATED file, which should not be manually edited. + * Instead edit one of the following: + * * the grammar files grammar/php5.y or grammar/php7.y + * * the skeleton file grammar/parser.template + * * the preprocessing script grammar/rebuildParsers.php + */ +class #(-p) extends \PhpParser\ParserAbstract +{ + protected $tokenToSymbolMapSize = #(YYMAXLEX); + protected $actionTableSize = #(YYLAST); + protected $gotoTableSize = #(YYGLAST); + + protected $invalidSymbol = #(YYBADCH); + protected $errorSymbol = #(YYINTERRTOK); + protected $defaultAction = #(YYDEFAULT); + protected $unexpectedTokenRule = #(YYUNEXPECTED); + + protected $YY2TBLSTATE = #(YY2TBLSTATE); + protected $YYNLSTATES = #(YYNLSTATES); + + protected $symbolToName = array( + #listvar terminals + ); + + protected $tokenToSymbol = array( + #listvar yytranslate + ); + + protected $action = array( + #listvar yyaction + ); + + protected $actionCheck = array( + #listvar yycheck + ); + + protected $actionBase = array( + #listvar yybase + ); + + protected $actionDefault = array( + #listvar yydefault + ); + + protected $goto = array( + #listvar yygoto + ); + + protected $gotoCheck = array( + #listvar yygcheck + ); + + protected $gotoBase = array( + #listvar yygbase + ); + + protected $gotoDefault = array( + #listvar yygdefault + ); + + protected $ruleToNonTerminal = array( + #listvar yylhs + ); + + protected $ruleToLength = array( + #listvar yylen + ); +#if -t + + protected $productions = array( + #production-strings; + ); +#endif +#reduce + + protected function reduceRule%n() { + %b + } +#noact + + protected function reduceRule%n() { + $this->semValue = $this->semStack[$this->stackPos]; + } +#endreduce +} +#tailcode; diff --git a/lib/nikic/php-parser/grammar/php5.y b/lib/nikic/php-parser/grammar/php5.y new file mode 100644 index 000000000..79384381f --- /dev/null +++ b/lib/nikic/php-parser/grammar/php5.y @@ -0,0 +1,1009 @@ +%pure_parser +%expect 6 + +%tokens + +%% + +start: + top_statement_list { $$ = $this->handleNamespaces($1); } +; + +top_statement_list_ex: + top_statement_list_ex top_statement { pushNormalizing($1, $2); } + | /* empty */ { init(); } +; + +top_statement_list: + top_statement_list_ex + { makeNop($nop, $this->lookaheadStartAttributes); + if ($nop !== null) { $1[] = $nop; } $$ = $1; } +; + +reserved_non_modifiers: + T_INCLUDE | T_INCLUDE_ONCE | T_EVAL | T_REQUIRE | T_REQUIRE_ONCE | T_LOGICAL_OR | T_LOGICAL_XOR | T_LOGICAL_AND + | T_INSTANCEOF | T_NEW | T_CLONE | T_EXIT | T_IF | T_ELSEIF | T_ELSE | T_ENDIF | T_ECHO | T_DO | T_WHILE + | T_ENDWHILE | T_FOR | T_ENDFOR | T_FOREACH | T_ENDFOREACH | T_DECLARE | T_ENDDECLARE | T_AS | T_TRY | T_CATCH + | T_FINALLY | T_THROW | T_USE | T_INSTEADOF | T_GLOBAL | T_VAR | T_UNSET | T_ISSET | T_EMPTY | T_CONTINUE | T_GOTO + | T_FUNCTION | T_CONST | T_RETURN | T_PRINT | T_YIELD | T_LIST | T_SWITCH | T_ENDSWITCH | T_CASE | T_DEFAULT + | T_BREAK | T_ARRAY | T_CALLABLE | T_EXTENDS | T_IMPLEMENTS | T_NAMESPACE | T_TRAIT | T_INTERFACE | T_CLASS + | T_CLASS_C | T_TRAIT_C | T_FUNC_C | T_METHOD_C | T_LINE | T_FILE | T_DIR | T_NS_C | T_HALT_COMPILER +; + +semi_reserved: + reserved_non_modifiers + | T_STATIC | T_ABSTRACT | T_FINAL | T_PRIVATE | T_PROTECTED | T_PUBLIC +; + +identifier: + T_STRING { $$ = $1; } + | semi_reserved { $$ = $1; } +; + +namespace_name_parts: + T_STRING { init($1); } + | namespace_name_parts T_NS_SEPARATOR T_STRING { push($1, $3); } +; + +namespace_name: + namespace_name_parts { $$ = Name[$1]; } +; + +top_statement: + statement { $$ = $1; } + | function_declaration_statement { $$ = $1; } + | class_declaration_statement { $$ = $1; } + | T_HALT_COMPILER + { $$ = Stmt\HaltCompiler[$this->lexer->handleHaltCompiler()]; } + | T_NAMESPACE namespace_name ';' + { $$ = Stmt\Namespace_[$2, null]; + $$->setAttribute('kind', Stmt\Namespace_::KIND_SEMICOLON); + $this->checkNamespace($$); } + | T_NAMESPACE namespace_name '{' top_statement_list '}' + { $$ = Stmt\Namespace_[$2, $4]; + $$->setAttribute('kind', Stmt\Namespace_::KIND_BRACED); + $this->checkNamespace($$); } + | T_NAMESPACE '{' top_statement_list '}' + { $$ = Stmt\Namespace_[null, $3]; + $$->setAttribute('kind', Stmt\Namespace_::KIND_BRACED); + $this->checkNamespace($$); } + | T_USE use_declarations ';' { $$ = Stmt\Use_[$2, Stmt\Use_::TYPE_NORMAL]; } + | T_USE use_type use_declarations ';' { $$ = Stmt\Use_[$3, $2]; } + | group_use_declaration ';' { $$ = $1; } + | T_CONST constant_declaration_list ';' { $$ = Stmt\Const_[$2]; } +; + +use_type: + T_FUNCTION { $$ = Stmt\Use_::TYPE_FUNCTION; } + | T_CONST { $$ = Stmt\Use_::TYPE_CONSTANT; } +; + +/* Using namespace_name_parts here to avoid s/r conflict on T_NS_SEPARATOR */ +group_use_declaration: + T_USE use_type namespace_name_parts T_NS_SEPARATOR '{' unprefixed_use_declarations '}' + { $$ = Stmt\GroupUse[new Name($3, stackAttributes(#3)), $6, $2]; } + | T_USE use_type T_NS_SEPARATOR namespace_name_parts T_NS_SEPARATOR '{' unprefixed_use_declarations '}' + { $$ = Stmt\GroupUse[new Name($4, stackAttributes(#4)), $7, $2]; } + | T_USE namespace_name_parts T_NS_SEPARATOR '{' inline_use_declarations '}' + { $$ = Stmt\GroupUse[new Name($2, stackAttributes(#2)), $5, Stmt\Use_::TYPE_UNKNOWN]; } + | T_USE T_NS_SEPARATOR namespace_name_parts T_NS_SEPARATOR '{' inline_use_declarations '}' + { $$ = Stmt\GroupUse[new Name($3, stackAttributes(#3)), $6, Stmt\Use_::TYPE_UNKNOWN]; } +; + +unprefixed_use_declarations: + unprefixed_use_declarations ',' unprefixed_use_declaration + { push($1, $3); } + | unprefixed_use_declaration { init($1); } +; + +use_declarations: + use_declarations ',' use_declaration { push($1, $3); } + | use_declaration { init($1); } +; + +inline_use_declarations: + inline_use_declarations ',' inline_use_declaration { push($1, $3); } + | inline_use_declaration { init($1); } +; + +unprefixed_use_declaration: + namespace_name + { $$ = Stmt\UseUse[$1, null, Stmt\Use_::TYPE_UNKNOWN]; $this->checkUseUse($$, #1); } + | namespace_name T_AS T_STRING + { $$ = Stmt\UseUse[$1, $3, Stmt\Use_::TYPE_UNKNOWN]; $this->checkUseUse($$, #3); } +; + +use_declaration: + unprefixed_use_declaration { $$ = $1; } + | T_NS_SEPARATOR unprefixed_use_declaration { $$ = $2; } +; + +inline_use_declaration: + unprefixed_use_declaration { $$ = $1; $$->type = Stmt\Use_::TYPE_NORMAL; } + | use_type unprefixed_use_declaration { $$ = $2; $$->type = $1; } +; + +constant_declaration_list: + constant_declaration_list ',' constant_declaration { push($1, $3); } + | constant_declaration { init($1); } +; + +constant_declaration: + T_STRING '=' static_scalar { $$ = Node\Const_[$1, $3]; } +; + +class_const_list: + class_const_list ',' class_const { push($1, $3); } + | class_const { init($1); } +; + +class_const: + identifier '=' static_scalar { $$ = Node\Const_[$1, $3]; } +; + +inner_statement_list_ex: + inner_statement_list_ex inner_statement { pushNormalizing($1, $2); } + | /* empty */ { init(); } +; + +inner_statement_list: + inner_statement_list_ex + { makeNop($nop, $this->lookaheadStartAttributes); + if ($nop !== null) { $1[] = $nop; } $$ = $1; } +; + +inner_statement: + statement { $$ = $1; } + | function_declaration_statement { $$ = $1; } + | class_declaration_statement { $$ = $1; } + | T_HALT_COMPILER + { throw new Error('__HALT_COMPILER() can only be used from the outermost scope', attributes()); } +; + +non_empty_statement: + '{' inner_statement_list '}' + { + if ($2) { + $$ = $2; prependLeadingComments($$); + } else { + makeNop($$, $this->startAttributeStack[#1]); + if (null === $$) { $$ = array(); } + } + } + | T_IF parentheses_expr statement elseif_list else_single + { $$ = Stmt\If_[$2, ['stmts' => toArray($3), 'elseifs' => $4, 'else' => $5]]; } + | T_IF parentheses_expr ':' inner_statement_list new_elseif_list new_else_single T_ENDIF ';' + { $$ = Stmt\If_[$2, ['stmts' => $4, 'elseifs' => $5, 'else' => $6]]; } + | T_WHILE parentheses_expr while_statement { $$ = Stmt\While_[$2, $3]; } + | T_DO statement T_WHILE parentheses_expr ';' { $$ = Stmt\Do_ [$4, toArray($2)]; } + | T_FOR '(' for_expr ';' for_expr ';' for_expr ')' for_statement + { $$ = Stmt\For_[['init' => $3, 'cond' => $5, 'loop' => $7, 'stmts' => $9]]; } + | T_SWITCH parentheses_expr switch_case_list { $$ = Stmt\Switch_[$2, $3]; } + | T_BREAK ';' { $$ = Stmt\Break_[null]; } + | T_BREAK expr ';' { $$ = Stmt\Break_[$2]; } + | T_CONTINUE ';' { $$ = Stmt\Continue_[null]; } + | T_CONTINUE expr ';' { $$ = Stmt\Continue_[$2]; } + | T_RETURN ';' { $$ = Stmt\Return_[null]; } + | T_RETURN expr ';' { $$ = Stmt\Return_[$2]; } + | yield_expr ';' { $$ = $1; } + | T_GLOBAL global_var_list ';' { $$ = Stmt\Global_[$2]; } + | T_STATIC static_var_list ';' { $$ = Stmt\Static_[$2]; } + | T_ECHO expr_list ';' { $$ = Stmt\Echo_[$2]; } + | T_INLINE_HTML { $$ = Stmt\InlineHTML[$1]; } + | expr ';' { $$ = $1; } + | T_UNSET '(' variables_list ')' ';' { $$ = Stmt\Unset_[$3]; } + | T_FOREACH '(' expr T_AS foreach_variable ')' foreach_statement + { $$ = Stmt\Foreach_[$3, $5[0], ['keyVar' => null, 'byRef' => $5[1], 'stmts' => $7]]; } + | T_FOREACH '(' expr T_AS variable T_DOUBLE_ARROW foreach_variable ')' foreach_statement + { $$ = Stmt\Foreach_[$3, $7[0], ['keyVar' => $5, 'byRef' => $7[1], 'stmts' => $9]]; } + | T_DECLARE '(' declare_list ')' declare_statement { $$ = Stmt\Declare_[$3, $5]; } + | T_TRY '{' inner_statement_list '}' catches optional_finally + { $$ = Stmt\TryCatch[$3, $5, $6]; $this->checkTryCatch($$); } + | T_THROW expr ';' { $$ = Stmt\Throw_[$2]; } + | T_GOTO T_STRING ';' { $$ = Stmt\Goto_[$2]; } + | T_STRING ':' { $$ = Stmt\Label[$1]; } + | expr error { $$ = $1; } + | error { $$ = array(); /* means: no statement */ } +; + +statement: + non_empty_statement { $$ = $1; } + | ';' + { makeNop($$, $this->startAttributeStack[#1]); + if ($$ === null) $$ = array(); /* means: no statement */ } +; + +catches: + /* empty */ { init(); } + | catches catch { push($1, $2); } +; + +catch: + T_CATCH '(' name T_VARIABLE ')' '{' inner_statement_list '}' + { $$ = Stmt\Catch_[array($3), parseVar($4), $7]; } +; + +optional_finally: + /* empty */ { $$ = null; } + | T_FINALLY '{' inner_statement_list '}' { $$ = Stmt\Finally_[$3]; } +; + +variables_list: + variable { init($1); } + | variables_list ',' variable { push($1, $3); } +; + +optional_ref: + /* empty */ { $$ = false; } + | '&' { $$ = true; } +; + +optional_ellipsis: + /* empty */ { $$ = false; } + | T_ELLIPSIS { $$ = true; } +; + +function_declaration_statement: + T_FUNCTION optional_ref T_STRING '(' parameter_list ')' optional_return_type '{' inner_statement_list '}' + { $$ = Stmt\Function_[$3, ['byRef' => $2, 'params' => $5, 'returnType' => $7, 'stmts' => $9]]; } +; + +class_declaration_statement: + class_entry_type T_STRING extends_from implements_list '{' class_statement_list '}' + { $$ = Stmt\Class_[$2, ['type' => $1, 'extends' => $3, 'implements' => $4, 'stmts' => $6]]; + $this->checkClass($$, #2); } + | T_INTERFACE T_STRING interface_extends_list '{' class_statement_list '}' + { $$ = Stmt\Interface_[$2, ['extends' => $3, 'stmts' => $5]]; + $this->checkInterface($$, #2); } + | T_TRAIT T_STRING '{' class_statement_list '}' + { $$ = Stmt\Trait_[$2, ['stmts' => $4]]; } +; + +class_entry_type: + T_CLASS { $$ = 0; } + | T_ABSTRACT T_CLASS { $$ = Stmt\Class_::MODIFIER_ABSTRACT; } + | T_FINAL T_CLASS { $$ = Stmt\Class_::MODIFIER_FINAL; } +; + +extends_from: + /* empty */ { $$ = null; } + | T_EXTENDS class_name { $$ = $2; } +; + +interface_extends_list: + /* empty */ { $$ = array(); } + | T_EXTENDS class_name_list { $$ = $2; } +; + +implements_list: + /* empty */ { $$ = array(); } + | T_IMPLEMENTS class_name_list { $$ = $2; } +; + +class_name_list: + class_name { init($1); } + | class_name_list ',' class_name { push($1, $3); } +; + +for_statement: + statement { $$ = toArray($1); } + | ':' inner_statement_list T_ENDFOR ';' { $$ = $2; } +; + +foreach_statement: + statement { $$ = toArray($1); } + | ':' inner_statement_list T_ENDFOREACH ';' { $$ = $2; } +; + +declare_statement: + non_empty_statement { $$ = toArray($1); } + | ';' { $$ = null; } + | ':' inner_statement_list T_ENDDECLARE ';' { $$ = $2; } +; + +declare_list: + declare_list_element { init($1); } + | declare_list ',' declare_list_element { push($1, $3); } +; + +declare_list_element: + T_STRING '=' static_scalar { $$ = Stmt\DeclareDeclare[$1, $3]; } +; + +switch_case_list: + '{' case_list '}' { $$ = $2; } + | '{' ';' case_list '}' { $$ = $3; } + | ':' case_list T_ENDSWITCH ';' { $$ = $2; } + | ':' ';' case_list T_ENDSWITCH ';' { $$ = $3; } +; + +case_list: + /* empty */ { init(); } + | case_list case { push($1, $2); } +; + +case: + T_CASE expr case_separator inner_statement_list_ex { $$ = Stmt\Case_[$2, $4]; } + | T_DEFAULT case_separator inner_statement_list_ex { $$ = Stmt\Case_[null, $3]; } +; + +case_separator: + ':' + | ';' +; + +while_statement: + statement { $$ = toArray($1); } + | ':' inner_statement_list T_ENDWHILE ';' { $$ = $2; } +; + +elseif_list: + /* empty */ { init(); } + | elseif_list elseif { push($1, $2); } +; + +elseif: + T_ELSEIF parentheses_expr statement { $$ = Stmt\ElseIf_[$2, toArray($3)]; } +; + +new_elseif_list: + /* empty */ { init(); } + | new_elseif_list new_elseif { push($1, $2); } +; + +new_elseif: + T_ELSEIF parentheses_expr ':' inner_statement_list { $$ = Stmt\ElseIf_[$2, $4]; } +; + +else_single: + /* empty */ { $$ = null; } + | T_ELSE statement { $$ = Stmt\Else_[toArray($2)]; } +; + +new_else_single: + /* empty */ { $$ = null; } + | T_ELSE ':' inner_statement_list { $$ = Stmt\Else_[$3]; } +; + +foreach_variable: + variable { $$ = array($1, false); } + | '&' variable { $$ = array($2, true); } + | list_expr { $$ = array($1, false); } +; + +parameter_list: + non_empty_parameter_list { $$ = $1; } + | /* empty */ { $$ = array(); } +; + +non_empty_parameter_list: + parameter { init($1); } + | non_empty_parameter_list ',' parameter { push($1, $3); } +; + +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($$); } +; + +type: + name { $$ = $1; } + | T_ARRAY { $$ = 'array'; } + | T_CALLABLE { $$ = 'callable'; } +; + +optional_param_type: + /* empty */ { $$ = null; } + | type { $$ = $1; } +; + +optional_return_type: + /* empty */ { $$ = null; } + | ':' type { $$ = $2; } +; + +argument_list: + '(' ')' { $$ = array(); } + | '(' non_empty_argument_list ')' { $$ = $2; } + | '(' yield_expr ')' { $$ = array(Node\Arg[$2, false, false]); } +; + +non_empty_argument_list: + argument { init($1); } + | non_empty_argument_list ',' argument { push($1, $3); } +; + +argument: + expr { $$ = Node\Arg[$1, false, false]; } + | '&' variable { $$ = Node\Arg[$2, true, false]; } + | T_ELLIPSIS expr { $$ = Node\Arg[$2, false, true]; } +; + +global_var_list: + global_var_list ',' global_var { push($1, $3); } + | global_var { init($1); } +; + +global_var: + T_VARIABLE { $$ = Expr\Variable[parseVar($1)]; } + | '$' variable { $$ = Expr\Variable[$2]; } + | '$' '{' expr '}' { $$ = Expr\Variable[$3]; } +; + +static_var_list: + static_var_list ',' static_var { push($1, $3); } + | static_var { init($1); } +; + +static_var: + T_VARIABLE { $$ = Stmt\StaticVar[parseVar($1), null]; } + | T_VARIABLE '=' static_scalar { $$ = Stmt\StaticVar[parseVar($1), $3]; } +; + +class_statement_list: + class_statement_list class_statement { push($1, $2); } + | /* empty */ { init(); } +; + +class_statement: + variable_modifiers property_declaration_list ';' + { $$ = Stmt\Property[$1, $2]; $this->checkProperty($$, #1); } + | T_CONST class_const_list ';' { $$ = Stmt\ClassConst[$2, 0]; } + | method_modifiers T_FUNCTION optional_ref identifier '(' parameter_list ')' optional_return_type method_body + { $$ = Stmt\ClassMethod[$4, ['type' => $1, 'byRef' => $3, 'params' => $6, 'returnType' => $8, 'stmts' => $9]]; + $this->checkClassMethod($$, #1); } + | T_USE class_name_list trait_adaptations { $$ = Stmt\TraitUse[$2, $3]; } +; + +trait_adaptations: + ';' { $$ = array(); } + | '{' trait_adaptation_list '}' { $$ = $2; } +; + +trait_adaptation_list: + /* empty */ { init(); } + | trait_adaptation_list trait_adaptation { push($1, $2); } +; + +trait_adaptation: + trait_method_reference_fully_qualified T_INSTEADOF class_name_list ';' + { $$ = Stmt\TraitUseAdaptation\Precedence[$1[0], $1[1], $3]; } + | trait_method_reference T_AS member_modifier identifier ';' + { $$ = Stmt\TraitUseAdaptation\Alias[$1[0], $1[1], $3, $4]; } + | trait_method_reference T_AS member_modifier ';' + { $$ = Stmt\TraitUseAdaptation\Alias[$1[0], $1[1], $3, null]; } + | trait_method_reference T_AS T_STRING ';' + { $$ = Stmt\TraitUseAdaptation\Alias[$1[0], $1[1], null, $3]; } + | trait_method_reference T_AS reserved_non_modifiers ';' + { $$ = Stmt\TraitUseAdaptation\Alias[$1[0], $1[1], null, $3]; } +; + +trait_method_reference_fully_qualified: + name T_PAAMAYIM_NEKUDOTAYIM identifier { $$ = array($1, $3); } +; +trait_method_reference: + trait_method_reference_fully_qualified { $$ = $1; } + | identifier { $$ = array(null, $1); } +; + +method_body: + ';' /* abstract method */ { $$ = null; } + | '{' inner_statement_list '}' { $$ = $2; } +; + +variable_modifiers: + non_empty_member_modifiers { $$ = $1; } + | T_VAR { $$ = 0; } +; + +method_modifiers: + /* empty */ { $$ = 0; } + | non_empty_member_modifiers { $$ = $1; } +; + +non_empty_member_modifiers: + member_modifier { $$ = $1; } + | non_empty_member_modifiers member_modifier { $this->checkModifier($1, $2, #2); $$ = $1 | $2; } +; + +member_modifier: + T_PUBLIC { $$ = Stmt\Class_::MODIFIER_PUBLIC; } + | T_PROTECTED { $$ = Stmt\Class_::MODIFIER_PROTECTED; } + | T_PRIVATE { $$ = Stmt\Class_::MODIFIER_PRIVATE; } + | T_STATIC { $$ = Stmt\Class_::MODIFIER_STATIC; } + | T_ABSTRACT { $$ = Stmt\Class_::MODIFIER_ABSTRACT; } + | T_FINAL { $$ = Stmt\Class_::MODIFIER_FINAL; } +; + +property_declaration_list: + property_declaration { init($1); } + | property_declaration_list ',' property_declaration { push($1, $3); } +; + +property_declaration: + T_VARIABLE { $$ = Stmt\PropertyProperty[parseVar($1), null]; } + | T_VARIABLE '=' static_scalar { $$ = Stmt\PropertyProperty[parseVar($1), $3]; } +; + +expr_list: + expr_list ',' expr { push($1, $3); } + | expr { init($1); } +; + +for_expr: + /* empty */ { $$ = array(); } + | expr_list { $$ = $1; } +; + +expr: + variable { $$ = $1; } + | list_expr '=' expr { $$ = Expr\Assign[$1, $3]; } + | variable '=' expr { $$ = Expr\Assign[$1, $3]; } + | variable '=' '&' variable { $$ = Expr\AssignRef[$1, $4]; } + | variable '=' '&' new_expr { $$ = Expr\AssignRef[$1, $4]; } + | new_expr { $$ = $1; } + | T_CLONE expr { $$ = Expr\Clone_[$2]; } + | variable T_PLUS_EQUAL expr { $$ = Expr\AssignOp\Plus [$1, $3]; } + | variable T_MINUS_EQUAL expr { $$ = Expr\AssignOp\Minus [$1, $3]; } + | variable T_MUL_EQUAL expr { $$ = Expr\AssignOp\Mul [$1, $3]; } + | variable T_DIV_EQUAL expr { $$ = Expr\AssignOp\Div [$1, $3]; } + | variable T_CONCAT_EQUAL expr { $$ = Expr\AssignOp\Concat [$1, $3]; } + | variable T_MOD_EQUAL expr { $$ = Expr\AssignOp\Mod [$1, $3]; } + | variable T_AND_EQUAL expr { $$ = Expr\AssignOp\BitwiseAnd[$1, $3]; } + | variable T_OR_EQUAL expr { $$ = Expr\AssignOp\BitwiseOr [$1, $3]; } + | variable T_XOR_EQUAL expr { $$ = Expr\AssignOp\BitwiseXor[$1, $3]; } + | variable T_SL_EQUAL expr { $$ = Expr\AssignOp\ShiftLeft [$1, $3]; } + | variable T_SR_EQUAL expr { $$ = Expr\AssignOp\ShiftRight[$1, $3]; } + | variable T_POW_EQUAL expr { $$ = Expr\AssignOp\Pow [$1, $3]; } + | variable T_INC { $$ = Expr\PostInc[$1]; } + | T_INC variable { $$ = Expr\PreInc [$2]; } + | variable T_DEC { $$ = Expr\PostDec[$1]; } + | T_DEC variable { $$ = Expr\PreDec [$2]; } + | expr T_BOOLEAN_OR expr { $$ = Expr\BinaryOp\BooleanOr [$1, $3]; } + | expr T_BOOLEAN_AND expr { $$ = Expr\BinaryOp\BooleanAnd[$1, $3]; } + | expr T_LOGICAL_OR expr { $$ = Expr\BinaryOp\LogicalOr [$1, $3]; } + | expr T_LOGICAL_AND expr { $$ = Expr\BinaryOp\LogicalAnd[$1, $3]; } + | expr T_LOGICAL_XOR expr { $$ = Expr\BinaryOp\LogicalXor[$1, $3]; } + | expr '|' expr { $$ = Expr\BinaryOp\BitwiseOr [$1, $3]; } + | expr '&' expr { $$ = Expr\BinaryOp\BitwiseAnd[$1, $3]; } + | expr '^' expr { $$ = Expr\BinaryOp\BitwiseXor[$1, $3]; } + | expr '.' expr { $$ = Expr\BinaryOp\Concat [$1, $3]; } + | expr '+' expr { $$ = Expr\BinaryOp\Plus [$1, $3]; } + | expr '-' expr { $$ = Expr\BinaryOp\Minus [$1, $3]; } + | expr '*' expr { $$ = Expr\BinaryOp\Mul [$1, $3]; } + | expr '/' expr { $$ = Expr\BinaryOp\Div [$1, $3]; } + | expr '%' expr { $$ = Expr\BinaryOp\Mod [$1, $3]; } + | expr T_SL expr { $$ = Expr\BinaryOp\ShiftLeft [$1, $3]; } + | expr T_SR expr { $$ = Expr\BinaryOp\ShiftRight[$1, $3]; } + | expr T_POW expr { $$ = Expr\BinaryOp\Pow [$1, $3]; } + | '+' expr %prec T_INC { $$ = Expr\UnaryPlus [$2]; } + | '-' expr %prec T_INC { $$ = Expr\UnaryMinus[$2]; } + | '!' expr { $$ = Expr\BooleanNot[$2]; } + | '~' expr { $$ = Expr\BitwiseNot[$2]; } + | expr T_IS_IDENTICAL expr { $$ = Expr\BinaryOp\Identical [$1, $3]; } + | expr T_IS_NOT_IDENTICAL expr { $$ = Expr\BinaryOp\NotIdentical [$1, $3]; } + | expr T_IS_EQUAL expr { $$ = Expr\BinaryOp\Equal [$1, $3]; } + | expr T_IS_NOT_EQUAL expr { $$ = Expr\BinaryOp\NotEqual [$1, $3]; } + | expr T_SPACESHIP expr { $$ = Expr\BinaryOp\Spaceship [$1, $3]; } + | expr '<' expr { $$ = Expr\BinaryOp\Smaller [$1, $3]; } + | expr T_IS_SMALLER_OR_EQUAL expr { $$ = Expr\BinaryOp\SmallerOrEqual[$1, $3]; } + | expr '>' expr { $$ = Expr\BinaryOp\Greater [$1, $3]; } + | expr T_IS_GREATER_OR_EQUAL expr { $$ = Expr\BinaryOp\GreaterOrEqual[$1, $3]; } + | expr T_INSTANCEOF class_name_reference { $$ = Expr\Instanceof_[$1, $3]; } + | parentheses_expr { $$ = $1; } + /* we need a separate '(' new_expr ')' rule to avoid problems caused by a s/r conflict */ + | '(' new_expr ')' { $$ = $2; } + | expr '?' expr ':' expr { $$ = Expr\Ternary[$1, $3, $5]; } + | expr '?' ':' expr { $$ = Expr\Ternary[$1, null, $4]; } + | expr T_COALESCE expr { $$ = Expr\BinaryOp\Coalesce[$1, $3]; } + | T_ISSET '(' variables_list ')' { $$ = Expr\Isset_[$3]; } + | T_EMPTY '(' expr ')' { $$ = Expr\Empty_[$3]; } + | T_INCLUDE expr { $$ = Expr\Include_[$2, Expr\Include_::TYPE_INCLUDE]; } + | T_INCLUDE_ONCE expr { $$ = Expr\Include_[$2, Expr\Include_::TYPE_INCLUDE_ONCE]; } + | T_EVAL parentheses_expr { $$ = Expr\Eval_[$2]; } + | T_REQUIRE expr { $$ = Expr\Include_[$2, Expr\Include_::TYPE_REQUIRE]; } + | T_REQUIRE_ONCE expr { $$ = Expr\Include_[$2, Expr\Include_::TYPE_REQUIRE_ONCE]; } + | T_INT_CAST expr { $$ = Expr\Cast\Int_ [$2]; } + | T_DOUBLE_CAST expr { $$ = Expr\Cast\Double [$2]; } + | T_STRING_CAST expr { $$ = Expr\Cast\String_ [$2]; } + | T_ARRAY_CAST expr { $$ = Expr\Cast\Array_ [$2]; } + | T_OBJECT_CAST expr { $$ = Expr\Cast\Object_ [$2]; } + | T_BOOL_CAST expr { $$ = Expr\Cast\Bool_ [$2]; } + | T_UNSET_CAST expr { $$ = Expr\Cast\Unset_ [$2]; } + | T_EXIT exit_expr + { $attrs = attributes(); + $attrs['kind'] = strtolower($1) === 'exit' ? Expr\Exit_::KIND_EXIT : Expr\Exit_::KIND_DIE; + $$ = new Expr\Exit_($2, $attrs); } + | '@' expr { $$ = Expr\ErrorSuppress[$2]; } + | scalar { $$ = $1; } + | array_expr { $$ = $1; } + | scalar_dereference { $$ = $1; } + | '`' backticks_expr '`' { $$ = Expr\ShellExec[$2]; } + | T_PRINT expr { $$ = Expr\Print_[$2]; } + | T_YIELD { $$ = Expr\Yield_[null, null]; } + | T_YIELD_FROM expr { $$ = Expr\YieldFrom[$2]; } + | T_FUNCTION optional_ref '(' parameter_list ')' lexical_vars optional_return_type + '{' inner_statement_list '}' + { $$ = Expr\Closure[['static' => false, 'byRef' => $2, 'params' => $4, 'uses' => $6, 'returnType' => $7, 'stmts' => $9]]; } + | T_STATIC T_FUNCTION optional_ref '(' parameter_list ')' lexical_vars optional_return_type + '{' inner_statement_list '}' + { $$ = Expr\Closure[['static' => true, 'byRef' => $3, 'params' => $5, 'uses' => $7, 'returnType' => $8, 'stmts' => $10]]; } +; + +parentheses_expr: + '(' expr ')' { $$ = $2; } + | '(' yield_expr ')' { $$ = $2; } +; + +yield_expr: + T_YIELD expr { $$ = Expr\Yield_[$2, null]; } + | T_YIELD expr T_DOUBLE_ARROW expr { $$ = Expr\Yield_[$4, $2]; } +; + +array_expr: + T_ARRAY '(' array_pair_list ')' + { $attrs = attributes(); $attrs['kind'] = Expr\Array_::KIND_LONG; + $$ = new Expr\Array_($3, $attrs); } + | '[' array_pair_list ']' + { $attrs = attributes(); $attrs['kind'] = Expr\Array_::KIND_SHORT; + $$ = new Expr\Array_($2, $attrs); } +; + +scalar_dereference: + array_expr '[' dim_offset ']' { $$ = Expr\ArrayDimFetch[$1, $3]; } + | T_CONSTANT_ENCAPSED_STRING '[' dim_offset ']' + { $attrs = attributes(); $attrs['kind'] = strKind($1); + $$ = Expr\ArrayDimFetch[new Scalar\String_(Scalar\String_::parse($1), $attrs), $3]; } + | constant '[' dim_offset ']' { $$ = Expr\ArrayDimFetch[$1, $3]; } + | scalar_dereference '[' dim_offset ']' { $$ = Expr\ArrayDimFetch[$1, $3]; } + /* alternative array syntax missing intentionally */ +; + +anonymous_class: + T_CLASS ctor_arguments extends_from implements_list '{' class_statement_list '}' + { $$ = array(Stmt\Class_[null, ['type' => 0, 'extends' => $3, 'implements' => $4, 'stmts' => $6]], $2); + $this->checkClass($$[0], -1); } + +new_expr: + T_NEW class_name_reference ctor_arguments { $$ = Expr\New_[$2, $3]; } + | T_NEW anonymous_class + { list($class, $ctorArgs) = $2; $$ = Expr\New_[$class, $ctorArgs]; } +; + +lexical_vars: + /* empty */ { $$ = array(); } + | T_USE '(' lexical_var_list ')' { $$ = $3; } +; + +lexical_var_list: + lexical_var { init($1); } + | lexical_var_list ',' lexical_var { push($1, $3); } +; + +lexical_var: + optional_ref T_VARIABLE { $$ = Expr\ClosureUse[parseVar($2), $1]; } +; + +function_call: + name argument_list { $$ = Expr\FuncCall[$1, $2]; } + | class_name_or_var T_PAAMAYIM_NEKUDOTAYIM identifier argument_list + { $$ = Expr\StaticCall[$1, $3, $4]; } + | class_name_or_var T_PAAMAYIM_NEKUDOTAYIM '{' expr '}' argument_list + { $$ = Expr\StaticCall[$1, $4, $6]; } + | static_property argument_list { + if ($1 instanceof Node\Expr\StaticPropertyFetch) { + $$ = Expr\StaticCall[$1->class, Expr\Variable[$1->name], $2]; + } elseif ($1 instanceof Node\Expr\ArrayDimFetch) { + $tmp = $1; + while ($tmp->var instanceof Node\Expr\ArrayDimFetch) { + $tmp = $tmp->var; + } + + $$ = Expr\StaticCall[$tmp->var->class, $1, $2]; + $tmp->var = Expr\Variable[$tmp->var->name]; + } else { + throw new \Exception; + } + } + | variable_without_objects argument_list + { $$ = Expr\FuncCall[$1, $2]; } + | function_call '[' dim_offset ']' { $$ = Expr\ArrayDimFetch[$1, $3]; } + /* alternative array syntax missing intentionally */ +; + +class_name: + T_STATIC { $$ = Name[$1]; } + | name { $$ = $1; } +; + +name: + namespace_name_parts { $$ = Name[$1]; } + | T_NS_SEPARATOR namespace_name_parts { $$ = Name\FullyQualified[$2]; } + | T_NAMESPACE T_NS_SEPARATOR namespace_name_parts { $$ = Name\Relative[$3]; } +; + +class_name_reference: + class_name { $$ = $1; } + | dynamic_class_name_reference { $$ = $1; } +; + +dynamic_class_name_reference: + object_access_for_dcnr { $$ = $1; } + | base_variable { $$ = $1; } +; + +class_name_or_var: + class_name { $$ = $1; } + | reference_variable { $$ = $1; } +; + +object_access_for_dcnr: + base_variable T_OBJECT_OPERATOR object_property + { $$ = Expr\PropertyFetch[$1, $3]; } + | object_access_for_dcnr T_OBJECT_OPERATOR object_property + { $$ = Expr\PropertyFetch[$1, $3]; } + | object_access_for_dcnr '[' dim_offset ']' { $$ = Expr\ArrayDimFetch[$1, $3]; } + | object_access_for_dcnr '{' expr '}' { $$ = Expr\ArrayDimFetch[$1, $3]; } +; + +exit_expr: + /* empty */ { $$ = null; } + | '(' ')' { $$ = null; } + | parentheses_expr { $$ = $1; } +; + +backticks_expr: + /* empty */ { $$ = array(); } + | T_ENCAPSED_AND_WHITESPACE + { $$ = array(Scalar\EncapsedStringPart[Scalar\String_::parseEscapeSequences($1, '`', false)]); } + | encaps_list { parseEncapsed($1, '`', false); $$ = $1; } +; + +ctor_arguments: + /* empty */ { $$ = array(); } + | argument_list { $$ = $1; } +; + +common_scalar: + T_LNUMBER { $$ = $this->parseLNumber($1, attributes(), true); } + | T_DNUMBER { $$ = Scalar\DNumber[Scalar\DNumber::parse($1)]; } + | T_CONSTANT_ENCAPSED_STRING + { $attrs = attributes(); $attrs['kind'] = strKind($1); + $$ = new Scalar\String_(Scalar\String_::parse($1, false), $attrs); } + | T_LINE { $$ = Scalar\MagicConst\Line[]; } + | T_FILE { $$ = Scalar\MagicConst\File[]; } + | T_DIR { $$ = Scalar\MagicConst\Dir[]; } + | T_CLASS_C { $$ = Scalar\MagicConst\Class_[]; } + | T_TRAIT_C { $$ = Scalar\MagicConst\Trait_[]; } + | T_METHOD_C { $$ = Scalar\MagicConst\Method[]; } + | T_FUNC_C { $$ = Scalar\MagicConst\Function_[]; } + | T_NS_C { $$ = Scalar\MagicConst\Namespace_[]; } + | T_START_HEREDOC T_ENCAPSED_AND_WHITESPACE T_END_HEREDOC + { $attrs = attributes(); setDocStringAttrs($attrs, $1); + $$ = new Scalar\String_(Scalar\String_::parseDocString($1, $2, false), $attrs); } + | T_START_HEREDOC T_END_HEREDOC + { $attrs = attributes(); setDocStringAttrs($attrs, $1); + $$ = new Scalar\String_('', $attrs); } +; + +static_scalar: + common_scalar { $$ = $1; } + | class_name T_PAAMAYIM_NEKUDOTAYIM identifier { $$ = Expr\ClassConstFetch[$1, $3]; } + | name { $$ = Expr\ConstFetch[$1]; } + | T_ARRAY '(' static_array_pair_list ')' { $$ = Expr\Array_[$3]; } + | '[' static_array_pair_list ']' { $$ = Expr\Array_[$2]; } + | static_operation { $$ = $1; } +; + +static_operation: + static_scalar T_BOOLEAN_OR static_scalar { $$ = Expr\BinaryOp\BooleanOr [$1, $3]; } + | static_scalar T_BOOLEAN_AND static_scalar { $$ = Expr\BinaryOp\BooleanAnd[$1, $3]; } + | static_scalar T_LOGICAL_OR static_scalar { $$ = Expr\BinaryOp\LogicalOr [$1, $3]; } + | static_scalar T_LOGICAL_AND static_scalar { $$ = Expr\BinaryOp\LogicalAnd[$1, $3]; } + | static_scalar T_LOGICAL_XOR static_scalar { $$ = Expr\BinaryOp\LogicalXor[$1, $3]; } + | static_scalar '|' static_scalar { $$ = Expr\BinaryOp\BitwiseOr [$1, $3]; } + | static_scalar '&' static_scalar { $$ = Expr\BinaryOp\BitwiseAnd[$1, $3]; } + | static_scalar '^' static_scalar { $$ = Expr\BinaryOp\BitwiseXor[$1, $3]; } + | static_scalar '.' static_scalar { $$ = Expr\BinaryOp\Concat [$1, $3]; } + | static_scalar '+' static_scalar { $$ = Expr\BinaryOp\Plus [$1, $3]; } + | static_scalar '-' static_scalar { $$ = Expr\BinaryOp\Minus [$1, $3]; } + | static_scalar '*' static_scalar { $$ = Expr\BinaryOp\Mul [$1, $3]; } + | static_scalar '/' static_scalar { $$ = Expr\BinaryOp\Div [$1, $3]; } + | static_scalar '%' static_scalar { $$ = Expr\BinaryOp\Mod [$1, $3]; } + | static_scalar T_SL static_scalar { $$ = Expr\BinaryOp\ShiftLeft [$1, $3]; } + | static_scalar T_SR static_scalar { $$ = Expr\BinaryOp\ShiftRight[$1, $3]; } + | static_scalar T_POW static_scalar { $$ = Expr\BinaryOp\Pow [$1, $3]; } + | '+' static_scalar %prec T_INC { $$ = Expr\UnaryPlus [$2]; } + | '-' static_scalar %prec T_INC { $$ = Expr\UnaryMinus[$2]; } + | '!' static_scalar { $$ = Expr\BooleanNot[$2]; } + | '~' static_scalar { $$ = Expr\BitwiseNot[$2]; } + | static_scalar T_IS_IDENTICAL static_scalar { $$ = Expr\BinaryOp\Identical [$1, $3]; } + | static_scalar T_IS_NOT_IDENTICAL static_scalar { $$ = Expr\BinaryOp\NotIdentical [$1, $3]; } + | static_scalar T_IS_EQUAL static_scalar { $$ = Expr\BinaryOp\Equal [$1, $3]; } + | static_scalar T_IS_NOT_EQUAL static_scalar { $$ = Expr\BinaryOp\NotEqual [$1, $3]; } + | static_scalar '<' static_scalar { $$ = Expr\BinaryOp\Smaller [$1, $3]; } + | static_scalar T_IS_SMALLER_OR_EQUAL static_scalar { $$ = Expr\BinaryOp\SmallerOrEqual[$1, $3]; } + | static_scalar '>' static_scalar { $$ = Expr\BinaryOp\Greater [$1, $3]; } + | static_scalar T_IS_GREATER_OR_EQUAL static_scalar { $$ = Expr\BinaryOp\GreaterOrEqual[$1, $3]; } + | static_scalar '?' static_scalar ':' static_scalar { $$ = Expr\Ternary[$1, $3, $5]; } + | static_scalar '?' ':' static_scalar { $$ = Expr\Ternary[$1, null, $4]; } + | static_scalar '[' static_scalar ']' { $$ = Expr\ArrayDimFetch[$1, $3]; } + | '(' static_scalar ')' { $$ = $2; } +; + +constant: + name { $$ = Expr\ConstFetch[$1]; } + | class_name_or_var T_PAAMAYIM_NEKUDOTAYIM identifier + { $$ = Expr\ClassConstFetch[$1, $3]; } +; + +scalar: + common_scalar { $$ = $1; } + | constant { $$ = $1; } + | '"' encaps_list '"' + { $attrs = attributes(); $attrs['kind'] = Scalar\String_::KIND_DOUBLE_QUOTED; + parseEncapsed($2, '"', true); $$ = new Scalar\Encapsed($2, $attrs); } + | T_START_HEREDOC encaps_list T_END_HEREDOC + { $attrs = attributes(); setDocStringAttrs($attrs, $1); + parseEncapsedDoc($2, true); $$ = new Scalar\Encapsed($2, $attrs); } +; + +static_array_pair_list: + /* empty */ { $$ = array(); } + | non_empty_static_array_pair_list optional_comma { $$ = $1; } +; + +optional_comma: + /* empty */ + | ',' +; + +non_empty_static_array_pair_list: + non_empty_static_array_pair_list ',' static_array_pair { push($1, $3); } + | static_array_pair { init($1); } +; + +static_array_pair: + static_scalar T_DOUBLE_ARROW static_scalar { $$ = Expr\ArrayItem[$3, $1, false]; } + | static_scalar { $$ = Expr\ArrayItem[$1, null, false]; } +; + +variable: + object_access { $$ = $1; } + | base_variable { $$ = $1; } + | function_call { $$ = $1; } + | new_expr_array_deref { $$ = $1; } +; + +new_expr_array_deref: + '(' new_expr ')' '[' dim_offset ']' { $$ = Expr\ArrayDimFetch[$2, $5]; } + | new_expr_array_deref '[' dim_offset ']' { $$ = Expr\ArrayDimFetch[$1, $3]; } + /* alternative array syntax missing intentionally */ +; + +object_access: + variable_or_new_expr T_OBJECT_OPERATOR object_property + { $$ = Expr\PropertyFetch[$1, $3]; } + | variable_or_new_expr T_OBJECT_OPERATOR object_property argument_list + { $$ = Expr\MethodCall[$1, $3, $4]; } + | object_access argument_list { $$ = Expr\FuncCall[$1, $2]; } + | object_access '[' dim_offset ']' { $$ = Expr\ArrayDimFetch[$1, $3]; } + | object_access '{' expr '}' { $$ = Expr\ArrayDimFetch[$1, $3]; } +; + +variable_or_new_expr: + variable { $$ = $1; } + | '(' new_expr ')' { $$ = $2; } +; + +variable_without_objects: + reference_variable { $$ = $1; } + | '$' variable_without_objects { $$ = Expr\Variable[$2]; } +; + +base_variable: + variable_without_objects { $$ = $1; } + | static_property { $$ = $1; } +; + +static_property: + class_name_or_var T_PAAMAYIM_NEKUDOTAYIM '$' reference_variable + { $$ = Expr\StaticPropertyFetch[$1, $4]; } + | static_property_with_arrays { $$ = $1; } +; + +static_property_with_arrays: + class_name_or_var T_PAAMAYIM_NEKUDOTAYIM T_VARIABLE + { $$ = Expr\StaticPropertyFetch[$1, parseVar($3)]; } + | class_name_or_var T_PAAMAYIM_NEKUDOTAYIM '$' '{' expr '}' + { $$ = Expr\StaticPropertyFetch[$1, $5]; } + | static_property_with_arrays '[' dim_offset ']' { $$ = Expr\ArrayDimFetch[$1, $3]; } + | static_property_with_arrays '{' expr '}' { $$ = Expr\ArrayDimFetch[$1, $3]; } +; + +reference_variable: + reference_variable '[' dim_offset ']' { $$ = Expr\ArrayDimFetch[$1, $3]; } + | reference_variable '{' expr '}' { $$ = Expr\ArrayDimFetch[$1, $3]; } + | T_VARIABLE { $$ = Expr\Variable[parseVar($1)]; } + | '$' '{' expr '}' { $$ = Expr\Variable[$3]; } +; + +dim_offset: + /* empty */ { $$ = null; } + | expr { $$ = $1; } +; + +object_property: + T_STRING { $$ = $1; } + | '{' expr '}' { $$ = $2; } + | variable_without_objects { $$ = $1; } + | error { $$ = Expr\Error[]; $this->errorState = 2; } +; + +list_expr: + T_LIST '(' list_expr_elements ')' { $$ = Expr\List_[$3]; } +; + +list_expr_elements: + list_expr_elements ',' list_expr_element { push($1, $3); } + | list_expr_element { init($1); } +; + +list_expr_element: + variable { $$ = Expr\ArrayItem[$1, null, false]; } + | list_expr { $$ = Expr\ArrayItem[$1, null, false]; } + | /* empty */ { $$ = null; } +; + +array_pair_list: + /* empty */ { $$ = array(); } + | non_empty_array_pair_list optional_comma { $$ = $1; } +; + +non_empty_array_pair_list: + non_empty_array_pair_list ',' array_pair { push($1, $3); } + | array_pair { init($1); } +; + +array_pair: + expr T_DOUBLE_ARROW expr { $$ = Expr\ArrayItem[$3, $1, false]; } + | expr { $$ = Expr\ArrayItem[$1, null, false]; } + | expr T_DOUBLE_ARROW '&' variable { $$ = Expr\ArrayItem[$4, $1, true]; } + | '&' variable { $$ = Expr\ArrayItem[$2, null, true]; } +; + +encaps_list: + encaps_list encaps_var { push($1, $2); } + | encaps_list encaps_string_part { push($1, $2); } + | encaps_var { init($1); } + | encaps_string_part encaps_var { init($1, $2); } +; + +encaps_string_part: + T_ENCAPSED_AND_WHITESPACE { $$ = Scalar\EncapsedStringPart[$1]; } +; + +encaps_base_var: + T_VARIABLE { $$ = Expr\Variable[parseVar($1)]; } +; + +encaps_var: + encaps_base_var { $$ = $1; } + | encaps_base_var '[' encaps_var_offset ']' { $$ = Expr\ArrayDimFetch[$1, $3]; } + | encaps_base_var T_OBJECT_OPERATOR T_STRING { $$ = Expr\PropertyFetch[$1, $3]; } + | T_DOLLAR_OPEN_CURLY_BRACES expr '}' { $$ = Expr\Variable[$2]; } + | T_DOLLAR_OPEN_CURLY_BRACES T_STRING_VARNAME '}' { $$ = Expr\Variable[$2]; } + | T_DOLLAR_OPEN_CURLY_BRACES T_STRING_VARNAME '[' expr ']' '}' + { $$ = Expr\ArrayDimFetch[Expr\Variable[$2], $4]; } + | T_CURLY_OPEN variable '}' { $$ = $2; } +; + +encaps_var_offset: + T_STRING { $$ = Scalar\String_[$1]; } + | T_NUM_STRING { $$ = $this->parseNumString($1, attributes()); } + | T_VARIABLE { $$ = Expr\Variable[parseVar($1)]; } +; + +%% diff --git a/lib/nikic/php-parser/grammar/php7.y b/lib/nikic/php-parser/grammar/php7.y new file mode 100644 index 000000000..f9b599b8d --- /dev/null +++ b/lib/nikic/php-parser/grammar/php7.y @@ -0,0 +1,965 @@ +%pure_parser +%expect 2 + +%tokens + +%% + +start: + top_statement_list { $$ = $this->handleNamespaces($1); } +; + +top_statement_list_ex: + top_statement_list_ex top_statement { pushNormalizing($1, $2); } + | /* empty */ { init(); } +; + +top_statement_list: + top_statement_list_ex + { makeNop($nop, $this->lookaheadStartAttributes); + if ($nop !== null) { $1[] = $nop; } $$ = $1; } +; + +reserved_non_modifiers: + T_INCLUDE | T_INCLUDE_ONCE | T_EVAL | T_REQUIRE | T_REQUIRE_ONCE | T_LOGICAL_OR | T_LOGICAL_XOR | T_LOGICAL_AND + | T_INSTANCEOF | T_NEW | T_CLONE | T_EXIT | T_IF | T_ELSEIF | T_ELSE | T_ENDIF | T_ECHO | T_DO | T_WHILE + | T_ENDWHILE | T_FOR | T_ENDFOR | T_FOREACH | T_ENDFOREACH | T_DECLARE | T_ENDDECLARE | T_AS | T_TRY | T_CATCH + | T_FINALLY | T_THROW | T_USE | T_INSTEADOF | T_GLOBAL | T_VAR | T_UNSET | T_ISSET | T_EMPTY | T_CONTINUE | T_GOTO + | T_FUNCTION | T_CONST | T_RETURN | T_PRINT | T_YIELD | T_LIST | T_SWITCH | T_ENDSWITCH | T_CASE | T_DEFAULT + | T_BREAK | T_ARRAY | T_CALLABLE | T_EXTENDS | T_IMPLEMENTS | T_NAMESPACE | T_TRAIT | T_INTERFACE | T_CLASS + | T_CLASS_C | T_TRAIT_C | T_FUNC_C | T_METHOD_C | T_LINE | T_FILE | T_DIR | T_NS_C | T_HALT_COMPILER +; + +semi_reserved: + reserved_non_modifiers + | T_STATIC | T_ABSTRACT | T_FINAL | T_PRIVATE | T_PROTECTED | T_PUBLIC +; + +identifier: + T_STRING { $$ = $1; } + | semi_reserved { $$ = $1; } +; + +namespace_name_parts: + T_STRING { init($1); } + | namespace_name_parts T_NS_SEPARATOR T_STRING { push($1, $3); } +; + +namespace_name: + namespace_name_parts { $$ = Name[$1]; } +; + +semi: + ';' { /* nothing */ } + | error { /* nothing */ } +; + +no_comma: + /* empty */ { /* nothing */ } + | ',' { $this->emitError(new Error('A trailing comma is not allowed here', attributes())); } +; + +optional_comma: + /* empty */ + | ',' + +top_statement: + statement { $$ = $1; } + | function_declaration_statement { $$ = $1; } + | class_declaration_statement { $$ = $1; } + | T_HALT_COMPILER + { $$ = Stmt\HaltCompiler[$this->lexer->handleHaltCompiler()]; } + | T_NAMESPACE namespace_name semi + { $$ = Stmt\Namespace_[$2, null]; + $$->setAttribute('kind', Stmt\Namespace_::KIND_SEMICOLON); + $this->checkNamespace($$); } + | T_NAMESPACE namespace_name '{' top_statement_list '}' + { $$ = Stmt\Namespace_[$2, $4]; + $$->setAttribute('kind', Stmt\Namespace_::KIND_BRACED); + $this->checkNamespace($$); } + | T_NAMESPACE '{' top_statement_list '}' + { $$ = Stmt\Namespace_[null, $3]; + $$->setAttribute('kind', Stmt\Namespace_::KIND_BRACED); + $this->checkNamespace($$); } + | T_USE use_declarations semi { $$ = Stmt\Use_[$2, Stmt\Use_::TYPE_NORMAL]; } + | T_USE use_type use_declarations semi { $$ = Stmt\Use_[$3, $2]; } + | group_use_declaration semi { $$ = $1; } + | T_CONST constant_declaration_list semi { $$ = Stmt\Const_[$2]; } +; + +use_type: + T_FUNCTION { $$ = Stmt\Use_::TYPE_FUNCTION; } + | T_CONST { $$ = Stmt\Use_::TYPE_CONSTANT; } +; + +/* Using namespace_name_parts here to avoid s/r conflict on T_NS_SEPARATOR */ +group_use_declaration: + T_USE use_type namespace_name_parts T_NS_SEPARATOR '{' unprefixed_use_declarations '}' + { $$ = Stmt\GroupUse[new Name($3, stackAttributes(#3)), $6, $2]; } + | T_USE use_type T_NS_SEPARATOR namespace_name_parts T_NS_SEPARATOR '{' unprefixed_use_declarations '}' + { $$ = Stmt\GroupUse[new Name($4, stackAttributes(#4)), $7, $2]; } + | T_USE namespace_name_parts T_NS_SEPARATOR '{' inline_use_declarations '}' + { $$ = Stmt\GroupUse[new Name($2, stackAttributes(#2)), $5, Stmt\Use_::TYPE_UNKNOWN]; } + | T_USE T_NS_SEPARATOR namespace_name_parts T_NS_SEPARATOR '{' inline_use_declarations '}' + { $$ = Stmt\GroupUse[new Name($3, stackAttributes(#3)), $6, Stmt\Use_::TYPE_UNKNOWN]; } +; + +unprefixed_use_declarations: + non_empty_unprefixed_use_declarations optional_comma { $$ = $1; } +; + +non_empty_unprefixed_use_declarations: + non_empty_unprefixed_use_declarations ',' unprefixed_use_declaration + { push($1, $3); } + | unprefixed_use_declaration { init($1); } +; + +use_declarations: + non_empty_use_declarations no_comma { $$ = $1; } +; + +non_empty_use_declarations: + non_empty_use_declarations ',' use_declaration { push($1, $3); } + | use_declaration { init($1); } +; + +inline_use_declarations: + non_empty_inline_use_declarations optional_comma { $$ = $1; } +; + +non_empty_inline_use_declarations: + non_empty_inline_use_declarations ',' inline_use_declaration + { push($1, $3); } + | inline_use_declaration { init($1); } +; + +unprefixed_use_declaration: + namespace_name + { $$ = Stmt\UseUse[$1, null, Stmt\Use_::TYPE_UNKNOWN]; $this->checkUseUse($$, #1); } + | namespace_name T_AS T_STRING + { $$ = Stmt\UseUse[$1, $3, Stmt\Use_::TYPE_UNKNOWN]; $this->checkUseUse($$, #3); } +; + +use_declaration: + unprefixed_use_declaration { $$ = $1; } + | T_NS_SEPARATOR unprefixed_use_declaration { $$ = $2; } +; + +inline_use_declaration: + unprefixed_use_declaration { $$ = $1; $$->type = Stmt\Use_::TYPE_NORMAL; } + | use_type unprefixed_use_declaration { $$ = $2; $$->type = $1; } +; + +constant_declaration_list: + non_empty_constant_declaration_list no_comma { $$ = $1; } +; + +non_empty_constant_declaration_list: + non_empty_constant_declaration_list ',' constant_declaration + { push($1, $3); } + | constant_declaration { init($1); } +; + +constant_declaration: + T_STRING '=' expr { $$ = Node\Const_[$1, $3]; } +; + +class_const_list: + non_empty_class_const_list no_comma { $$ = $1; } +; + +non_empty_class_const_list: + non_empty_class_const_list ',' class_const { push($1, $3); } + | class_const { init($1); } +; + +class_const: + identifier '=' expr { $$ = Node\Const_[$1, $3]; } +; + +inner_statement_list_ex: + inner_statement_list_ex inner_statement { pushNormalizing($1, $2); } + | /* empty */ { init(); } +; + +inner_statement_list: + inner_statement_list_ex + { makeNop($nop, $this->lookaheadStartAttributes); + if ($nop !== null) { $1[] = $nop; } $$ = $1; } +; + +inner_statement: + statement { $$ = $1; } + | function_declaration_statement { $$ = $1; } + | class_declaration_statement { $$ = $1; } + | T_HALT_COMPILER + { throw new Error('__HALT_COMPILER() can only be used from the outermost scope', attributes()); } +; + +non_empty_statement: + '{' inner_statement_list '}' + { + if ($2) { + $$ = $2; prependLeadingComments($$); + } else { + makeNop($$, $this->startAttributeStack[#1]); + if (null === $$) { $$ = array(); } + } + } + | T_IF '(' expr ')' statement elseif_list else_single + { $$ = Stmt\If_[$3, ['stmts' => toArray($5), 'elseifs' => $6, 'else' => $7]]; } + | T_IF '(' expr ')' ':' inner_statement_list new_elseif_list new_else_single T_ENDIF ';' + { $$ = Stmt\If_[$3, ['stmts' => $6, 'elseifs' => $7, 'else' => $8]]; } + | T_WHILE '(' expr ')' while_statement { $$ = Stmt\While_[$3, $5]; } + | T_DO statement T_WHILE '(' expr ')' ';' { $$ = Stmt\Do_ [$5, toArray($2)]; } + | T_FOR '(' for_expr ';' for_expr ';' for_expr ')' for_statement + { $$ = Stmt\For_[['init' => $3, 'cond' => $5, 'loop' => $7, 'stmts' => $9]]; } + | T_SWITCH '(' expr ')' switch_case_list { $$ = Stmt\Switch_[$3, $5]; } + | T_BREAK optional_expr semi { $$ = Stmt\Break_[$2]; } + | T_CONTINUE optional_expr semi { $$ = Stmt\Continue_[$2]; } + | T_RETURN optional_expr semi { $$ = Stmt\Return_[$2]; } + | T_GLOBAL global_var_list semi { $$ = Stmt\Global_[$2]; } + | T_STATIC static_var_list semi { $$ = Stmt\Static_[$2]; } + | T_ECHO expr_list semi { $$ = Stmt\Echo_[$2]; } + | T_INLINE_HTML { $$ = Stmt\InlineHTML[$1]; } + | expr semi { $$ = $1; } + | T_UNSET '(' variables_list ')' semi { $$ = Stmt\Unset_[$3]; } + | T_FOREACH '(' expr T_AS foreach_variable ')' foreach_statement + { $$ = Stmt\Foreach_[$3, $5[0], ['keyVar' => null, 'byRef' => $5[1], 'stmts' => $7]]; } + | T_FOREACH '(' expr T_AS variable T_DOUBLE_ARROW foreach_variable ')' foreach_statement + { $$ = Stmt\Foreach_[$3, $7[0], ['keyVar' => $5, 'byRef' => $7[1], 'stmts' => $9]]; } + | T_DECLARE '(' declare_list ')' declare_statement { $$ = Stmt\Declare_[$3, $5]; } + | T_TRY '{' inner_statement_list '}' catches optional_finally + { $$ = Stmt\TryCatch[$3, $5, $6]; $this->checkTryCatch($$); } + | T_THROW expr semi { $$ = Stmt\Throw_[$2]; } + | T_GOTO T_STRING semi { $$ = Stmt\Goto_[$2]; } + | T_STRING ':' { $$ = Stmt\Label[$1]; } + | error { $$ = array(); /* means: no statement */ } +; + +statement: + non_empty_statement { $$ = $1; } + | ';' + { makeNop($$, $this->startAttributeStack[#1]); + if ($$ === null) $$ = array(); /* means: no statement */ } +; + +catches: + /* empty */ { init(); } + | catches catch { push($1, $2); } +; + +name_union: + name { init($1); } + | name_union '|' name { push($1, $3); } +; + +catch: + T_CATCH '(' name_union T_VARIABLE ')' '{' inner_statement_list '}' + { $$ = Stmt\Catch_[$3, parseVar($4), $7]; } +; + +optional_finally: + /* empty */ { $$ = null; } + | T_FINALLY '{' inner_statement_list '}' { $$ = Stmt\Finally_[$3]; } +; + +variables_list: + non_empty_variables_list no_comma { $$ = $1; } +; + +non_empty_variables_list: + variable { init($1); } + | non_empty_variables_list ',' variable { push($1, $3); } +; + +optional_ref: + /* empty */ { $$ = false; } + | '&' { $$ = true; } +; + +optional_ellipsis: + /* empty */ { $$ = false; } + | T_ELLIPSIS { $$ = true; } +; + +function_declaration_statement: + T_FUNCTION optional_ref T_STRING '(' parameter_list ')' optional_return_type '{' inner_statement_list '}' + { $$ = Stmt\Function_[$3, ['byRef' => $2, 'params' => $5, 'returnType' => $7, 'stmts' => $9]]; } +; + +class_declaration_statement: + class_entry_type T_STRING extends_from implements_list '{' class_statement_list '}' + { $$ = Stmt\Class_[$2, ['type' => $1, 'extends' => $3, 'implements' => $4, 'stmts' => $6]]; + $this->checkClass($$, #2); } + | T_INTERFACE T_STRING interface_extends_list '{' class_statement_list '}' + { $$ = Stmt\Interface_[$2, ['extends' => $3, 'stmts' => $5]]; + $this->checkInterface($$, #2); } + | T_TRAIT T_STRING '{' class_statement_list '}' + { $$ = Stmt\Trait_[$2, ['stmts' => $4]]; } +; + +class_entry_type: + T_CLASS { $$ = 0; } + | T_ABSTRACT T_CLASS { $$ = Stmt\Class_::MODIFIER_ABSTRACT; } + | T_FINAL T_CLASS { $$ = Stmt\Class_::MODIFIER_FINAL; } +; + +extends_from: + /* empty */ { $$ = null; } + | T_EXTENDS class_name { $$ = $2; } +; + +interface_extends_list: + /* empty */ { $$ = array(); } + | T_EXTENDS class_name_list { $$ = $2; } +; + +implements_list: + /* empty */ { $$ = array(); } + | T_IMPLEMENTS class_name_list { $$ = $2; } +; + +class_name_list: + non_empty_class_name_list no_comma { $$ = $1; } +; + +non_empty_class_name_list: + class_name { init($1); } + | non_empty_class_name_list ',' class_name { push($1, $3); } +; + +for_statement: + statement { $$ = toArray($1); } + | ':' inner_statement_list T_ENDFOR ';' { $$ = $2; } +; + +foreach_statement: + statement { $$ = toArray($1); } + | ':' inner_statement_list T_ENDFOREACH ';' { $$ = $2; } +; + +declare_statement: + non_empty_statement { $$ = toArray($1); } + | ';' { $$ = null; } + | ':' inner_statement_list T_ENDDECLARE ';' { $$ = $2; } +; + +declare_list: + non_empty_declare_list no_comma { $$ = $1; } +; + +non_empty_declare_list: + declare_list_element { init($1); } + | non_empty_declare_list ',' declare_list_element { push($1, $3); } +; + +declare_list_element: + T_STRING '=' expr { $$ = Stmt\DeclareDeclare[$1, $3]; } +; + +switch_case_list: + '{' case_list '}' { $$ = $2; } + | '{' ';' case_list '}' { $$ = $3; } + | ':' case_list T_ENDSWITCH ';' { $$ = $2; } + | ':' ';' case_list T_ENDSWITCH ';' { $$ = $3; } +; + +case_list: + /* empty */ { init(); } + | case_list case { push($1, $2); } +; + +case: + T_CASE expr case_separator inner_statement_list_ex { $$ = Stmt\Case_[$2, $4]; } + | T_DEFAULT case_separator inner_statement_list_ex { $$ = Stmt\Case_[null, $3]; } +; + +case_separator: + ':' + | ';' +; + +while_statement: + statement { $$ = toArray($1); } + | ':' inner_statement_list T_ENDWHILE ';' { $$ = $2; } +; + +elseif_list: + /* empty */ { init(); } + | elseif_list elseif { push($1, $2); } +; + +elseif: + T_ELSEIF '(' expr ')' statement { $$ = Stmt\ElseIf_[$3, toArray($5)]; } +; + +new_elseif_list: + /* empty */ { init(); } + | new_elseif_list new_elseif { push($1, $2); } +; + +new_elseif: + T_ELSEIF '(' expr ')' ':' inner_statement_list { $$ = Stmt\ElseIf_[$3, $6]; } +; + +else_single: + /* empty */ { $$ = null; } + | T_ELSE statement { $$ = Stmt\Else_[toArray($2)]; } +; + +new_else_single: + /* empty */ { $$ = null; } + | T_ELSE ':' inner_statement_list { $$ = Stmt\Else_[$3]; } +; + +foreach_variable: + variable { $$ = array($1, false); } + | '&' variable { $$ = array($2, true); } + | list_expr { $$ = array($1, false); } + | array_short_syntax { $$ = array($1, false); } +; + +parameter_list: + non_empty_parameter_list no_comma { $$ = $1; } + | /* empty */ { $$ = array(); } +; + +non_empty_parameter_list: + parameter { init($1); } + | non_empty_parameter_list ',' parameter { push($1, $3); } +; + +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($$); } +; + +type_expr: + type { $$ = $1; } + | '?' type { $$ = Node\NullableType[$2]; } +; + +type: + name { $$ = $this->handleBuiltinTypes($1); } + | T_ARRAY { $$ = 'array'; } + | T_CALLABLE { $$ = 'callable'; } +; + +optional_param_type: + /* empty */ { $$ = null; } + | type_expr { $$ = $1; } +; + +optional_return_type: + /* empty */ { $$ = null; } + | ':' type_expr { $$ = $2; } +; + +argument_list: + '(' ')' { $$ = array(); } + | '(' non_empty_argument_list no_comma ')' { $$ = $2; } +; + +non_empty_argument_list: + argument { init($1); } + | non_empty_argument_list ',' argument { push($1, $3); } +; + +argument: + expr { $$ = Node\Arg[$1, false, false]; } + | '&' variable { $$ = Node\Arg[$2, true, false]; } + | T_ELLIPSIS expr { $$ = Node\Arg[$2, false, true]; } +; + +global_var_list: + non_empty_global_var_list no_comma { $$ = $1; } +; + +non_empty_global_var_list: + non_empty_global_var_list ',' global_var { push($1, $3); } + | global_var { init($1); } +; + +global_var: + simple_variable { $$ = Expr\Variable[$1]; } +; + +static_var_list: + non_empty_static_var_list no_comma { $$ = $1; } +; + +non_empty_static_var_list: + non_empty_static_var_list ',' static_var { push($1, $3); } + | static_var { init($1); } +; + +static_var: + T_VARIABLE { $$ = Stmt\StaticVar[parseVar($1), null]; } + | T_VARIABLE '=' expr { $$ = Stmt\StaticVar[parseVar($1), $3]; } +; + +class_statement_list: + class_statement_list class_statement { push($1, $2); } + | /* empty */ { init(); } +; + +class_statement: + variable_modifiers property_declaration_list ';' + { $$ = Stmt\Property[$1, $2]; $this->checkProperty($$, #1); } + | method_modifiers T_CONST class_const_list ';' + { $$ = Stmt\ClassConst[$3, $1]; $this->checkClassConst($$, #1); } + | method_modifiers T_FUNCTION optional_ref identifier '(' parameter_list ')' optional_return_type method_body + { $$ = Stmt\ClassMethod[$4, ['type' => $1, 'byRef' => $3, 'params' => $6, 'returnType' => $8, 'stmts' => $9]]; + $this->checkClassMethod($$, #1); } + | T_USE class_name_list trait_adaptations { $$ = Stmt\TraitUse[$2, $3]; } +; + +trait_adaptations: + ';' { $$ = array(); } + | '{' trait_adaptation_list '}' { $$ = $2; } +; + +trait_adaptation_list: + /* empty */ { init(); } + | trait_adaptation_list trait_adaptation { push($1, $2); } +; + +trait_adaptation: + trait_method_reference_fully_qualified T_INSTEADOF class_name_list ';' + { $$ = Stmt\TraitUseAdaptation\Precedence[$1[0], $1[1], $3]; } + | trait_method_reference T_AS member_modifier identifier ';' + { $$ = Stmt\TraitUseAdaptation\Alias[$1[0], $1[1], $3, $4]; } + | trait_method_reference T_AS member_modifier ';' + { $$ = Stmt\TraitUseAdaptation\Alias[$1[0], $1[1], $3, null]; } + | trait_method_reference T_AS T_STRING ';' + { $$ = Stmt\TraitUseAdaptation\Alias[$1[0], $1[1], null, $3]; } + | trait_method_reference T_AS reserved_non_modifiers ';' + { $$ = Stmt\TraitUseAdaptation\Alias[$1[0], $1[1], null, $3]; } +; + +trait_method_reference_fully_qualified: + name T_PAAMAYIM_NEKUDOTAYIM identifier { $$ = array($1, $3); } +; +trait_method_reference: + trait_method_reference_fully_qualified { $$ = $1; } + | identifier { $$ = array(null, $1); } +; + +method_body: + ';' /* abstract method */ { $$ = null; } + | '{' inner_statement_list '}' { $$ = $2; } +; + +variable_modifiers: + non_empty_member_modifiers { $$ = $1; } + | T_VAR { $$ = 0; } +; + +method_modifiers: + /* empty */ { $$ = 0; } + | non_empty_member_modifiers { $$ = $1; } +; + +non_empty_member_modifiers: + member_modifier { $$ = $1; } + | non_empty_member_modifiers member_modifier { $this->checkModifier($1, $2, #2); $$ = $1 | $2; } +; + +member_modifier: + T_PUBLIC { $$ = Stmt\Class_::MODIFIER_PUBLIC; } + | T_PROTECTED { $$ = Stmt\Class_::MODIFIER_PROTECTED; } + | T_PRIVATE { $$ = Stmt\Class_::MODIFIER_PRIVATE; } + | T_STATIC { $$ = Stmt\Class_::MODIFIER_STATIC; } + | T_ABSTRACT { $$ = Stmt\Class_::MODIFIER_ABSTRACT; } + | T_FINAL { $$ = Stmt\Class_::MODIFIER_FINAL; } +; + +property_declaration_list: + non_empty_property_declaration_list no_comma { $$ = $1; } +; + +non_empty_property_declaration_list: + property_declaration { init($1); } + | non_empty_property_declaration_list ',' property_declaration + { push($1, $3); } +; + +property_declaration: + T_VARIABLE { $$ = Stmt\PropertyProperty[parseVar($1), null]; } + | T_VARIABLE '=' expr { $$ = Stmt\PropertyProperty[parseVar($1), $3]; } +; + +expr_list: + non_empty_expr_list no_comma { $$ = $1; } +; + +non_empty_expr_list: + non_empty_expr_list ',' expr { push($1, $3); } + | expr { init($1); } +; + +for_expr: + /* empty */ { $$ = array(); } + | expr_list { $$ = $1; } +; + +expr: + variable { $$ = $1; } + | list_expr '=' expr { $$ = Expr\Assign[$1, $3]; } + | array_short_syntax '=' expr { $$ = Expr\Assign[$1, $3]; } + | variable '=' expr { $$ = Expr\Assign[$1, $3]; } + | variable '=' '&' variable { $$ = Expr\AssignRef[$1, $4]; } + | new_expr { $$ = $1; } + | T_CLONE expr { $$ = Expr\Clone_[$2]; } + | variable T_PLUS_EQUAL expr { $$ = Expr\AssignOp\Plus [$1, $3]; } + | variable T_MINUS_EQUAL expr { $$ = Expr\AssignOp\Minus [$1, $3]; } + | variable T_MUL_EQUAL expr { $$ = Expr\AssignOp\Mul [$1, $3]; } + | variable T_DIV_EQUAL expr { $$ = Expr\AssignOp\Div [$1, $3]; } + | variable T_CONCAT_EQUAL expr { $$ = Expr\AssignOp\Concat [$1, $3]; } + | variable T_MOD_EQUAL expr { $$ = Expr\AssignOp\Mod [$1, $3]; } + | variable T_AND_EQUAL expr { $$ = Expr\AssignOp\BitwiseAnd[$1, $3]; } + | variable T_OR_EQUAL expr { $$ = Expr\AssignOp\BitwiseOr [$1, $3]; } + | variable T_XOR_EQUAL expr { $$ = Expr\AssignOp\BitwiseXor[$1, $3]; } + | variable T_SL_EQUAL expr { $$ = Expr\AssignOp\ShiftLeft [$1, $3]; } + | variable T_SR_EQUAL expr { $$ = Expr\AssignOp\ShiftRight[$1, $3]; } + | variable T_POW_EQUAL expr { $$ = Expr\AssignOp\Pow [$1, $3]; } + | variable T_INC { $$ = Expr\PostInc[$1]; } + | T_INC variable { $$ = Expr\PreInc [$2]; } + | variable T_DEC { $$ = Expr\PostDec[$1]; } + | T_DEC variable { $$ = Expr\PreDec [$2]; } + | expr T_BOOLEAN_OR expr { $$ = Expr\BinaryOp\BooleanOr [$1, $3]; } + | expr T_BOOLEAN_AND expr { $$ = Expr\BinaryOp\BooleanAnd[$1, $3]; } + | expr T_LOGICAL_OR expr { $$ = Expr\BinaryOp\LogicalOr [$1, $3]; } + | expr T_LOGICAL_AND expr { $$ = Expr\BinaryOp\LogicalAnd[$1, $3]; } + | expr T_LOGICAL_XOR expr { $$ = Expr\BinaryOp\LogicalXor[$1, $3]; } + | expr '|' expr { $$ = Expr\BinaryOp\BitwiseOr [$1, $3]; } + | expr '&' expr { $$ = Expr\BinaryOp\BitwiseAnd[$1, $3]; } + | expr '^' expr { $$ = Expr\BinaryOp\BitwiseXor[$1, $3]; } + | expr '.' expr { $$ = Expr\BinaryOp\Concat [$1, $3]; } + | expr '+' expr { $$ = Expr\BinaryOp\Plus [$1, $3]; } + | expr '-' expr { $$ = Expr\BinaryOp\Minus [$1, $3]; } + | expr '*' expr { $$ = Expr\BinaryOp\Mul [$1, $3]; } + | expr '/' expr { $$ = Expr\BinaryOp\Div [$1, $3]; } + | expr '%' expr { $$ = Expr\BinaryOp\Mod [$1, $3]; } + | expr T_SL expr { $$ = Expr\BinaryOp\ShiftLeft [$1, $3]; } + | expr T_SR expr { $$ = Expr\BinaryOp\ShiftRight[$1, $3]; } + | expr T_POW expr { $$ = Expr\BinaryOp\Pow [$1, $3]; } + | '+' expr %prec T_INC { $$ = Expr\UnaryPlus [$2]; } + | '-' expr %prec T_INC { $$ = Expr\UnaryMinus[$2]; } + | '!' expr { $$ = Expr\BooleanNot[$2]; } + | '~' expr { $$ = Expr\BitwiseNot[$2]; } + | expr T_IS_IDENTICAL expr { $$ = Expr\BinaryOp\Identical [$1, $3]; } + | expr T_IS_NOT_IDENTICAL expr { $$ = Expr\BinaryOp\NotIdentical [$1, $3]; } + | expr T_IS_EQUAL expr { $$ = Expr\BinaryOp\Equal [$1, $3]; } + | expr T_IS_NOT_EQUAL expr { $$ = Expr\BinaryOp\NotEqual [$1, $3]; } + | expr T_SPACESHIP expr { $$ = Expr\BinaryOp\Spaceship [$1, $3]; } + | expr '<' expr { $$ = Expr\BinaryOp\Smaller [$1, $3]; } + | expr T_IS_SMALLER_OR_EQUAL expr { $$ = Expr\BinaryOp\SmallerOrEqual[$1, $3]; } + | expr '>' expr { $$ = Expr\BinaryOp\Greater [$1, $3]; } + | expr T_IS_GREATER_OR_EQUAL expr { $$ = Expr\BinaryOp\GreaterOrEqual[$1, $3]; } + | expr T_INSTANCEOF class_name_reference { $$ = Expr\Instanceof_[$1, $3]; } + | '(' expr ')' { $$ = $2; } + | expr '?' expr ':' expr { $$ = Expr\Ternary[$1, $3, $5]; } + | expr '?' ':' expr { $$ = Expr\Ternary[$1, null, $4]; } + | expr T_COALESCE expr { $$ = Expr\BinaryOp\Coalesce[$1, $3]; } + | T_ISSET '(' variables_list ')' { $$ = Expr\Isset_[$3]; } + | T_EMPTY '(' expr ')' { $$ = Expr\Empty_[$3]; } + | T_INCLUDE expr { $$ = Expr\Include_[$2, Expr\Include_::TYPE_INCLUDE]; } + | T_INCLUDE_ONCE expr { $$ = Expr\Include_[$2, Expr\Include_::TYPE_INCLUDE_ONCE]; } + | T_EVAL '(' expr ')' { $$ = Expr\Eval_[$3]; } + | T_REQUIRE expr { $$ = Expr\Include_[$2, Expr\Include_::TYPE_REQUIRE]; } + | T_REQUIRE_ONCE expr { $$ = Expr\Include_[$2, Expr\Include_::TYPE_REQUIRE_ONCE]; } + | T_INT_CAST expr { $$ = Expr\Cast\Int_ [$2]; } + | T_DOUBLE_CAST expr { $$ = Expr\Cast\Double [$2]; } + | T_STRING_CAST expr { $$ = Expr\Cast\String_ [$2]; } + | T_ARRAY_CAST expr { $$ = Expr\Cast\Array_ [$2]; } + | T_OBJECT_CAST expr { $$ = Expr\Cast\Object_ [$2]; } + | T_BOOL_CAST expr { $$ = Expr\Cast\Bool_ [$2]; } + | T_UNSET_CAST expr { $$ = Expr\Cast\Unset_ [$2]; } + | T_EXIT exit_expr + { $attrs = attributes(); + $attrs['kind'] = strtolower($1) === 'exit' ? Expr\Exit_::KIND_EXIT : Expr\Exit_::KIND_DIE; + $$ = new Expr\Exit_($2, $attrs); } + | '@' expr { $$ = Expr\ErrorSuppress[$2]; } + | scalar { $$ = $1; } + | '`' backticks_expr '`' { $$ = Expr\ShellExec[$2]; } + | T_PRINT expr { $$ = Expr\Print_[$2]; } + | T_YIELD { $$ = Expr\Yield_[null, null]; } + | T_YIELD expr { $$ = Expr\Yield_[$2, null]; } + | T_YIELD expr T_DOUBLE_ARROW expr { $$ = Expr\Yield_[$4, $2]; } + | T_YIELD_FROM expr { $$ = Expr\YieldFrom[$2]; } + | T_FUNCTION optional_ref '(' parameter_list ')' lexical_vars optional_return_type + '{' inner_statement_list '}' + { $$ = Expr\Closure[['static' => false, 'byRef' => $2, 'params' => $4, 'uses' => $6, 'returnType' => $7, 'stmts' => $9]]; } + | T_STATIC T_FUNCTION optional_ref '(' parameter_list ')' lexical_vars optional_return_type + '{' inner_statement_list '}' + { $$ = Expr\Closure[['static' => true, 'byRef' => $3, 'params' => $5, 'uses' => $7, 'returnType' => $8, 'stmts' => $10]]; } +; + +anonymous_class: + T_CLASS ctor_arguments extends_from implements_list '{' class_statement_list '}' + { $$ = array(Stmt\Class_[null, ['type' => 0, 'extends' => $3, 'implements' => $4, 'stmts' => $6]], $2); + $this->checkClass($$[0], -1); } + +new_expr: + T_NEW class_name_reference ctor_arguments { $$ = Expr\New_[$2, $3]; } + | T_NEW anonymous_class + { list($class, $ctorArgs) = $2; $$ = Expr\New_[$class, $ctorArgs]; } +; + +lexical_vars: + /* empty */ { $$ = array(); } + | T_USE '(' lexical_var_list ')' { $$ = $3; } +; + +lexical_var_list: + non_empty_lexical_var_list no_comma { $$ = $1; } +; + +non_empty_lexical_var_list: + lexical_var { init($1); } + | non_empty_lexical_var_list ',' lexical_var { push($1, $3); } +; + +lexical_var: + optional_ref T_VARIABLE { $$ = Expr\ClosureUse[parseVar($2), $1]; } +; + +function_call: + name argument_list { $$ = Expr\FuncCall[$1, $2]; } + | callable_expr argument_list { $$ = Expr\FuncCall[$1, $2]; } + | class_name_or_var T_PAAMAYIM_NEKUDOTAYIM member_name argument_list + { $$ = Expr\StaticCall[$1, $3, $4]; } +; + +class_name: + T_STATIC { $$ = Name[$1]; } + | name { $$ = $1; } +; + +name: + namespace_name_parts { $$ = Name[$1]; } + | T_NS_SEPARATOR namespace_name_parts { $$ = Name\FullyQualified[$2]; } + | T_NAMESPACE T_NS_SEPARATOR namespace_name_parts { $$ = Name\Relative[$3]; } +; + +class_name_reference: + class_name { $$ = $1; } + | new_variable { $$ = $1; } + | error { $$ = Expr\Error[]; $this->errorState = 2; } +; + +class_name_or_var: + class_name { $$ = $1; } + | dereferencable { $$ = $1; } +; + +exit_expr: + /* empty */ { $$ = null; } + | '(' optional_expr ')' { $$ = $2; } +; + +backticks_expr: + /* empty */ { $$ = array(); } + | T_ENCAPSED_AND_WHITESPACE + { $$ = array(Scalar\EncapsedStringPart[Scalar\String_::parseEscapeSequences($1, '`')]); } + | encaps_list { parseEncapsed($1, '`', true); $$ = $1; } +; + +ctor_arguments: + /* empty */ { $$ = array(); } + | argument_list { $$ = $1; } +; + +constant: + name { $$ = Expr\ConstFetch[$1]; } + | class_name_or_var T_PAAMAYIM_NEKUDOTAYIM identifier + { $$ = Expr\ClassConstFetch[$1, $3]; } + /* We interpret and isolated FOO:: as an unfinished class constant fetch. It could also be + an unfinished static property fetch or unfinished scoped call. */ + | class_name_or_var T_PAAMAYIM_NEKUDOTAYIM error + { $$ = Expr\ClassConstFetch[$1, new Expr\Error(stackAttributes(#3))]; $this->errorState = 2; } +; + +array_short_syntax: + '[' array_pair_list ']' + { $attrs = attributes(); $attrs['kind'] = Expr\Array_::KIND_SHORT; + $$ = new Expr\Array_($2, $attrs); } +; + +dereferencable_scalar: + T_ARRAY '(' array_pair_list ')' + { $attrs = attributes(); $attrs['kind'] = Expr\Array_::KIND_LONG; + $$ = new Expr\Array_($3, $attrs); } + | array_short_syntax { $$ = $1; } + | T_CONSTANT_ENCAPSED_STRING + { $attrs = attributes(); $attrs['kind'] = strKind($1); + $$ = new Scalar\String_(Scalar\String_::parse($1), $attrs); } +; + +scalar: + T_LNUMBER { $$ = $this->parseLNumber($1, attributes()); } + | T_DNUMBER { $$ = Scalar\DNumber[Scalar\DNumber::parse($1)]; } + | T_LINE { $$ = Scalar\MagicConst\Line[]; } + | T_FILE { $$ = Scalar\MagicConst\File[]; } + | T_DIR { $$ = Scalar\MagicConst\Dir[]; } + | T_CLASS_C { $$ = Scalar\MagicConst\Class_[]; } + | T_TRAIT_C { $$ = Scalar\MagicConst\Trait_[]; } + | T_METHOD_C { $$ = Scalar\MagicConst\Method[]; } + | T_FUNC_C { $$ = Scalar\MagicConst\Function_[]; } + | T_NS_C { $$ = Scalar\MagicConst\Namespace_[]; } + | dereferencable_scalar { $$ = $1; } + | constant { $$ = $1; } + | T_START_HEREDOC T_ENCAPSED_AND_WHITESPACE T_END_HEREDOC + { $attrs = attributes(); setDocStringAttrs($attrs, $1); + $$ = new Scalar\String_(Scalar\String_::parseDocString($1, $2), $attrs); } + | T_START_HEREDOC T_END_HEREDOC + { $attrs = attributes(); setDocStringAttrs($attrs, $1); + $$ = new Scalar\String_('', $attrs); } + | '"' encaps_list '"' + { $attrs = attributes(); $attrs['kind'] = Scalar\String_::KIND_DOUBLE_QUOTED; + parseEncapsed($2, '"', true); $$ = new Scalar\Encapsed($2, $attrs); } + | T_START_HEREDOC encaps_list T_END_HEREDOC + { $attrs = attributes(); setDocStringAttrs($attrs, $1); + parseEncapsedDoc($2, true); $$ = new Scalar\Encapsed($2, $attrs); } +; + +optional_expr: + /* empty */ { $$ = null; } + | expr { $$ = $1; } +; + +dereferencable: + variable { $$ = $1; } + | '(' expr ')' { $$ = $2; } + | dereferencable_scalar { $$ = $1; } +; + +callable_expr: + callable_variable { $$ = $1; } + | '(' expr ')' { $$ = $2; } + | dereferencable_scalar { $$ = $1; } +; + +callable_variable: + simple_variable { $$ = Expr\Variable[$1]; } + | dereferencable '[' optional_expr ']' { $$ = Expr\ArrayDimFetch[$1, $3]; } + | constant '[' optional_expr ']' { $$ = Expr\ArrayDimFetch[$1, $3]; } + | dereferencable '{' expr '}' { $$ = Expr\ArrayDimFetch[$1, $3]; } + | function_call { $$ = $1; } + | dereferencable T_OBJECT_OPERATOR property_name argument_list + { $$ = Expr\MethodCall[$1, $3, $4]; } +; + +variable: + callable_variable { $$ = $1; } + | static_member { $$ = $1; } + | dereferencable T_OBJECT_OPERATOR property_name { $$ = Expr\PropertyFetch[$1, $3]; } +; + +simple_variable: + T_VARIABLE { $$ = parseVar($1); } + | '$' '{' expr '}' { $$ = $3; } + | '$' simple_variable { $$ = Expr\Variable[$2]; } + | '$' error { $$ = Expr\Error[]; $this->errorState = 2; } +; + +static_member: + class_name_or_var T_PAAMAYIM_NEKUDOTAYIM simple_variable + { $$ = Expr\StaticPropertyFetch[$1, $3]; } +; + +new_variable: + simple_variable { $$ = Expr\Variable[$1]; } + | new_variable '[' optional_expr ']' { $$ = Expr\ArrayDimFetch[$1, $3]; } + | new_variable '{' expr '}' { $$ = Expr\ArrayDimFetch[$1, $3]; } + | new_variable T_OBJECT_OPERATOR property_name { $$ = Expr\PropertyFetch[$1, $3]; } + | class_name T_PAAMAYIM_NEKUDOTAYIM simple_variable { $$ = Expr\StaticPropertyFetch[$1, $3]; } + | new_variable T_PAAMAYIM_NEKUDOTAYIM simple_variable { $$ = Expr\StaticPropertyFetch[$1, $3]; } +; + +member_name: + identifier { $$ = $1; } + | '{' expr '}' { $$ = $2; } + | simple_variable { $$ = Expr\Variable[$1]; } +; + +property_name: + T_STRING { $$ = $1; } + | '{' expr '}' { $$ = $2; } + | simple_variable { $$ = Expr\Variable[$1]; } + | error { $$ = Expr\Error[]; $this->errorState = 2; } +; + +list_expr: + T_LIST '(' list_expr_elements ')' { $$ = Expr\List_[$3]; } +; + +list_expr_elements: + list_expr_elements ',' list_expr_element { push($1, $3); } + | list_expr_element { init($1); } +; + +list_expr_element: + variable { $$ = Expr\ArrayItem[$1, null, false]; } + | list_expr { $$ = Expr\ArrayItem[$1, null, false]; } + | expr T_DOUBLE_ARROW variable { $$ = Expr\ArrayItem[$3, $1, false]; } + | expr T_DOUBLE_ARROW list_expr { $$ = Expr\ArrayItem[$3, $1, false]; } + | /* empty */ { $$ = null; } +; + +array_pair_list: + inner_array_pair_list + { $$ = $1; $end = count($$)-1; if ($$[$end] === null) unset($$[$end]); } +; + +inner_array_pair_list: + inner_array_pair_list ',' array_pair { push($1, $3); } + | array_pair { init($1); } +; + +array_pair: + expr T_DOUBLE_ARROW expr { $$ = Expr\ArrayItem[$3, $1, false]; } + | expr { $$ = Expr\ArrayItem[$1, null, false]; } + | expr T_DOUBLE_ARROW '&' variable { $$ = Expr\ArrayItem[$4, $1, true]; } + | '&' variable { $$ = Expr\ArrayItem[$2, null, true]; } + | /* empty */ { $$ = null; } +; + +encaps_list: + encaps_list encaps_var { push($1, $2); } + | encaps_list encaps_string_part { push($1, $2); } + | encaps_var { init($1); } + | encaps_string_part encaps_var { init($1, $2); } +; + +encaps_string_part: + T_ENCAPSED_AND_WHITESPACE { $$ = Scalar\EncapsedStringPart[$1]; } +; + +encaps_base_var: + T_VARIABLE { $$ = Expr\Variable[parseVar($1)]; } +; + +encaps_var: + encaps_base_var { $$ = $1; } + | encaps_base_var '[' encaps_var_offset ']' { $$ = Expr\ArrayDimFetch[$1, $3]; } + | encaps_base_var T_OBJECT_OPERATOR T_STRING { $$ = Expr\PropertyFetch[$1, $3]; } + | T_DOLLAR_OPEN_CURLY_BRACES expr '}' { $$ = Expr\Variable[$2]; } + | T_DOLLAR_OPEN_CURLY_BRACES T_STRING_VARNAME '}' { $$ = Expr\Variable[$2]; } + | T_DOLLAR_OPEN_CURLY_BRACES T_STRING_VARNAME '[' expr ']' '}' + { $$ = Expr\ArrayDimFetch[Expr\Variable[$2], $4]; } + | T_CURLY_OPEN variable '}' { $$ = $2; } +; + +encaps_var_offset: + T_STRING { $$ = Scalar\String_[$1]; } + | T_NUM_STRING { $$ = $this->parseNumString($1, attributes()); } + | '-' T_NUM_STRING { $$ = $this->parseNumString('-' . $2, attributes()); } + | T_VARIABLE { $$ = Expr\Variable[parseVar($1)]; } +; + +%% diff --git a/lib/nikic/php-parser/grammar/rebuildParsers.php b/lib/nikic/php-parser/grammar/rebuildParsers.php new file mode 100644 index 000000000..340b0eacd --- /dev/null +++ b/lib/nikic/php-parser/grammar/rebuildParsers.php @@ -0,0 +1,263 @@ + 'Php5', + __DIR__ . '/php7.y' => 'Php7', +]; + +$tokensFile = __DIR__ . '/tokens.y'; +$tokensTemplate = __DIR__ . '/tokens.template'; +$skeletonFile = __DIR__ . '/parser.template'; +$tmpGrammarFile = __DIR__ . '/tmp_parser.phpy'; +$tmpResultFile = __DIR__ . '/tmp_parser.php'; +$resultDir = __DIR__ . '/../lib/PhpParser/Parser'; +$tokensResultsFile = $resultDir . '/Tokens.php'; + +// check for kmyacc.exe binary in this directory, otherwise fall back to global name +$kmyacc = __DIR__ . '/kmyacc.exe'; +if (!file_exists($kmyacc)) { + $kmyacc = 'kmyacc'; +} + +$options = array_flip($argv); +$optionDebug = isset($options['--debug']); +$optionKeepTmpGrammar = isset($options['--keep-tmp-grammar']); + +/////////////////////////////// +/// Utility regex constants /// +/////////////////////////////// + +const LIB = '(?(DEFINE) + (?\'[^\\\\\']*+(?:\\\\.[^\\\\\']*+)*+\') + (?"[^\\\\"]*+(?:\\\\.[^\\\\"]*+)*+") + (?(?&singleQuotedString)|(?&doubleQuotedString)) + (?/\*[^*]*+(?:\*(?!/)[^*]*+)*+\*/) + (?\{[^\'"/{}]*+(?:(?:(?&string)|(?&comment)|(?&code)|/)[^\'"/{}]*+)*+}) +)'; + +const PARAMS = '\[(?[^[\]]*+(?:\[(?¶ms)\][^[\]]*+)*+)\]'; +const ARGS = '\((?[^()]*+(?:\((?&args)\)[^()]*+)*+)\)'; + +/////////////////// +/// Main script /// +/////////////////// + +$tokens = file_get_contents($tokensFile); + +foreach ($grammarFileToName as $grammarFile => $name) { + echo "Building temporary $name grammar file.\n"; + + $grammarCode = file_get_contents($grammarFile); + $grammarCode = str_replace('%tokens', $tokens, $grammarCode); + + $grammarCode = resolveNodes($grammarCode); + $grammarCode = resolveMacros($grammarCode); + $grammarCode = resolveStackAccess($grammarCode); + + file_put_contents($tmpGrammarFile, $grammarCode); + + $additionalArgs = $optionDebug ? '-t -v' : ''; + + echo "Building $name parser.\n"; + $output = trim(shell_exec("$kmyacc $additionalArgs -l -m $skeletonFile -p $name $tmpGrammarFile 2>&1")); + echo "Output: \"$output\"\n"; + + $resultCode = file_get_contents($tmpResultFile); + $resultCode = removeTrailingWhitespace($resultCode); + + ensureDirExists($resultDir); + file_put_contents("$resultDir/$name.php", $resultCode); + unlink($tmpResultFile); + + echo "Building token definition.\n"; + $output = trim(shell_exec("$kmyacc -l -m $tokensTemplate $tmpGrammarFile 2>&1")); + assert($output === ''); + rename($tmpResultFile, $tokensResultsFile); + + if (!$optionKeepTmpGrammar) { + unlink($tmpGrammarFile); + } +} + +/////////////////////////////// +/// Preprocessing functions /// +/////////////////////////////// + +function resolveNodes($code) { + return preg_replace_callback( + '~\b(?[A-Z][a-zA-Z_\\\\]++)\s*' . PARAMS . '~', + function($matches) { + // recurse + $matches['params'] = resolveNodes($matches['params']); + + $params = magicSplit( + '(?:' . PARAMS . '|' . ARGS . ')(*SKIP)(*FAIL)|,', + $matches['params'] + ); + + $paramCode = ''; + foreach ($params as $param) { + $paramCode .= $param . ', '; + } + + return 'new ' . $matches['name'] . '(' . $paramCode . 'attributes())'; + }, + $code + ); +} + +function resolveMacros($code) { + return preg_replace_callback( + '~\b(?)(?!array\()(?[a-z][A-Za-z]++)' . ARGS . '~', + function($matches) { + // recurse + $matches['args'] = resolveMacros($matches['args']); + + $name = $matches['name']; + $args = magicSplit( + '(?:' . PARAMS . '|' . ARGS . ')(*SKIP)(*FAIL)|,', + $matches['args'] + ); + + if ('attributes' == $name) { + assertArgs(0, $args, $name); + return '$this->startAttributeStack[#1] + $this->endAttributes'; + } + + if ('stackAttributes' == $name) { + assertArgs(1, $args, $name); + return '$this->startAttributeStack[' . $args[0] . ']' + . ' + $this->endAttributeStack[' . $args[0] . ']'; + } + + if ('init' == $name) { + return '$$ = array(' . implode(', ', $args) . ')'; + } + + if ('push' == $name) { + assertArgs(2, $args, $name); + + return $args[0] . '[] = ' . $args[1] . '; $$ = ' . $args[0]; + } + + if ('pushNormalizing' == $name) { + assertArgs(2, $args, $name); + + return 'if (is_array(' . $args[1] . ')) { $$ = array_merge(' . $args[0] . ', ' . $args[1] . '); }' + . ' else { ' . $args[0] . '[] = ' . $args[1] . '; $$ = ' . $args[0] . '; }'; + } + + if ('toArray' == $name) { + assertArgs(1, $args, $name); + + return 'is_array(' . $args[0] . ') ? ' . $args[0] . ' : array(' . $args[0] . ')'; + } + + if ('parseVar' == $name) { + assertArgs(1, $args, $name); + + return 'substr(' . $args[0] . ', 1)'; + } + + if ('parseEncapsed' == $name) { + assertArgs(3, $args, $name); + + return 'foreach (' . $args[0] . ' as $s) { if ($s instanceof Node\Scalar\EncapsedStringPart) {' + . ' $s->value = Node\Scalar\String_::parseEscapeSequences($s->value, ' . $args[1] . ', ' . $args[2] . '); } }'; + } + + if ('parseEncapsedDoc' == $name) { + assertArgs(2, $args, $name); + + return 'foreach (' . $args[0] . ' as $s) { if ($s instanceof Node\Scalar\EncapsedStringPart) {' + . ' $s->value = Node\Scalar\String_::parseEscapeSequences($s->value, null, ' . $args[1] . '); } }' + . ' $s->value = preg_replace(\'~(\r\n|\n|\r)\z~\', \'\', $s->value);' + . ' if (\'\' === $s->value) array_pop(' . $args[0] . ');'; + } + + if ('makeNop' == $name) { + assertArgs(2, $args, $name); + + return '$startAttributes = ' . $args[1] . ';' + . ' if (isset($startAttributes[\'comments\']))' + . ' { ' . $args[0] . ' = new Stmt\Nop([\'comments\' => $startAttributes[\'comments\']]); }' + . ' else { ' . $args[0] . ' = null; }'; + } + + if ('strKind' == $name) { + assertArgs(1, $args, $name); + + return '(' . $args[0] . '[0] === "\'" || (' . $args[0] . '[1] === "\'" && ' + . '(' . $args[0] . '[0] === \'b\' || ' . $args[0] . '[0] === \'B\')) ' + . '? Scalar\String_::KIND_SINGLE_QUOTED : Scalar\String_::KIND_DOUBLE_QUOTED)'; + } + + if ('setDocStringAttrs' == $name) { + assertArgs(2, $args, $name); + + return $args[0] . '[\'kind\'] = strpos(' . $args[1] . ', "\'") === false ' + . '? Scalar\String_::KIND_HEREDOC : Scalar\String_::KIND_NOWDOC; ' + . 'preg_match(\'/\A[bB]?<<<[ \t]*[\\\'"]?([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)[\\\'"]?(?:\r\n|\n|\r)\z/\', ' . $args[1] . ', $matches); ' + . $args[0] . '[\'docLabel\'] = $matches[1];'; + } + + if ('prependLeadingComments' == $name) { + assertArgs(1, $args, $name); + + return '$attrs = $this->startAttributeStack[#1]; $stmts = ' . $args[0] . '; ' + . 'if (!empty($attrs[\'comments\'])) {' + . '$stmts[0]->setAttribute(\'comments\', ' + . 'array_merge($attrs[\'comments\'], $stmts[0]->getAttribute(\'comments\', []))); }'; + } + + return $matches[0]; + }, + $code + ); +} + +function assertArgs($num, $args, $name) { + if ($num != count($args)) { + die('Wrong argument count for ' . $name . '().'); + } +} + +function resolveStackAccess($code) { + $code = preg_replace('/\$\d+/', '$this->semStack[$0]', $code); + $code = preg_replace('/#(\d+)/', '$$1', $code); + return $code; +} + +function removeTrailingWhitespace($code) { + $lines = explode("\n", $code); + $lines = array_map('rtrim', $lines); + return implode("\n", $lines); +} + +function ensureDirExists($dir) { + if (!is_dir($dir)) { + mkdir($dir, 0777, true); + } +} + +////////////////////////////// +/// Regex helper functions /// +////////////////////////////// + +function regex($regex) { + return '~' . LIB . '(?:' . str_replace('~', '\~', $regex) . ')~'; +} + +function magicSplit($regex, $string) { + $pieces = preg_split(regex('(?:(?&string)|(?&comment)|(?&code))(*SKIP)(*FAIL)|' . $regex), $string); + + foreach ($pieces as &$piece) { + $piece = trim($piece); + } + + if ($pieces === ['']) { + return []; + } + + return $pieces; +} diff --git a/lib/nikic/php-parser/grammar/tokens.template b/lib/nikic/php-parser/grammar/tokens.template new file mode 100644 index 000000000..ba4e4901c --- /dev/null +++ b/lib/nikic/php-parser/grammar/tokens.template @@ -0,0 +1,17 @@ +semValue +#semval($,%t) $this->semValue +#semval(%n) $this->stackPos-(%l-%n) +#semval(%n,%t) $this->stackPos-(%l-%n) + +namespace PhpParser\Parser; +#include; + +/* GENERATED file based on grammar/tokens.y */ +final class Tokens +{ +#tokenval + const %s = %n; +#endtokenval +} diff --git a/lib/nikic/php-parser/grammar/tokens.y b/lib/nikic/php-parser/grammar/tokens.y new file mode 100644 index 000000000..2b54f80b4 --- /dev/null +++ b/lib/nikic/php-parser/grammar/tokens.y @@ -0,0 +1,113 @@ +/* We currently rely on the token ID mapping to be the same between PHP 5 and PHP 7 - so the same lexer can be used for + * both. This is enforced by sharing this token file. */ + +%left T_INCLUDE T_INCLUDE_ONCE T_EVAL T_REQUIRE T_REQUIRE_ONCE +%left ',' +%left T_LOGICAL_OR +%left T_LOGICAL_XOR +%left T_LOGICAL_AND +%right T_PRINT +%right T_YIELD +%right T_DOUBLE_ARROW +%right T_YIELD_FROM +%left '=' T_PLUS_EQUAL T_MINUS_EQUAL T_MUL_EQUAL T_DIV_EQUAL T_CONCAT_EQUAL T_MOD_EQUAL T_AND_EQUAL T_OR_EQUAL T_XOR_EQUAL T_SL_EQUAL T_SR_EQUAL T_POW_EQUAL +%left '?' ':' +%right T_COALESCE +%left T_BOOLEAN_OR +%left T_BOOLEAN_AND +%left '|' +%left '^' +%left '&' +%nonassoc T_IS_EQUAL T_IS_NOT_EQUAL T_IS_IDENTICAL T_IS_NOT_IDENTICAL T_SPACESHIP +%nonassoc '<' T_IS_SMALLER_OR_EQUAL '>' T_IS_GREATER_OR_EQUAL +%left T_SL T_SR +%left '+' '-' '.' +%left '*' '/' '%' +%right '!' +%nonassoc T_INSTANCEOF +%right '~' T_INC T_DEC T_INT_CAST T_DOUBLE_CAST T_STRING_CAST T_ARRAY_CAST T_OBJECT_CAST T_BOOL_CAST T_UNSET_CAST '@' +%right T_POW +%right '[' +%nonassoc T_NEW T_CLONE +%token T_EXIT +%token T_IF +%left T_ELSEIF +%left T_ELSE +%left T_ENDIF +%token T_LNUMBER +%token T_DNUMBER +%token T_STRING +%token T_STRING_VARNAME +%token T_VARIABLE +%token T_NUM_STRING +%token T_INLINE_HTML +%token T_CHARACTER +%token T_BAD_CHARACTER +%token T_ENCAPSED_AND_WHITESPACE +%token T_CONSTANT_ENCAPSED_STRING +%token T_ECHO +%token T_DO +%token T_WHILE +%token T_ENDWHILE +%token T_FOR +%token T_ENDFOR +%token T_FOREACH +%token T_ENDFOREACH +%token T_DECLARE +%token T_ENDDECLARE +%token T_AS +%token T_SWITCH +%token T_ENDSWITCH +%token T_CASE +%token T_DEFAULT +%token T_BREAK +%token T_CONTINUE +%token T_GOTO +%token T_FUNCTION +%token T_CONST +%token T_RETURN +%token T_TRY +%token T_CATCH +%token T_FINALLY +%token T_THROW +%token T_USE +%token T_INSTEADOF +%token T_GLOBAL +%right T_STATIC T_ABSTRACT T_FINAL T_PRIVATE T_PROTECTED T_PUBLIC +%token T_VAR +%token T_UNSET +%token T_ISSET +%token T_EMPTY +%token T_HALT_COMPILER +%token T_CLASS +%token T_TRAIT +%token T_INTERFACE +%token T_EXTENDS +%token T_IMPLEMENTS +%token T_OBJECT_OPERATOR +%token T_DOUBLE_ARROW +%token T_LIST +%token T_ARRAY +%token T_CALLABLE +%token T_CLASS_C +%token T_TRAIT_C +%token T_METHOD_C +%token T_FUNC_C +%token T_LINE +%token T_FILE +%token T_COMMENT +%token T_DOC_COMMENT +%token T_OPEN_TAG +%token T_OPEN_TAG_WITH_ECHO +%token T_CLOSE_TAG +%token T_WHITESPACE +%token T_START_HEREDOC +%token T_END_HEREDOC +%token T_DOLLAR_OPEN_CURLY_BRACES +%token T_CURLY_OPEN +%token T_PAAMAYIM_NEKUDOTAYIM +%token T_NAMESPACE +%token T_NS_C +%token T_DIR +%token T_NS_SEPARATOR +%token T_ELLIPSIS diff --git a/lib/nikic/php-parser/lib/PhpParser/Autoloader.php b/lib/nikic/php-parser/lib/PhpParser/Autoloader.php new file mode 100644 index 000000000..809a06ed8 --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Autoloader.php @@ -0,0 +1,40 @@ +name = $name; + } + + /** + * Extends a class. + * + * @param Name|string $class Name of class to extend + * + * @return $this The builder instance (for fluid interface) + */ + public function extend($class) { + $this->extends = $this->normalizeName($class); + + return $this; + } + + /** + * Implements one or more interfaces. + * + * @param Name|string ...$interfaces Names of interfaces to implement + * + * @return $this The builder instance (for fluid interface) + */ + public function implement() { + foreach (func_get_args() as $interface) { + $this->implements[] = $this->normalizeName($interface); + } + + return $this; + } + + /** + * Makes the class abstract. + * + * @return $this The builder instance (for fluid interface) + */ + public function makeAbstract() { + $this->setModifier(Stmt\Class_::MODIFIER_ABSTRACT); + + return $this; + } + + /** + * Makes the class final. + * + * @return $this The builder instance (for fluid interface) + */ + public function makeFinal() { + $this->setModifier(Stmt\Class_::MODIFIER_FINAL); + + return $this; + } + + /** + * Adds a statement. + * + * @param Stmt|PhpParser\Builder $stmt The statement to add + * + * @return $this The builder instance (for fluid interface) + */ + public function addStmt($stmt) { + $stmt = $this->normalizeNode($stmt); + + $targets = array( + 'Stmt_TraitUse' => &$this->uses, + 'Stmt_ClassConst' => &$this->constants, + 'Stmt_Property' => &$this->properties, + 'Stmt_ClassMethod' => &$this->methods, + ); + + $type = $stmt->getType(); + if (!isset($targets[$type])) { + throw new \LogicException(sprintf('Unexpected node of type "%s"', $type)); + } + + $targets[$type][] = $stmt; + + return $this; + } + + /** + * Returns the built class node. + * + * @return Stmt\Class_ The built class node + */ + public function getNode() { + return new Stmt\Class_($this->name, array( + 'flags' => $this->flags, + 'extends' => $this->extends, + 'implements' => $this->implements, + 'stmts' => array_merge($this->uses, $this->constants, $this->properties, $this->methods), + ), $this->attributes); + } +} \ No newline at end of file diff --git a/lib/nikic/php-parser/lib/PhpParser/Builder/Declaration.php b/lib/nikic/php-parser/lib/PhpParser/Builder/Declaration.php new file mode 100644 index 000000000..30a1937f9 --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Builder/Declaration.php @@ -0,0 +1,42 @@ +addStmt($stmt); + } + + return $this; + } + + /** + * Sets doc comment for the declaration. + * + * @param PhpParser\Comment\Doc|string $docComment Doc comment to set + * + * @return $this The builder instance (for fluid interface) + */ + public function setDocComment($docComment) { + $this->attributes['comments'] = array( + $this->normalizeDocComment($docComment) + ); + + return $this; + } +} \ No newline at end of file diff --git a/lib/nikic/php-parser/lib/PhpParser/Builder/FunctionLike.php b/lib/nikic/php-parser/lib/PhpParser/Builder/FunctionLike.php new file mode 100644 index 000000000..28a2ea618 --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Builder/FunctionLike.php @@ -0,0 +1,75 @@ +returnByRef = true; + + return $this; + } + + /** + * Adds a parameter. + * + * @param Node\Param|Param $param The parameter to add + * + * @return $this The builder instance (for fluid interface) + */ + public function addParam($param) { + $param = $this->normalizeNode($param); + + if (!$param instanceof Node\Param) { + throw new \LogicException(sprintf('Expected parameter node, got "%s"', $param->getType())); + } + + $this->params[] = $param; + + return $this; + } + + /** + * Adds multiple parameters. + * + * @param array $params The parameters to add + * + * @return $this The builder instance (for fluid interface) + */ + public function addParams(array $params) { + foreach ($params as $param) { + $this->addParam($param); + } + + return $this; + } + + /** + * Sets the return type for PHP 7. + * + * @param string|Node\Name|Node\NullableType $type One of array, callable, string, int, float, bool, iterable, + * or a class/interface name. + * + * @return $this The builder instance (for fluid interface) + */ + public function setReturnType($type) + { + $this->returnType = $this->normalizeType($type); + + return $this; + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/Builder/Function_.php b/lib/nikic/php-parser/lib/PhpParser/Builder/Function_.php new file mode 100644 index 000000000..228bdfaa2 --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Builder/Function_.php @@ -0,0 +1,49 @@ +name = $name; + } + + /** + * Adds a statement. + * + * @param Node|PhpParser\Builder $stmt The statement to add + * + * @return $this The builder instance (for fluid interface) + */ + public function addStmt($stmt) { + $this->stmts[] = $this->normalizeNode($stmt); + + return $this; + } + + /** + * Returns the built function node. + * + * @return Stmt\Function_ The built function node + */ + public function getNode() { + return new Stmt\Function_($this->name, array( + 'byRef' => $this->returnByRef, + 'params' => $this->params, + 'returnType' => $this->returnType, + 'stmts' => $this->stmts, + ), $this->attributes); + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/Builder/Interface_.php b/lib/nikic/php-parser/lib/PhpParser/Builder/Interface_.php new file mode 100644 index 000000000..8ebb292a5 --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Builder/Interface_.php @@ -0,0 +1,80 @@ +name = $name; + } + + /** + * Extends one or more interfaces. + * + * @param Name|string ...$interfaces Names of interfaces to extend + * + * @return $this The builder instance (for fluid interface) + */ + public function extend() { + foreach (func_get_args() as $interface) { + $this->extends[] = $this->normalizeName($interface); + } + + return $this; + } + + /** + * Adds a statement. + * + * @param Stmt|PhpParser\Builder $stmt The statement to add + * + * @return $this The builder instance (for fluid interface) + */ + public function addStmt($stmt) { + $stmt = $this->normalizeNode($stmt); + + $type = $stmt->getType(); + switch ($type) { + case 'Stmt_ClassConst': + $this->constants[] = $stmt; + break; + + case 'Stmt_ClassMethod': + // we erase all statements in the body of an interface method + $stmt->stmts = null; + $this->methods[] = $stmt; + break; + + default: + throw new \LogicException(sprintf('Unexpected node of type "%s"', $type)); + } + + return $this; + } + + /** + * Returns the built interface node. + * + * @return Stmt\Interface_ The built interface node + */ + public function getNode() { + return new Stmt\Interface_($this->name, array( + 'extends' => $this->extends, + 'stmts' => array_merge($this->constants, $this->methods), + ), $this->attributes); + } +} \ No newline at end of file diff --git a/lib/nikic/php-parser/lib/PhpParser/Builder/Method.php b/lib/nikic/php-parser/lib/PhpParser/Builder/Method.php new file mode 100644 index 000000000..1ed75eeda --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Builder/Method.php @@ -0,0 +1,128 @@ +name = $name; + } + + /** + * Makes the method public. + * + * @return $this The builder instance (for fluid interface) + */ + public function makePublic() { + $this->setModifier(Stmt\Class_::MODIFIER_PUBLIC); + + return $this; + } + + /** + * Makes the method protected. + * + * @return $this The builder instance (for fluid interface) + */ + public function makeProtected() { + $this->setModifier(Stmt\Class_::MODIFIER_PROTECTED); + + return $this; + } + + /** + * Makes the method private. + * + * @return $this The builder instance (for fluid interface) + */ + public function makePrivate() { + $this->setModifier(Stmt\Class_::MODIFIER_PRIVATE); + + return $this; + } + + /** + * Makes the method static. + * + * @return $this The builder instance (for fluid interface) + */ + public function makeStatic() { + $this->setModifier(Stmt\Class_::MODIFIER_STATIC); + + return $this; + } + + /** + * Makes the method abstract. + * + * @return $this The builder instance (for fluid interface) + */ + public function makeAbstract() { + if (!empty($this->stmts)) { + throw new \LogicException('Cannot make method with statements abstract'); + } + + $this->setModifier(Stmt\Class_::MODIFIER_ABSTRACT); + $this->stmts = null; // abstract methods don't have statements + + return $this; + } + + /** + * Makes the method final. + * + * @return $this The builder instance (for fluid interface) + */ + public function makeFinal() { + $this->setModifier(Stmt\Class_::MODIFIER_FINAL); + + return $this; + } + + /** + * Adds a statement. + * + * @param Node|PhpParser\Builder $stmt The statement to add + * + * @return $this The builder instance (for fluid interface) + */ + public function addStmt($stmt) { + if (null === $this->stmts) { + throw new \LogicException('Cannot add statements to an abstract method'); + } + + $this->stmts[] = $this->normalizeNode($stmt); + + return $this; + } + + /** + * Returns the built method node. + * + * @return Stmt\ClassMethod The built method node + */ + public function getNode() { + return new Stmt\ClassMethod($this->name, array( + 'flags' => $this->flags, + 'byRef' => $this->returnByRef, + 'params' => $this->params, + 'returnType' => $this->returnType, + 'stmts' => $this->stmts, + ), $this->attributes); + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/Builder/Namespace_.php b/lib/nikic/php-parser/lib/PhpParser/Builder/Namespace_.php new file mode 100644 index 000000000..fe636c4ff --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Builder/Namespace_.php @@ -0,0 +1,44 @@ +name = null !== $name ? $this->normalizeName($name) : null; + } + + /** + * Adds a statement. + * + * @param Node|PhpParser\Builder $stmt The statement to add + * + * @return $this The builder instance (for fluid interface) + */ + public function addStmt($stmt) { + $this->stmts[] = $this->normalizeNode($stmt); + + return $this; + } + + /** + * Returns the built node. + * + * @return Node The built node + */ + public function getNode() { + return new Stmt\Namespace_($this->name, $this->stmts, $this->attributes); + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/Builder/Param.php b/lib/nikic/php-parser/lib/PhpParser/Builder/Param.php new file mode 100644 index 000000000..c029e748b --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Builder/Param.php @@ -0,0 +1,91 @@ +name = $name; + } + + /** + * Sets default value for the parameter. + * + * @param mixed $value Default value to use + * + * @return $this The builder instance (for fluid interface) + */ + public function setDefault($value) { + $this->default = $this->normalizeValue($value); + + return $this; + } + + /** + * Sets type hint for the parameter. + * + * @param string|Node\Name|Node\NullableType $type Type hint to use + * + * @return $this The builder instance (for fluid interface) + */ + public function setTypeHint($type) { + $this->type = $this->normalizeType($type); + if ($this->type === 'void') { + throw new \LogicException('Parameter type cannot be void'); + } + + return $this; + } + + /** + * Make the parameter accept the value by reference. + * + * @return $this The builder instance (for fluid interface) + */ + public function makeByRef() { + $this->byRef = true; + + return $this; + } + + /** + * Make the parameter variadic + * + * @return $this The builder instance (for fluid interface) + */ + public function makeVariadic() { + $this->variadic = true; + + return $this; + } + + /** + * Returns the built parameter node. + * + * @return Node\Param The built parameter node + */ + public function getNode() { + return new Node\Param( + $this->name, $this->default, $this->type, $this->byRef, $this->variadic + ); + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/Builder/Property.php b/lib/nikic/php-parser/lib/PhpParser/Builder/Property.php new file mode 100644 index 000000000..053c851b9 --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Builder/Property.php @@ -0,0 +1,111 @@ +name = $name; + } + + /** + * Makes the property public. + * + * @return $this The builder instance (for fluid interface) + */ + public function makePublic() { + $this->setModifier(Stmt\Class_::MODIFIER_PUBLIC); + + return $this; + } + + /** + * Makes the property protected. + * + * @return $this The builder instance (for fluid interface) + */ + public function makeProtected() { + $this->setModifier(Stmt\Class_::MODIFIER_PROTECTED); + + return $this; + } + + /** + * Makes the property private. + * + * @return $this The builder instance (for fluid interface) + */ + public function makePrivate() { + $this->setModifier(Stmt\Class_::MODIFIER_PRIVATE); + + return $this; + } + + /** + * Makes the property static. + * + * @return $this The builder instance (for fluid interface) + */ + public function makeStatic() { + $this->setModifier(Stmt\Class_::MODIFIER_STATIC); + + return $this; + } + + /** + * Sets default value for the property. + * + * @param mixed $value Default value to use + * + * @return $this The builder instance (for fluid interface) + */ + public function setDefault($value) { + $this->default = $this->normalizeValue($value); + + return $this; + } + + /** + * Sets doc comment for the property. + * + * @param PhpParser\Comment\Doc|string $docComment Doc comment to set + * + * @return $this The builder instance (for fluid interface) + */ + public function setDocComment($docComment) { + $this->attributes = array( + 'comments' => array($this->normalizeDocComment($docComment)) + ); + + return $this; + } + + /** + * Returns the built class node. + * + * @return Stmt\Property The built property node + */ + public function getNode() { + return new Stmt\Property( + $this->flags !== 0 ? $this->flags : Stmt\Class_::MODIFIER_PUBLIC, + array( + new Stmt\PropertyProperty($this->name, $this->default) + ), + $this->attributes + ); + } +} \ No newline at end of file diff --git a/lib/nikic/php-parser/lib/PhpParser/Builder/Trait_.php b/lib/nikic/php-parser/lib/PhpParser/Builder/Trait_.php new file mode 100644 index 000000000..7b004fa96 --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Builder/Trait_.php @@ -0,0 +1,59 @@ +name = $name; + } + + /** + * Adds a statement. + * + * @param Stmt|PhpParser\Builder $stmt The statement to add + * + * @return $this The builder instance (for fluid interface) + */ + public function addStmt($stmt) { + $stmt = $this->normalizeNode($stmt); + + if ($stmt instanceof Stmt\Property) { + $this->properties[] = $stmt; + } else if ($stmt instanceof Stmt\ClassMethod) { + $this->methods[] = $stmt; + } else if ($stmt instanceof Stmt\TraitUse) { + $this->uses[] = $stmt; + } else { + throw new \LogicException(sprintf('Unexpected node of type "%s"', $stmt->getType())); + } + + return $this; + } + + /** + * Returns the built trait node. + * + * @return Stmt\Trait_ The built interface node + */ + public function getNode() { + return new Stmt\Trait_( + $this->name, array( + 'stmts' => array_merge($this->uses, $this->properties, $this->methods) + ), $this->attributes + ); + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/Builder/Use_.php b/lib/nikic/php-parser/lib/PhpParser/Builder/Use_.php new file mode 100644 index 000000000..f6d3a856f --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Builder/Use_.php @@ -0,0 +1,58 @@ +name = $this->normalizeName($name); + $this->type = $type; + } + + /** + * Sets alias for used name. + * + * @param string $alias Alias to use (last component of full name by default) + * + * @return $this The builder instance (for fluid interface) + */ + protected function as_($alias) { + $this->alias = $alias; + return $this; + } + public function __call($name, $args) { + if (method_exists($this, $name . '_')) { + return call_user_func_array(array($this, $name . '_'), $args); + } + + throw new \LogicException(sprintf('Method "%s" does not exist', $name)); + } + + /** + * Returns the built node. + * + * @return Node The built node + */ + public function getNode() { + $alias = null !== $this->alias ? $this->alias : $this->name->getLast(); + return new Stmt\Use_(array( + new Stmt\UseUse($this->name, $alias) + ), $this->type); + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/BuilderAbstract.php b/lib/nikic/php-parser/lib/PhpParser/BuilderAbstract.php new file mode 100644 index 000000000..e353963e6 --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/BuilderAbstract.php @@ -0,0 +1,175 @@ +getNode(); + } elseif ($node instanceof Node) { + return $node; + } + + throw new \LogicException('Expected node or builder object'); + } + + /** + * Normalizes a name: Converts plain string names to PhpParser\Node\Name. + * + * @param Name|string $name The name to normalize + * + * @return Name The normalized name + */ + protected function normalizeName($name) { + if ($name instanceof Name) { + return $name; + } elseif (is_string($name)) { + if (!$name) { + throw new \LogicException('Name cannot be empty'); + } + + if ($name[0] == '\\') { + return new Name\FullyQualified(substr($name, 1)); + } elseif (0 === strpos($name, 'namespace\\')) { + return new Name\Relative(substr($name, strlen('namespace\\'))); + } else { + return new Name($name); + } + } + + throw new \LogicException('Name must be a string or an instance of PhpParser\Node\Name'); + } + + /** + * Normalizes a type: Converts plain-text type names into proper AST representation. + * + * In particular, builtin types are left as strings, custom types become Names and nullables + * are wrapped in NullableType nodes. + * + * @param Name|string|NullableType $type The type to normalize + * + * @return Name|string|NullableType The normalized type + */ + protected function normalizeType($type) { + if (!is_string($type)) { + if (!$type instanceof Name && !$type instanceof NullableType) { + throw new \LogicException( + 'Type must be a string, or an instance of Name or NullableType'); + } + return $type; + } + + $nullable = false; + if (strlen($type) > 0 && $type[0] === '?') { + $nullable = true; + $type = substr($type, 1); + } + + $builtinTypes = array( + 'array', 'callable', 'string', 'int', 'float', 'bool', 'iterable', 'void', 'object' + ); + + $lowerType = strtolower($type); + if (in_array($lowerType, $builtinTypes)) { + $type = $lowerType; + } else { + $type = $this->normalizeName($type); + } + + if ($nullable && $type === 'void') { + throw new \LogicException('void type cannot be nullable'); + } + + return $nullable ? new Node\NullableType($type) : $type; + } + + /** + * Normalizes a value: Converts nulls, booleans, integers, + * floats, strings and arrays into their respective nodes + * + * @param mixed $value The value to normalize + * + * @return Expr The normalized value + */ + protected function normalizeValue($value) { + if ($value instanceof Node) { + return $value; + } elseif (is_null($value)) { + return new Expr\ConstFetch( + new Name('null') + ); + } elseif (is_bool($value)) { + return new Expr\ConstFetch( + new Name($value ? 'true' : 'false') + ); + } elseif (is_int($value)) { + return new Scalar\LNumber($value); + } elseif (is_float($value)) { + return new Scalar\DNumber($value); + } elseif (is_string($value)) { + return new Scalar\String_($value); + } elseif (is_array($value)) { + $items = array(); + $lastKey = -1; + foreach ($value as $itemKey => $itemValue) { + // for consecutive, numeric keys don't generate keys + if (null !== $lastKey && ++$lastKey === $itemKey) { + $items[] = new Expr\ArrayItem( + $this->normalizeValue($itemValue) + ); + } else { + $lastKey = null; + $items[] = new Expr\ArrayItem( + $this->normalizeValue($itemValue), + $this->normalizeValue($itemKey) + ); + } + } + + return new Expr\Array_($items); + } else { + throw new \LogicException('Invalid value'); + } + } + + /** + * Normalizes a doc comment: Converts plain strings to PhpParser\Comment\Doc. + * + * @param Comment\Doc|string $docComment The doc comment to normalize + * + * @return Comment\Doc The normalized doc comment + */ + protected function normalizeDocComment($docComment) { + if ($docComment instanceof Comment\Doc) { + return $docComment; + } else if (is_string($docComment)) { + return new Comment\Doc($docComment); + } else { + throw new \LogicException('Doc comment must be a string or an instance of PhpParser\Comment\Doc'); + } + } + + /** + * Sets a modifier in the $this->type property. + * + * @param int $modifier Modifier to set + */ + protected function setModifier($modifier) { + Stmt\Class_::verifyModifier($this->flags, $modifier); + $this->flags |= $modifier; + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/BuilderFactory.php b/lib/nikic/php-parser/lib/PhpParser/BuilderFactory.php new file mode 100644 index 000000000..42c7f612c --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/BuilderFactory.php @@ -0,0 +1,127 @@ +text = $text; + $this->line = $startLine; + $this->filePos = $startFilePos; + } + + /** + * Gets the comment text. + * + * @return string The comment text (including comment delimiters like /*) + */ + public function getText() { + return $this->text; + } + + /** + * Gets the line number the comment started on. + * + * @return int Line number + */ + public function getLine() { + return $this->line; + } + + /** + * Gets the file offset the comment started on. + * + * @return int File offset + */ + public function getFilePos() { + return $this->filePos; + } + + /** + * Gets the comment text. + * + * @return string The comment text (including comment delimiters like /*) + */ + public function __toString() { + return $this->text; + } + + /** + * Gets the reformatted comment text. + * + * "Reformatted" here means that we try to clean up the whitespace at the + * starts of the lines. This is necessary because we receive the comments + * without trailing whitespace on the first line, but with trailing whitespace + * on all subsequent lines. + * + * @return mixed|string + */ + public function getReformattedText() { + $text = trim($this->text); + $newlinePos = strpos($text, "\n"); + if (false === $newlinePos) { + // Single line comments don't need further processing + return $text; + } elseif (preg_match('((*BSR_ANYCRLF)(*ANYCRLF)^.*(?:\R\s+\*.*)+$)', $text)) { + // Multi line comment of the type + // + // /* + // * Some text. + // * Some more text. + // */ + // + // is handled by replacing the whitespace sequences before the * by a single space + return preg_replace('(^\s+\*)m', ' *', $this->text); + } elseif (preg_match('(^/\*\*?\s*[\r\n])', $text) && preg_match('(\n(\s*)\*/$)', $text, $matches)) { + // Multi line comment of the type + // + // /* + // Some text. + // Some more text. + // */ + // + // is handled by removing the whitespace sequence on the line before the closing + // */ on all lines. So if the last line is " */", then " " is removed at the + // start of all lines. + return preg_replace('(^' . preg_quote($matches[1]) . ')m', '', $text); + } elseif (preg_match('(^/\*\*?\s*(?!\s))', $text, $matches)) { + // Multi line comment of the type + // + // /* Some text. + // Some more text. + // Indented text. + // Even more text. */ + // + // is handled by removing the difference between the shortest whitespace prefix on all + // lines and the length of the "/* " opening sequence. + $prefixLen = $this->getShortestWhitespacePrefixLen(substr($text, $newlinePos + 1)); + $removeLen = $prefixLen - strlen($matches[0]); + return preg_replace('(^\s{' . $removeLen . '})m', '', $text); + } + + // No idea how to format this comment, so simply return as is + return $text; + } + + private function getShortestWhitespacePrefixLen($str) { + $lines = explode("\n", $str); + $shortestPrefixLen = INF; + foreach ($lines as $line) { + preg_match('(^\s*)', $line, $matches); + $prefixLen = strlen($matches[0]); + if ($prefixLen < $shortestPrefixLen) { + $shortestPrefixLen = $prefixLen; + } + } + return $shortestPrefixLen; + } + + public function jsonSerialize() { + // Technically not a node, but we make it look like one anyway + $type = $this instanceof Comment\Doc ? 'Comment_Doc' : 'Comment'; + return [ + 'nodeType' => $type, + 'text' => $this->text, + 'line' => $this->line, + 'filePos' => $this->filePos, + ]; + } +} \ No newline at end of file diff --git a/lib/nikic/php-parser/lib/PhpParser/Comment/Doc.php b/lib/nikic/php-parser/lib/PhpParser/Comment/Doc.php new file mode 100644 index 000000000..24fc6c9ec --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Comment/Doc.php @@ -0,0 +1,7 @@ +rawMessage = (string) $message; + if (is_array($attributes)) { + $this->attributes = $attributes; + } else { + $this->attributes = array('startLine' => $attributes); + } + $this->updateMessage(); + } + + /** + * Gets the error message + * + * @return string Error message + */ + public function getRawMessage() { + return $this->rawMessage; + } + + /** + * Gets the line the error starts in. + * + * @return int Error start line + */ + public function getStartLine() { + return isset($this->attributes['startLine']) ? $this->attributes['startLine'] : -1; + } + + /** + * Gets the line the error ends in. + * + * @return int Error end line + */ + public function getEndLine() { + return isset($this->attributes['endLine']) ? $this->attributes['endLine'] : -1; + } + + + /** + * Gets the attributes of the node/token the error occurred at. + * + * @return array + */ + public function getAttributes() { + return $this->attributes; + } + + /** + * Sets the attributes of the node/token the error occured at. + * + * @param array $attributes + */ + public function setAttributes(array $attributes) { + $this->attributes = $attributes; + $this->updateMessage(); + } + + /** + * Sets the line of the PHP file the error occurred in. + * + * @param string $message Error message + */ + public function setRawMessage($message) { + $this->rawMessage = (string) $message; + $this->updateMessage(); + } + + /** + * Sets the line the error starts in. + * + * @param int $line Error start line + */ + public function setStartLine($line) { + $this->attributes['startLine'] = (int) $line; + $this->updateMessage(); + } + + /** + * Returns whether the error has start and end column information. + * + * For column information enable the startFilePos and endFilePos in the lexer options. + * + * @return bool + */ + public function hasColumnInfo() { + return isset($this->attributes['startFilePos']) && isset($this->attributes['endFilePos']); + } + + /** + * Gets the start column (1-based) into the line where the error started. + * + * @param string $code Source code of the file + * @return int + */ + public function getStartColumn($code) { + if (!$this->hasColumnInfo()) { + throw new \RuntimeException('Error does not have column information'); + } + + return $this->toColumn($code, $this->attributes['startFilePos']); + } + + /** + * Gets the end column (1-based) into the line where the error ended. + * + * @param string $code Source code of the file + * @return int + */ + public function getEndColumn($code) { + if (!$this->hasColumnInfo()) { + throw new \RuntimeException('Error does not have column information'); + } + + return $this->toColumn($code, $this->attributes['endFilePos']); + } + + public function getMessageWithColumnInfo($code) { + return sprintf( + '%s from %d:%d to %d:%d', $this->getRawMessage(), + $this->getStartLine(), $this->getStartColumn($code), + $this->getEndLine(), $this->getEndColumn($code) + ); + } + + private function toColumn($code, $pos) { + if ($pos > strlen($code)) { + throw new \RuntimeException('Invalid position information'); + } + + $lineStartPos = strrpos($code, "\n", $pos - strlen($code)); + if (false === $lineStartPos) { + $lineStartPos = -1; + } + + return $pos - $lineStartPos; + } + + /** + * Updates the exception message after a change to rawMessage or rawLine. + */ + protected function updateMessage() { + $this->message = $this->rawMessage; + + if (-1 === $this->getStartLine()) { + $this->message .= ' on unknown line'; + } else { + $this->message .= ' on line ' . $this->getStartLine(); + } + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/ErrorHandler.php b/lib/nikic/php-parser/lib/PhpParser/ErrorHandler.php new file mode 100644 index 000000000..fa2c2f8ce --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/ErrorHandler.php @@ -0,0 +1,13 @@ +errors[] = $error; + } + + /** + * Get collected errors. + * + * @return Error[] + */ + public function getErrors() { + return $this->errors; + } + + /** + * Check whether there are any errors. + * + * @return bool + */ + public function hasErrors() { + return !empty($this->errors); + } + + /** + * Reset/clear collected errors. + */ + public function clearErrors() { + $this->errors = []; + } +} \ No newline at end of file diff --git a/lib/nikic/php-parser/lib/PhpParser/ErrorHandler/Throwing.php b/lib/nikic/php-parser/lib/PhpParser/ErrorHandler/Throwing.php new file mode 100644 index 000000000..c5a76dd0c --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/ErrorHandler/Throwing.php @@ -0,0 +1,18 @@ +tokenMap = $this->createTokenMap(); + + // map of tokens to drop while lexing (the map is only used for isset lookup, + // that's why the value is simply set to 1; the value is never actually used.) + $this->dropTokens = array_fill_keys( + array(T_WHITESPACE, T_OPEN_TAG, T_COMMENT, T_DOC_COMMENT), 1 + ); + + // the usedAttributes member is a map of the used attribute names to a dummy + // value (here "true") + $options += array( + 'usedAttributes' => array('comments', 'startLine', 'endLine'), + ); + $this->usedAttributes = array_fill_keys($options['usedAttributes'], true); + } + + /** + * Initializes the lexer for lexing the provided source code. + * + * This function does not throw if lexing errors occur. Instead, errors may be retrieved using + * the getErrors() method. + * + * @param string $code The source code to lex + * @param ErrorHandler|null $errorHandler Error handler to use for lexing errors. Defaults to + * ErrorHandler\Throwing + */ + public function startLexing($code, ErrorHandler $errorHandler = null) { + if (null === $errorHandler) { + $errorHandler = new ErrorHandler\Throwing(); + } + + $this->code = $code; // keep the code around for __halt_compiler() handling + $this->pos = -1; + $this->line = 1; + $this->filePos = 0; + + // If inline HTML occurs without preceding code, treat it as if it had a leading newline. + // This ensures proper composability, because having a newline is the "safe" assumption. + $this->prevCloseTagHasNewline = true; + + $scream = ini_set('xdebug.scream', '0'); + + $this->resetErrors(); + $this->tokens = @token_get_all($code); + $this->handleErrors($errorHandler); + + if (false !== $scream) { + ini_set('xdebug.scream', $scream); + } + } + + protected function resetErrors() { + if (function_exists('error_clear_last')) { + error_clear_last(); + } else { + // set error_get_last() to defined state by forcing an undefined variable error + set_error_handler(function() { return false; }, 0); + @$undefinedVariable; + restore_error_handler(); + } + } + + private function handleInvalidCharacterRange($start, $end, $line, ErrorHandler $errorHandler) { + for ($i = $start; $i < $end; $i++) { + $chr = $this->code[$i]; + if ($chr === 'b' || $chr === 'B') { + // HHVM does not treat b" tokens correctly, so ignore these + continue; + } + + if ($chr === "\0") { + // PHP cuts error message after null byte, so need special case + $errorMsg = 'Unexpected null byte'; + } else { + $errorMsg = sprintf( + 'Unexpected character "%s" (ASCII %d)', $chr, ord($chr) + ); + } + + $errorHandler->handleError(new Error($errorMsg, [ + 'startLine' => $line, + 'endLine' => $line, + 'startFilePos' => $i, + 'endFilePos' => $i, + ])); + } + } + + private function isUnterminatedComment($token) { + return ($token[0] === T_COMMENT || $token[0] === T_DOC_COMMENT) + && substr($token[1], 0, 2) === '/*' + && substr($token[1], -2) !== '*/'; + } + + private function errorMayHaveOccurred() { + if (defined('HHVM_VERSION')) { + // In HHVM token_get_all() does not throw warnings, so we need to conservatively + // assume that an error occurred + return true; + } + + $error = error_get_last(); + return null !== $error + && false === strpos($error['message'], 'Undefined variable'); + } + + protected function handleErrors(ErrorHandler $errorHandler) { + if (!$this->errorMayHaveOccurred()) { + return; + } + + // PHP's error handling for token_get_all() is rather bad, so if we want detailed + // error information we need to compute it ourselves. Invalid character errors are + // detected by finding "gaps" in the token array. Unterminated comments are detected + // by checking if a trailing comment has a "*/" at the end. + + $filePos = 0; + $line = 1; + foreach ($this->tokens as $i => $token) { + $tokenValue = \is_string($token) ? $token : $token[1]; + $tokenLen = \strlen($tokenValue); + + if (substr($this->code, $filePos, $tokenLen) !== $tokenValue) { + // Something is missing, must be an invalid character + $nextFilePos = strpos($this->code, $tokenValue, $filePos); + $this->handleInvalidCharacterRange( + $filePos, $nextFilePos, $line, $errorHandler); + $filePos = $nextFilePos; + } + + $filePos += $tokenLen; + $line += substr_count($tokenValue, "\n"); + } + + if ($filePos !== \strlen($this->code)) { + if (substr($this->code, $filePos, 2) === '/*') { + // Unlike PHP, HHVM will drop unterminated comments entirely + $comment = substr($this->code, $filePos); + $errorHandler->handleError(new Error('Unterminated comment', [ + 'startLine' => $line, + 'endLine' => $line + substr_count($comment, "\n"), + 'startFilePos' => $filePos, + 'endFilePos' => $filePos + \strlen($comment), + ])); + + // Emulate the PHP behavior + $isDocComment = isset($comment[3]) && $comment[3] === '*'; + $this->tokens[] = [$isDocComment ? T_DOC_COMMENT : T_COMMENT, $comment, $line]; + } else { + // Invalid characters at the end of the input + $this->handleInvalidCharacterRange( + $filePos, \strlen($this->code), $line, $errorHandler); + } + return; + } + + if (count($this->tokens) > 0) { + // Check for unterminated comment + $lastToken = $this->tokens[count($this->tokens) - 1]; + if ($this->isUnterminatedComment($lastToken)) { + $errorHandler->handleError(new Error('Unterminated comment', [ + 'startLine' => $line - substr_count($lastToken[1], "\n"), + 'endLine' => $line, + 'startFilePos' => $filePos - \strlen($lastToken[1]), + 'endFilePos' => $filePos, + ])); + } + } + } + + /** + * Fetches the next token. + * + * The available attributes are determined by the 'usedAttributes' option, which can + * be specified in the constructor. The following attributes are supported: + * + * * 'comments' => Array of PhpParser\Comment or PhpParser\Comment\Doc instances, + * representing all comments that occurred between the previous + * non-discarded token and the current one. + * * 'startLine' => Line in which the node starts. + * * 'endLine' => Line in which the node ends. + * * 'startTokenPos' => Offset into the token array of the first token in the node. + * * 'endTokenPos' => Offset into the token array of the last token in the node. + * * 'startFilePos' => Offset into the code string of the first character that is part of the node. + * * 'endFilePos' => Offset into the code string of the last character that is part of the node. + * + * @param mixed $value Variable to store token content in + * @param mixed $startAttributes Variable to store start attributes in + * @param mixed $endAttributes Variable to store end attributes in + * + * @return int Token id + */ + public function getNextToken(&$value = null, &$startAttributes = null, &$endAttributes = null) { + $startAttributes = array(); + $endAttributes = array(); + + while (1) { + if (isset($this->tokens[++$this->pos])) { + $token = $this->tokens[$this->pos]; + } else { + // EOF token with ID 0 + $token = "\0"; + } + + if (isset($this->usedAttributes['startLine'])) { + $startAttributes['startLine'] = $this->line; + } + if (isset($this->usedAttributes['startTokenPos'])) { + $startAttributes['startTokenPos'] = $this->pos; + } + if (isset($this->usedAttributes['startFilePos'])) { + $startAttributes['startFilePos'] = $this->filePos; + } + + if (\is_string($token)) { + $value = $token; + if (isset($token[1])) { + // bug in token_get_all + $this->filePos += 2; + $id = ord('"'); + } else { + $this->filePos += 1; + $id = ord($token); + } + } elseif (!isset($this->dropTokens[$token[0]])) { + $value = $token[1]; + $id = $this->tokenMap[$token[0]]; + if (T_CLOSE_TAG === $token[0]) { + $this->prevCloseTagHasNewline = false !== strpos($token[1], "\n"); + } else if (T_INLINE_HTML === $token[0]) { + $startAttributes['hasLeadingNewline'] = $this->prevCloseTagHasNewline; + } + + $this->line += substr_count($value, "\n"); + $this->filePos += \strlen($value); + } else { + if (T_COMMENT === $token[0] || T_DOC_COMMENT === $token[0]) { + if (isset($this->usedAttributes['comments'])) { + $comment = T_DOC_COMMENT === $token[0] + ? new Comment\Doc($token[1], $this->line, $this->filePos) + : new Comment($token[1], $this->line, $this->filePos); + $startAttributes['comments'][] = $comment; + } + } + + $this->line += substr_count($token[1], "\n"); + $this->filePos += \strlen($token[1]); + continue; + } + + if (isset($this->usedAttributes['endLine'])) { + $endAttributes['endLine'] = $this->line; + } + if (isset($this->usedAttributes['endTokenPos'])) { + $endAttributes['endTokenPos'] = $this->pos; + } + if (isset($this->usedAttributes['endFilePos'])) { + $endAttributes['endFilePos'] = $this->filePos - 1; + } + + return $id; + } + + throw new \RuntimeException('Reached end of lexer loop'); + } + + /** + * Returns the token array for current code. + * + * The token array is in the same format as provided by the + * token_get_all() function and does not discard tokens (i.e. + * whitespace and comments are included). The token position + * attributes are against this token array. + * + * @return array Array of tokens in token_get_all() format + */ + public function getTokens() { + return $this->tokens; + } + + /** + * Handles __halt_compiler() by returning the text after it. + * + * @return string Remaining text + */ + public function handleHaltCompiler() { + // text after T_HALT_COMPILER, still including (); + $textAfter = substr($this->code, $this->filePos); + + // ensure that it is followed by (); + // this simplifies the situation, by not allowing any comments + // in between of the tokens. + if (!preg_match('~^\s*\(\s*\)\s*(?:;|\?>\r?\n?)~', $textAfter, $matches)) { + throw new Error('__HALT_COMPILER must be followed by "();"'); + } + + // prevent the lexer from returning any further tokens + $this->pos = count($this->tokens); + + // return with (); removed + return (string) substr($textAfter, strlen($matches[0])); // (string) converts false to '' + } + + /** + * Creates the token map. + * + * The token map maps the PHP internal token identifiers + * to the identifiers used by the Parser. Additionally it + * maps T_OPEN_TAG_WITH_ECHO to T_ECHO and T_CLOSE_TAG to ';'. + * + * @return array The token map + */ + protected function createTokenMap() { + $tokenMap = array(); + + // 256 is the minimum possible token number, as everything below + // it is an ASCII value + for ($i = 256; $i < 1000; ++$i) { + if (T_DOUBLE_COLON === $i) { + // T_DOUBLE_COLON is equivalent to T_PAAMAYIM_NEKUDOTAYIM + $tokenMap[$i] = Tokens::T_PAAMAYIM_NEKUDOTAYIM; + } elseif(T_OPEN_TAG_WITH_ECHO === $i) { + // T_OPEN_TAG_WITH_ECHO with dropped T_OPEN_TAG results in T_ECHO + $tokenMap[$i] = Tokens::T_ECHO; + } elseif(T_CLOSE_TAG === $i) { + // T_CLOSE_TAG is equivalent to ';' + $tokenMap[$i] = ord(';'); + } elseif ('UNKNOWN' !== $name = token_name($i)) { + if ('T_HASHBANG' === $name) { + // HHVM uses a special token for #! hashbang lines + $tokenMap[$i] = Tokens::T_INLINE_HTML; + } else if (defined($name = Tokens::class . '::' . $name)) { + // Other tokens can be mapped directly + $tokenMap[$i] = constant($name); + } + } + } + + // HHVM uses a special token for numbers that overflow to double + if (defined('T_ONUMBER')) { + $tokenMap[T_ONUMBER] = Tokens::T_DNUMBER; + } + // HHVM also has a separate token for the __COMPILER_HALT_OFFSET__ constant + if (defined('T_COMPILER_HALT_OFFSET')) { + $tokenMap[T_COMPILER_HALT_OFFSET] = Tokens::T_STRING; + } + + return $tokenMap; + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/Lexer/Emulative.php b/lib/nikic/php-parser/lib/PhpParser/Lexer/Emulative.php new file mode 100644 index 000000000..739a328ab --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Lexer/Emulative.php @@ -0,0 +1,174 @@ +newKeywords = array(); + foreach ($newKeywordsPerVersion as $version => $newKeywords) { + if (version_compare(PHP_VERSION, $version, '>=')) { + break; + } + + $this->newKeywords += $newKeywords; + } + + if (version_compare(PHP_VERSION, self::PHP_7_0, '>=')) { + return; + } + $this->tokenMap[self::T_COALESCE] = Tokens::T_COALESCE; + $this->tokenMap[self::T_SPACESHIP] = Tokens::T_SPACESHIP; + $this->tokenMap[self::T_YIELD_FROM] = Tokens::T_YIELD_FROM; + + if (version_compare(PHP_VERSION, self::PHP_5_6, '>=')) { + return; + } + $this->tokenMap[self::T_ELLIPSIS] = Tokens::T_ELLIPSIS; + $this->tokenMap[self::T_POW] = Tokens::T_POW; + $this->tokenMap[self::T_POW_EQUAL] = Tokens::T_POW_EQUAL; + } + + public function startLexing($code, ErrorHandler $errorHandler = null) { + $this->inObjectAccess = false; + + parent::startLexing($code, $errorHandler); + if ($this->requiresEmulation($code)) { + $this->emulateTokens(); + } + } + + /* + * Checks if the code is potentially using features that require emulation. + */ + protected function requiresEmulation($code) { + if (version_compare(PHP_VERSION, self::PHP_7_0, '>=')) { + return false; + } + + if (preg_match('(\?\?|<=>|yield[ \n\r\t]+from)', $code)) { + return true; + } + + if (version_compare(PHP_VERSION, self::PHP_5_6, '>=')) { + return false; + } + + return preg_match('(\.\.\.|(?tokens); $i < $c; ++$i) { + $replace = null; + if (isset($this->tokens[$i + 1])) { + if ($this->tokens[$i] === '?' && $this->tokens[$i + 1] === '?') { + array_splice($this->tokens, $i, 2, array( + array(self::T_COALESCE, '??', $line) + )); + $c--; + continue; + } + if ($this->tokens[$i][0] === T_IS_SMALLER_OR_EQUAL + && $this->tokens[$i + 1] === '>' + ) { + array_splice($this->tokens, $i, 2, array( + array(self::T_SPACESHIP, '<=>', $line) + )); + $c--; + continue; + } + if ($this->tokens[$i] === '*' && $this->tokens[$i + 1] === '*') { + array_splice($this->tokens, $i, 2, array( + array(self::T_POW, '**', $line) + )); + $c--; + continue; + } + if ($this->tokens[$i] === '*' && $this->tokens[$i + 1][0] === T_MUL_EQUAL) { + array_splice($this->tokens, $i, 2, array( + array(self::T_POW_EQUAL, '**=', $line) + )); + $c--; + continue; + } + } + + if (isset($this->tokens[$i + 2])) { + if ($this->tokens[$i][0] === T_YIELD && $this->tokens[$i + 1][0] === T_WHITESPACE + && $this->tokens[$i + 2][0] === T_STRING + && !strcasecmp($this->tokens[$i + 2][1], 'from') + ) { + array_splice($this->tokens, $i, 3, array( + array( + self::T_YIELD_FROM, + $this->tokens[$i][1] . $this->tokens[$i + 1][1] . $this->tokens[$i + 2][1], + $line + ) + )); + $c -= 2; + $line += substr_count($this->tokens[$i][1], "\n"); + continue; + } + if ($this->tokens[$i] === '.' && $this->tokens[$i + 1] === '.' + && $this->tokens[$i + 2] === '.' + ) { + array_splice($this->tokens, $i, 3, array( + array(self::T_ELLIPSIS, '...', $line) + )); + $c -= 2; + continue; + } + } + + if (\is_array($this->tokens[$i])) { + $line += substr_count($this->tokens[$i][1], "\n"); + } + } + } + + public function getNextToken(&$value = null, &$startAttributes = null, &$endAttributes = null) { + $token = parent::getNextToken($value, $startAttributes, $endAttributes); + + // replace new keywords by their respective tokens. This is not done + // if we currently are in an object access (e.g. in $obj->namespace + // "namespace" stays a T_STRING tokens and isn't converted to T_NAMESPACE) + if (Tokens::T_STRING === $token && !$this->inObjectAccess) { + if (isset($this->newKeywords[strtolower($value)])) { + return $this->newKeywords[strtolower($value)]; + } + } else { + // keep track of whether we currently are in an object access (after ->) + $this->inObjectAccess = Tokens::T_OBJECT_OPERATOR === $token; + } + + return $token; + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/Node.php b/lib/nikic/php-parser/lib/PhpParser/Node.php new file mode 100644 index 000000000..6925fd726 --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Node.php @@ -0,0 +1,88 @@ +value = $value; + $this->byRef = $byRef; + $this->unpack = $unpack; + } + + public function getSubNodeNames() { + return array('value', 'byRef', 'unpack'); + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/Node/Const_.php b/lib/nikic/php-parser/lib/PhpParser/Node/Const_.php new file mode 100644 index 000000000..26322d49e --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Node/Const_.php @@ -0,0 +1,30 @@ +name = $name; + $this->value = $value; + } + + public function getSubNodeNames() { + return array('name', 'value'); + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/Node/Expr.php b/lib/nikic/php-parser/lib/PhpParser/Node/Expr.php new file mode 100644 index 000000000..2dae5bfcd --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Node/Expr.php @@ -0,0 +1,9 @@ +var = $var; + $this->dim = $dim; + } + + public function getSubNodeNames() { + return array('var', 'dim'); + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/Node/Expr/ArrayItem.php b/lib/nikic/php-parser/lib/PhpParser/Node/Expr/ArrayItem.php new file mode 100644 index 000000000..de73ef467 --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Node/Expr/ArrayItem.php @@ -0,0 +1,34 @@ +key = $key; + $this->value = $value; + $this->byRef = $byRef; + } + + public function getSubNodeNames() { + return array('key', 'value', 'byRef'); + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/Node/Expr/Array_.php b/lib/nikic/php-parser/lib/PhpParser/Node/Expr/Array_.php new file mode 100644 index 000000000..9151f27d8 --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Node/Expr/Array_.php @@ -0,0 +1,30 @@ +items = $items; + } + + public function getSubNodeNames() { + return array('items'); + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/Node/Expr/Assign.php b/lib/nikic/php-parser/lib/PhpParser/Node/Expr/Assign.php new file mode 100644 index 000000000..1f280ff0c --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Node/Expr/Assign.php @@ -0,0 +1,30 @@ +var = $var; + $this->expr = $expr; + } + + public function getSubNodeNames() { + return array('var', 'expr'); + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp.php b/lib/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp.php new file mode 100644 index 000000000..83540a072 --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp.php @@ -0,0 +1,30 @@ +var = $var; + $this->expr = $expr; + } + + public function getSubNodeNames() { + return array('var', 'expr'); + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/BitwiseAnd.php b/lib/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/BitwiseAnd.php new file mode 100644 index 000000000..9e3ed8226 --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/BitwiseAnd.php @@ -0,0 +1,9 @@ +var = $var; + $this->expr = $expr; + } + + public function getSubNodeNames() { + return array('var', 'expr'); + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp.php b/lib/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp.php new file mode 100644 index 000000000..6f87e2350 --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp.php @@ -0,0 +1,30 @@ +left = $left; + $this->right = $right; + } + + public function getSubNodeNames() { + return array('left', 'right'); + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/BitwiseAnd.php b/lib/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/BitwiseAnd.php new file mode 100644 index 000000000..bd6c5c1fb --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/BitwiseAnd.php @@ -0,0 +1,9 @@ +expr = $expr; + } + + public function getSubNodeNames() { + return array('expr'); + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/Node/Expr/BooleanNot.php b/lib/nikic/php-parser/lib/PhpParser/Node/Expr/BooleanNot.php new file mode 100644 index 000000000..8f543b822 --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Node/Expr/BooleanNot.php @@ -0,0 +1,26 @@ +expr = $expr; + } + + public function getSubNodeNames() { + return array('expr'); + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/Node/Expr/Cast.php b/lib/nikic/php-parser/lib/PhpParser/Node/Expr/Cast.php new file mode 100644 index 000000000..bf850dc52 --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Node/Expr/Cast.php @@ -0,0 +1,26 @@ +expr = $expr; + } + + public function getSubNodeNames() { + return array('expr'); + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/Node/Expr/Cast/Array_.php b/lib/nikic/php-parser/lib/PhpParser/Node/Expr/Cast/Array_.php new file mode 100644 index 000000000..08b3a384c --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Node/Expr/Cast/Array_.php @@ -0,0 +1,9 @@ +class = $class; + $this->name = $name; + } + + public function getSubNodeNames() { + return array('class', 'name'); + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/Node/Expr/Clone_.php b/lib/nikic/php-parser/lib/PhpParser/Node/Expr/Clone_.php new file mode 100644 index 000000000..198ec4d89 --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Node/Expr/Clone_.php @@ -0,0 +1,26 @@ +expr = $expr; + } + + public function getSubNodeNames() { + return array('expr'); + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/Node/Expr/Closure.php b/lib/nikic/php-parser/lib/PhpParser/Node/Expr/Closure.php new file mode 100644 index 000000000..5d3765508 --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Node/Expr/Closure.php @@ -0,0 +1,65 @@ + false : Whether the closure is static + * 'byRef' => false : Whether to return by reference + * 'params' => array(): Parameters + * 'uses' => array(): use()s + * 'returnType' => null : Return type + * 'stmts' => array(): Statements + * @param array $attributes Additional attributes + */ + public function __construct(array $subNodes = array(), array $attributes = array()) { + parent::__construct($attributes); + $this->static = isset($subNodes['static']) ? $subNodes['static'] : false; + $this->byRef = isset($subNodes['byRef']) ? $subNodes['byRef'] : false; + $this->params = isset($subNodes['params']) ? $subNodes['params'] : array(); + $this->uses = isset($subNodes['uses']) ? $subNodes['uses'] : array(); + $this->returnType = isset($subNodes['returnType']) ? $subNodes['returnType'] : null; + $this->stmts = isset($subNodes['stmts']) ? $subNodes['stmts'] : array(); + } + + public function getSubNodeNames() { + return array('static', 'byRef', 'params', 'uses', 'returnType', 'stmts'); + } + + public function returnsByRef() { + return $this->byRef; + } + + public function getParams() { + return $this->params; + } + + public function getReturnType() { + return $this->returnType; + } + + public function getStmts() { + return $this->stmts; + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/Node/Expr/ClosureUse.php b/lib/nikic/php-parser/lib/PhpParser/Node/Expr/ClosureUse.php new file mode 100644 index 000000000..f4d02023e --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Node/Expr/ClosureUse.php @@ -0,0 +1,30 @@ +var = $var; + $this->byRef = $byRef; + } + + public function getSubNodeNames() { + return array('var', 'byRef'); + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/Node/Expr/ConstFetch.php b/lib/nikic/php-parser/lib/PhpParser/Node/Expr/ConstFetch.php new file mode 100644 index 000000000..98e51d527 --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Node/Expr/ConstFetch.php @@ -0,0 +1,27 @@ +name = $name; + } + + public function getSubNodeNames() { + return array('name'); + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/Node/Expr/Empty_.php b/lib/nikic/php-parser/lib/PhpParser/Node/Expr/Empty_.php new file mode 100644 index 000000000..0c0509efb --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Node/Expr/Empty_.php @@ -0,0 +1,26 @@ +expr = $expr; + } + + public function getSubNodeNames() { + return array('expr'); + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/Node/Expr/Error.php b/lib/nikic/php-parser/lib/PhpParser/Node/Expr/Error.php new file mode 100644 index 000000000..5ab8fd445 --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Node/Expr/Error.php @@ -0,0 +1,27 @@ +expr = $expr; + } + + public function getSubNodeNames() { + return array('expr'); + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/Node/Expr/Eval_.php b/lib/nikic/php-parser/lib/PhpParser/Node/Expr/Eval_.php new file mode 100644 index 000000000..eadffd008 --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Node/Expr/Eval_.php @@ -0,0 +1,26 @@ +expr = $expr; + } + + public function getSubNodeNames() { + return array('expr'); + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/Node/Expr/Exit_.php b/lib/nikic/php-parser/lib/PhpParser/Node/Expr/Exit_.php new file mode 100644 index 000000000..b0b94cf7b --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Node/Expr/Exit_.php @@ -0,0 +1,30 @@ +expr = $expr; + } + + public function getSubNodeNames() { + return array('expr'); + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/Node/Expr/FuncCall.php b/lib/nikic/php-parser/lib/PhpParser/Node/Expr/FuncCall.php new file mode 100644 index 000000000..60d00507d --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Node/Expr/FuncCall.php @@ -0,0 +1,31 @@ +name = $name; + $this->args = $args; + } + + public function getSubNodeNames() { + return array('name', 'args'); + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/Node/Expr/Include_.php b/lib/nikic/php-parser/lib/PhpParser/Node/Expr/Include_.php new file mode 100644 index 000000000..b27f3af18 --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Node/Expr/Include_.php @@ -0,0 +1,35 @@ +expr = $expr; + $this->type = $type; + } + + public function getSubNodeNames() { + return array('expr', 'type'); + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/Node/Expr/Instanceof_.php b/lib/nikic/php-parser/lib/PhpParser/Node/Expr/Instanceof_.php new file mode 100644 index 000000000..69573d865 --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Node/Expr/Instanceof_.php @@ -0,0 +1,31 @@ +expr = $expr; + $this->class = $class; + } + + public function getSubNodeNames() { + return array('expr', 'class'); + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/Node/Expr/Isset_.php b/lib/nikic/php-parser/lib/PhpParser/Node/Expr/Isset_.php new file mode 100644 index 000000000..4ec1d025a --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Node/Expr/Isset_.php @@ -0,0 +1,26 @@ +vars = $vars; + } + + public function getSubNodeNames() { + return array('vars'); + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/Node/Expr/List_.php b/lib/nikic/php-parser/lib/PhpParser/Node/Expr/List_.php new file mode 100644 index 000000000..30f3dc165 --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Node/Expr/List_.php @@ -0,0 +1,26 @@ +items = $items; + } + + public function getSubNodeNames() { + return array('items'); + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/Node/Expr/MethodCall.php b/lib/nikic/php-parser/lib/PhpParser/Node/Expr/MethodCall.php new file mode 100644 index 000000000..a6cdd07c1 --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Node/Expr/MethodCall.php @@ -0,0 +1,35 @@ +var = $var; + $this->name = $name; + $this->args = $args; + } + + public function getSubNodeNames() { + return array('var', 'name', 'args'); + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/Node/Expr/New_.php b/lib/nikic/php-parser/lib/PhpParser/Node/Expr/New_.php new file mode 100644 index 000000000..a8c87794d --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Node/Expr/New_.php @@ -0,0 +1,31 @@ +class = $class; + $this->args = $args; + } + + public function getSubNodeNames() { + return array('class', 'args'); + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/Node/Expr/PostDec.php b/lib/nikic/php-parser/lib/PhpParser/Node/Expr/PostDec.php new file mode 100644 index 000000000..06ce5470e --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Node/Expr/PostDec.php @@ -0,0 +1,26 @@ +var = $var; + } + + public function getSubNodeNames() { + return array('var'); + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/Node/Expr/PostInc.php b/lib/nikic/php-parser/lib/PhpParser/Node/Expr/PostInc.php new file mode 100644 index 000000000..54865ba12 --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Node/Expr/PostInc.php @@ -0,0 +1,26 @@ +var = $var; + } + + public function getSubNodeNames() { + return array('var'); + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/Node/Expr/PreDec.php b/lib/nikic/php-parser/lib/PhpParser/Node/Expr/PreDec.php new file mode 100644 index 000000000..db30f5102 --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Node/Expr/PreDec.php @@ -0,0 +1,26 @@ +var = $var; + } + + public function getSubNodeNames() { + return array('var'); + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/Node/Expr/PreInc.php b/lib/nikic/php-parser/lib/PhpParser/Node/Expr/PreInc.php new file mode 100644 index 000000000..06356028c --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Node/Expr/PreInc.php @@ -0,0 +1,26 @@ +var = $var; + } + + public function getSubNodeNames() { + return array('var'); + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/Node/Expr/Print_.php b/lib/nikic/php-parser/lib/PhpParser/Node/Expr/Print_.php new file mode 100644 index 000000000..0666ab84d --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Node/Expr/Print_.php @@ -0,0 +1,26 @@ +expr = $expr; + } + + public function getSubNodeNames() { + return array('expr'); + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/Node/Expr/PropertyFetch.php b/lib/nikic/php-parser/lib/PhpParser/Node/Expr/PropertyFetch.php new file mode 100644 index 000000000..adcf21ce1 --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Node/Expr/PropertyFetch.php @@ -0,0 +1,30 @@ +var = $var; + $this->name = $name; + } + + public function getSubNodeNames() { + return array('var', 'name'); + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/Node/Expr/ShellExec.php b/lib/nikic/php-parser/lib/PhpParser/Node/Expr/ShellExec.php new file mode 100644 index 000000000..9516a32f4 --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Node/Expr/ShellExec.php @@ -0,0 +1,26 @@ +parts = $parts; + } + + public function getSubNodeNames() { + return array('parts'); + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/Node/Expr/StaticCall.php b/lib/nikic/php-parser/lib/PhpParser/Node/Expr/StaticCall.php new file mode 100644 index 000000000..5118f34a7 --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Node/Expr/StaticCall.php @@ -0,0 +1,35 @@ +class = $class; + $this->name = $name; + $this->args = $args; + } + + public function getSubNodeNames() { + return array('class', 'name', 'args'); + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/Node/Expr/StaticPropertyFetch.php b/lib/nikic/php-parser/lib/PhpParser/Node/Expr/StaticPropertyFetch.php new file mode 100644 index 000000000..477a69ddb --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Node/Expr/StaticPropertyFetch.php @@ -0,0 +1,31 @@ +class = $class; + $this->name = $name; + } + + public function getSubNodeNames() { + return array('class', 'name'); + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/Node/Expr/Ternary.php b/lib/nikic/php-parser/lib/PhpParser/Node/Expr/Ternary.php new file mode 100644 index 000000000..57301390f --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Node/Expr/Ternary.php @@ -0,0 +1,34 @@ +cond = $cond; + $this->if = $if; + $this->else = $else; + } + + public function getSubNodeNames() { + return array('cond', 'if', 'else'); + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/Node/Expr/UnaryMinus.php b/lib/nikic/php-parser/lib/PhpParser/Node/Expr/UnaryMinus.php new file mode 100644 index 000000000..94635d638 --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Node/Expr/UnaryMinus.php @@ -0,0 +1,26 @@ +expr = $expr; + } + + public function getSubNodeNames() { + return array('expr'); + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/Node/Expr/UnaryPlus.php b/lib/nikic/php-parser/lib/PhpParser/Node/Expr/UnaryPlus.php new file mode 100644 index 000000000..651412003 --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Node/Expr/UnaryPlus.php @@ -0,0 +1,26 @@ +expr = $expr; + } + + public function getSubNodeNames() { + return array('expr'); + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/Node/Expr/Variable.php b/lib/nikic/php-parser/lib/PhpParser/Node/Expr/Variable.php new file mode 100644 index 000000000..3ae3ecd9b --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Node/Expr/Variable.php @@ -0,0 +1,26 @@ +name = $name; + } + + public function getSubNodeNames() { + return array('name'); + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/Node/Expr/YieldFrom.php b/lib/nikic/php-parser/lib/PhpParser/Node/Expr/YieldFrom.php new file mode 100644 index 000000000..993c82c20 --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Node/Expr/YieldFrom.php @@ -0,0 +1,26 @@ +expr = $expr; + } + + public function getSubNodeNames() { + return array('expr'); + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/Node/Expr/Yield_.php b/lib/nikic/php-parser/lib/PhpParser/Node/Expr/Yield_.php new file mode 100644 index 000000000..f3ca88e05 --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Node/Expr/Yield_.php @@ -0,0 +1,30 @@ +key = $key; + $this->value = $value; + } + + public function getSubNodeNames() { + return array('key', 'value'); + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/Node/FunctionLike.php b/lib/nikic/php-parser/lib/PhpParser/Node/FunctionLike.php new file mode 100644 index 000000000..82569450c --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Node/FunctionLike.php @@ -0,0 +1,36 @@ +parts = self::prepareName($name); + } + + public function getSubNodeNames() { + return array('parts'); + } + + /** + * Gets the first part of the name, i.e. everything before the first namespace separator. + * + * @return string First part of the name + */ + public function getFirst() { + return $this->parts[0]; + } + + /** + * Gets the last part of the name, i.e. everything after the last namespace separator. + * + * @return string Last part of the name + */ + public function getLast() { + return $this->parts[count($this->parts) - 1]; + } + + /** + * Checks whether the name is unqualified. (E.g. Name) + * + * @return bool Whether the name is unqualified + */ + public function isUnqualified() { + return 1 == count($this->parts); + } + + /** + * Checks whether the name is qualified. (E.g. Name\Name) + * + * @return bool Whether the name is qualified + */ + public function isQualified() { + return 1 < count($this->parts); + } + + /** + * Checks whether the name is fully qualified. (E.g. \Name) + * + * @return bool Whether the name is fully qualified + */ + public function isFullyQualified() { + return false; + } + + /** + * Checks whether the name is explicitly relative to the current namespace. (E.g. namespace\Name) + * + * @return bool Whether the name is relative + */ + public function isRelative() { + return false; + } + + /** + * Returns a string representation of the name by imploding the namespace parts with the + * namespace separator. + * + * @return string String representation + */ + public function toString() { + return implode('\\', $this->parts); + } + + /** + * Returns a string representation of the name by imploding the namespace parts with the + * namespace separator. + * + * @return string String representation + */ + public function __toString() { + return implode('\\', $this->parts); + } + + /** + * Gets a slice of a name (similar to array_slice). + * + * This method returns a new instance of the same type as the original and with the same + * attributes. + * + * If the slice is empty, null is returned. The null value will be correctly handled in + * concatenations using concat(). + * + * Offset and length have the same meaning as in array_slice(). + * + * @param int $offset Offset to start the slice at (may be negative) + * @param int|null $length Length of the slice (may be negative) + * + * @return static|null Sliced name + */ + public function slice($offset, $length = null) { + $numParts = count($this->parts); + + $realOffset = $offset < 0 ? $offset + $numParts : $offset; + if ($realOffset < 0 || $realOffset > $numParts) { + throw new \OutOfBoundsException(sprintf('Offset %d is out of bounds', $offset)); + } + + if (null === $length) { + $realLength = $numParts - $realOffset; + } else { + $realLength = $length < 0 ? $length + $numParts - $realOffset : $length; + if ($realLength < 0 || $realLength > $numParts) { + throw new \OutOfBoundsException(sprintf('Length %d is out of bounds', $length)); + } + } + + if ($realLength === 0) { + // Empty slice is represented as null + return null; + } + + return new static(array_slice($this->parts, $realOffset, $realLength), $this->attributes); + } + + /** + * Concatenate two names, yielding a new Name instance. + * + * The type of the generated instance depends on which class this method is called on, for + * example Name\FullyQualified::concat() will yield a Name\FullyQualified instance. + * + * If one of the arguments is null, a new instance of the other name will be returned. If both + * arguments are null, null will be returned. As such, writing + * Name::concat($namespace, $shortName) + * where $namespace is a Name node or null will work as expected. + * + * @param string|array|self|null $name1 The first name + * @param string|array|self|null $name2 The second name + * @param array $attributes Attributes to assign to concatenated name + * + * @return static|null Concatenated name + */ + public static function concat($name1, $name2, array $attributes = []) { + if (null === $name1 && null === $name2) { + return null; + } elseif (null === $name1) { + return new static(self::prepareName($name2), $attributes); + } else if (null === $name2) { + return new static(self::prepareName($name1), $attributes); + } else { + return new static( + array_merge(self::prepareName($name1), self::prepareName($name2)), $attributes + ); + } + } + + /** + * Prepares a (string, array or Name node) name for use in name changing methods by converting + * it to an array. + * + * @param string|array|self $name Name to prepare + * + * @return array Prepared name + */ + private static function prepareName($name) { + if (\is_string($name)) { + return explode('\\', $name); + } elseif (\is_array($name)) { + return $name; + } elseif ($name instanceof self) { + return $name->parts; + } + + throw new \InvalidArgumentException( + 'Expected string, array of parts or Name instance' + ); + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/Node/Name/FullyQualified.php b/lib/nikic/php-parser/lib/PhpParser/Node/Name/FullyQualified.php new file mode 100644 index 000000000..97cc1113d --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Node/Name/FullyQualified.php @@ -0,0 +1,42 @@ +type = $type; + } + + public function getSubNodeNames() { + return array('type'); + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/Node/Param.php b/lib/nikic/php-parser/lib/PhpParser/Node/Param.php new file mode 100644 index 000000000..b35ee4ef0 --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Node/Param.php @@ -0,0 +1,42 @@ +type = $type; + $this->byRef = $byRef; + $this->variadic = $variadic; + $this->name = $name; + $this->default = $default; + } + + public function getSubNodeNames() { + return array('type', 'byRef', 'variadic', 'name', 'default'); + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/Node/Scalar.php b/lib/nikic/php-parser/lib/PhpParser/Node/Scalar.php new file mode 100644 index 000000000..01177532c --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Node/Scalar.php @@ -0,0 +1,7 @@ +value = $value; + } + + public function getSubNodeNames() { + return array('value'); + } + + /** + * @internal + * + * Parses a DNUMBER token like PHP would. + * + * @param string $str A string number + * + * @return float The parsed number + */ + public static function parse($str) { + // if string contains any of .eE just cast it to float + if (false !== strpbrk($str, '.eE')) { + return (float) $str; + } + + // otherwise it's an integer notation that overflowed into a float + // if it starts with 0 it's one of the special integer notations + if ('0' === $str[0]) { + // hex + if ('x' === $str[1] || 'X' === $str[1]) { + return hexdec($str); + } + + // bin + if ('b' === $str[1] || 'B' === $str[1]) { + return bindec($str); + } + + // oct + // substr($str, 0, strcspn($str, '89')) cuts the string at the first invalid digit (8 or 9) + // so that only the digits before that are used + return octdec(substr($str, 0, strcspn($str, '89'))); + } + + // dec + return (float) $str; + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/Node/Scalar/Encapsed.php b/lib/nikic/php-parser/lib/PhpParser/Node/Scalar/Encapsed.php new file mode 100644 index 000000000..4f9b433c2 --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Node/Scalar/Encapsed.php @@ -0,0 +1,27 @@ +parts = $parts; + } + + public function getSubNodeNames() { + return array('parts'); + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/Node/Scalar/EncapsedStringPart.php b/lib/nikic/php-parser/lib/PhpParser/Node/Scalar/EncapsedStringPart.php new file mode 100644 index 000000000..50cb1afe6 --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Node/Scalar/EncapsedStringPart.php @@ -0,0 +1,26 @@ +value = $value; + } + + public function getSubNodeNames() { + return array('value'); + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/Node/Scalar/LNumber.php b/lib/nikic/php-parser/lib/PhpParser/Node/Scalar/LNumber.php new file mode 100644 index 000000000..3559b982c --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Node/Scalar/LNumber.php @@ -0,0 +1,67 @@ +value = $value; + } + + public function getSubNodeNames() { + return array('value'); + } + + /** + * Constructs an LNumber node from a string number literal. + * + * @param string $str String number literal (decimal, octal, hex or binary) + * @param array $attributes Additional attributes + * @param bool $allowInvalidOctal Whether to allow invalid octal numbers (PHP 5) + * + * @return LNumber The constructed LNumber, including kind attribute + */ + public static function fromString($str, array $attributes = array(), $allowInvalidOctal = false) { + if ('0' !== $str[0] || '0' === $str) { + $attributes['kind'] = LNumber::KIND_DEC; + return new LNumber((int) $str, $attributes); + } + + if ('x' === $str[1] || 'X' === $str[1]) { + $attributes['kind'] = LNumber::KIND_HEX; + return new LNumber(hexdec($str), $attributes); + } + + if ('b' === $str[1] || 'B' === $str[1]) { + $attributes['kind'] = LNumber::KIND_BIN; + return new LNumber(bindec($str), $attributes); + } + + if (!$allowInvalidOctal && strpbrk($str, '89')) { + throw new Error('Invalid numeric literal', $attributes); + } + + // use intval instead of octdec to get proper cutting behavior with malformed numbers + $attributes['kind'] = LNumber::KIND_OCT; + return new LNumber(intval($str, 8), $attributes); + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/Node/Scalar/MagicConst.php b/lib/nikic/php-parser/lib/PhpParser/Node/Scalar/MagicConst.php new file mode 100644 index 000000000..a50d68f3d --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Node/Scalar/MagicConst.php @@ -0,0 +1,28 @@ + '\\', + '$' => '$', + 'n' => "\n", + 'r' => "\r", + 't' => "\t", + 'f' => "\f", + 'v' => "\v", + 'e' => "\x1B", + ); + + /** + * Constructs a string scalar node. + * + * @param string $value Value of the string + * @param array $attributes Additional attributes + */ + public function __construct($value, array $attributes = array()) { + parent::__construct($attributes); + $this->value = $value; + } + + public function getSubNodeNames() { + return array('value'); + } + + /** + * @internal + * + * Parses a string token. + * + * @param string $str String token content + * @param bool $parseUnicodeEscape Whether to parse PHP 7 \u escapes + * + * @return string The parsed string + */ + public static function parse($str, $parseUnicodeEscape = true) { + $bLength = 0; + if ('b' === $str[0] || 'B' === $str[0]) { + $bLength = 1; + } + + if ('\'' === $str[$bLength]) { + return str_replace( + array('\\\\', '\\\''), + array( '\\', '\''), + substr($str, $bLength + 1, -1) + ); + } else { + return self::parseEscapeSequences( + substr($str, $bLength + 1, -1), '"', $parseUnicodeEscape + ); + } + } + + /** + * @internal + * + * Parses escape sequences in strings (all string types apart from single quoted). + * + * @param string $str String without quotes + * @param null|string $quote Quote type + * @param bool $parseUnicodeEscape Whether to parse PHP 7 \u escapes + * + * @return string String with escape sequences parsed + */ + public static function parseEscapeSequences($str, $quote, $parseUnicodeEscape = true) { + if (null !== $quote) { + $str = str_replace('\\' . $quote, $quote, $str); + } + + $extra = ''; + if ($parseUnicodeEscape) { + $extra = '|u\{([0-9a-fA-F]+)\}'; + } + + return preg_replace_callback( + '~\\\\([\\\\$nrtfve]|[xX][0-9a-fA-F]{1,2}|[0-7]{1,3}' . $extra . ')~', + function($matches) { + $str = $matches[1]; + + if (isset(self::$replacements[$str])) { + return self::$replacements[$str]; + } elseif ('x' === $str[0] || 'X' === $str[0]) { + return chr(hexdec($str)); + } elseif ('u' === $str[0]) { + return self::codePointToUtf8(hexdec($matches[2])); + } else { + return chr(octdec($str)); + } + }, + $str + ); + } + + private static function codePointToUtf8($num) { + if ($num <= 0x7F) { + return chr($num); + } + if ($num <= 0x7FF) { + return chr(($num>>6) + 0xC0) . chr(($num&0x3F) + 0x80); + } + if ($num <= 0xFFFF) { + return chr(($num>>12) + 0xE0) . chr((($num>>6)&0x3F) + 0x80) . chr(($num&0x3F) + 0x80); + } + if ($num <= 0x1FFFFF) { + return chr(($num>>18) + 0xF0) . chr((($num>>12)&0x3F) + 0x80) + . chr((($num>>6)&0x3F) + 0x80) . chr(($num&0x3F) + 0x80); + } + throw new Error('Invalid UTF-8 codepoint escape sequence: Codepoint too large'); + } + + /** + * @internal + * + * Parses a constant doc string. + * + * @param string $startToken Doc string start token content (<<num = $num; + } + + public function getSubNodeNames() { + return array('num'); + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Case_.php b/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Case_.php new file mode 100644 index 000000000..03f892c7c --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Case_.php @@ -0,0 +1,30 @@ +cond = $cond; + $this->stmts = $stmts; + } + + public function getSubNodeNames() { + return array('cond', 'stmts'); + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Catch_.php b/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Catch_.php new file mode 100644 index 000000000..58337ad9b --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Catch_.php @@ -0,0 +1,34 @@ +types = $types; + $this->var = $var; + $this->stmts = $stmts; + } + + public function getSubNodeNames() { + return array('types', 'var', 'stmts'); + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/ClassConst.php b/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/ClassConst.php new file mode 100644 index 000000000..0d41094ff --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/ClassConst.php @@ -0,0 +1,47 @@ +flags = $flags; + $this->consts = $consts; + } + + public function getSubNodeNames() { + return array('flags', 'consts'); + } + + public function isPublic() { + return ($this->flags & Class_::MODIFIER_PUBLIC) !== 0 + || ($this->flags & Class_::VISIBILITY_MODIFIER_MASK) === 0; + } + + public function isProtected() { + return (bool) ($this->flags & Class_::MODIFIER_PROTECTED); + } + + public function isPrivate() { + return (bool) ($this->flags & Class_::MODIFIER_PRIVATE); + } + + public function isStatic() { + return (bool) ($this->flags & Class_::MODIFIER_STATIC); + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/ClassLike.php b/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/ClassLike.php new file mode 100644 index 000000000..f90533553 --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/ClassLike.php @@ -0,0 +1,44 @@ +stmts as $stmt) { + if ($stmt instanceof ClassMethod) { + $methods[] = $stmt; + } + } + return $methods; + } + + /** + * Gets method with the given name defined directly in this class/interface/trait. + * + * @param string $name Name of the method (compared case-insensitively) + * + * @return ClassMethod|null Method node or null if the method does not exist + */ + public function getMethod($name) { + $lowerName = strtolower($name); + foreach ($this->stmts as $stmt) { + if ($stmt instanceof ClassMethod && $lowerName === strtolower($stmt->name)) { + return $stmt; + } + } + return null; + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/ClassMethod.php b/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/ClassMethod.php new file mode 100644 index 000000000..de05390ad --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/ClassMethod.php @@ -0,0 +1,94 @@ + MODIFIER_PUBLIC: Flags + * 'byRef' => false : Whether to return by reference + * 'params' => array() : Parameters + * 'returnType' => null : Return type + * 'stmts' => array() : Statements + * @param array $attributes Additional attributes + */ + public function __construct($name, array $subNodes = array(), array $attributes = array()) { + parent::__construct($attributes); + $this->flags = isset($subNodes['flags']) ? $subNodes['flags'] + : (isset($subNodes['type']) ? $subNodes['type'] : 0); + $this->type = $this->flags; + $this->byRef = isset($subNodes['byRef']) ? $subNodes['byRef'] : false; + $this->name = $name; + $this->params = isset($subNodes['params']) ? $subNodes['params'] : array(); + $this->returnType = isset($subNodes['returnType']) ? $subNodes['returnType'] : null; + $this->stmts = array_key_exists('stmts', $subNodes) ? $subNodes['stmts'] : array(); + } + + public function getSubNodeNames() { + return array('flags', 'byRef', 'name', 'params', 'returnType', 'stmts'); + } + + public function returnsByRef() { + return $this->byRef; + } + + public function getParams() { + return $this->params; + } + + public function getReturnType() { + return $this->returnType; + } + + public function getStmts() { + return $this->stmts; + } + + public function isPublic() { + return ($this->flags & Class_::MODIFIER_PUBLIC) !== 0 + || ($this->flags & Class_::VISIBILITY_MODIFIER_MASK) === 0; + } + + public function isProtected() { + return (bool) ($this->flags & Class_::MODIFIER_PROTECTED); + } + + public function isPrivate() { + return (bool) ($this->flags & Class_::MODIFIER_PRIVATE); + } + + public function isAbstract() { + return (bool) ($this->flags & Class_::MODIFIER_ABSTRACT); + } + + public function isFinal() { + return (bool) ($this->flags & Class_::MODIFIER_FINAL); + } + + public function isStatic() { + return (bool) ($this->flags & Class_::MODIFIER_STATIC); + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Class_.php b/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Class_.php new file mode 100644 index 000000000..0a65e3740 --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Class_.php @@ -0,0 +1,99 @@ + true, + 'parent' => true, + 'static' => true, + ); + + /** + * Constructs a class node. + * + * @param string|null $name Name + * @param array $subNodes Array of the following optional subnodes: + * 'flags' => 0 : Flags + * 'extends' => null : Name of extended class + * 'implements' => array(): Names of implemented interfaces + * 'stmts' => array(): Statements + * @param array $attributes Additional attributes + */ + public function __construct($name, array $subNodes = array(), array $attributes = array()) { + parent::__construct($attributes); + $this->flags = isset($subNodes['flags']) ? $subNodes['flags'] + : (isset($subNodes['type']) ? $subNodes['type'] : 0); + $this->type = $this->flags; + $this->name = $name; + $this->extends = isset($subNodes['extends']) ? $subNodes['extends'] : null; + $this->implements = isset($subNodes['implements']) ? $subNodes['implements'] : array(); + $this->stmts = isset($subNodes['stmts']) ? $subNodes['stmts'] : array(); + } + + public function getSubNodeNames() { + return array('flags', 'name', 'extends', 'implements', 'stmts'); + } + + public function isAbstract() { + return (bool) ($this->flags & self::MODIFIER_ABSTRACT); + } + + public function isFinal() { + return (bool) ($this->flags & self::MODIFIER_FINAL); + } + + public function isAnonymous() { + return null === $this->name; + } + + /** + * @internal + */ + public static function verifyModifier($a, $b) { + if ($a & self::VISIBILITY_MODIFIER_MASK && $b & self::VISIBILITY_MODIFIER_MASK) { + throw new Error('Multiple access type modifiers are not allowed'); + } + + if ($a & self::MODIFIER_ABSTRACT && $b & self::MODIFIER_ABSTRACT) { + throw new Error('Multiple abstract modifiers are not allowed'); + } + + if ($a & self::MODIFIER_STATIC && $b & self::MODIFIER_STATIC) { + throw new Error('Multiple static modifiers are not allowed'); + } + + if ($a & self::MODIFIER_FINAL && $b & self::MODIFIER_FINAL) { + throw new Error('Multiple final modifiers are not allowed'); + } + + if ($a & 48 && $b & 48) { + throw new Error('Cannot use the final modifier on an abstract class member'); + } + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Const_.php b/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Const_.php new file mode 100644 index 000000000..8b2eecd51 --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Const_.php @@ -0,0 +1,26 @@ +consts = $consts; + } + + public function getSubNodeNames() { + return array('consts'); + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Continue_.php b/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Continue_.php new file mode 100644 index 000000000..f78e19a2a --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Continue_.php @@ -0,0 +1,26 @@ +num = $num; + } + + public function getSubNodeNames() { + return array('num'); + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/DeclareDeclare.php b/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/DeclareDeclare.php new file mode 100644 index 000000000..829dbaf25 --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/DeclareDeclare.php @@ -0,0 +1,30 @@ +value pair node. + * + * @param string $key Key + * @param Node\Expr $value Value + * @param array $attributes Additional attributes + */ + public function __construct($key, Node\Expr $value, array $attributes = array()) { + parent::__construct($attributes); + $this->key = $key; + $this->value = $value; + } + + public function getSubNodeNames() { + return array('key', 'value'); + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Declare_.php b/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Declare_.php new file mode 100644 index 000000000..32739f35f --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Declare_.php @@ -0,0 +1,30 @@ +declares = $declares; + $this->stmts = $stmts; + } + + public function getSubNodeNames() { + return array('declares', 'stmts'); + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Do_.php b/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Do_.php new file mode 100644 index 000000000..dd4c6c843 --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Do_.php @@ -0,0 +1,30 @@ +cond = $cond; + $this->stmts = $stmts; + } + + public function getSubNodeNames() { + return array('cond', 'stmts'); + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Echo_.php b/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Echo_.php new file mode 100644 index 000000000..11e107072 --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Echo_.php @@ -0,0 +1,26 @@ +exprs = $exprs; + } + + public function getSubNodeNames() { + return array('exprs'); + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/ElseIf_.php b/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/ElseIf_.php new file mode 100644 index 000000000..608878f65 --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/ElseIf_.php @@ -0,0 +1,30 @@ +cond = $cond; + $this->stmts = $stmts; + } + + public function getSubNodeNames() { + return array('cond', 'stmts'); + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Else_.php b/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Else_.php new file mode 100644 index 000000000..c91a1484f --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Else_.php @@ -0,0 +1,26 @@ +stmts = $stmts; + } + + public function getSubNodeNames() { + return array('stmts'); + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Finally_.php b/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Finally_.php new file mode 100644 index 000000000..0e3eabbe1 --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Finally_.php @@ -0,0 +1,26 @@ +stmts = $stmts; + } + + public function getSubNodeNames() { + return array('stmts'); + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/For_.php b/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/For_.php new file mode 100644 index 000000000..2ca88a332 --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/For_.php @@ -0,0 +1,39 @@ + array(): Init expressions + * 'cond' => array(): Loop conditions + * 'loop' => array(): Loop expressions + * 'stmts' => array(): Statements + * @param array $attributes Additional attributes + */ + public function __construct(array $subNodes = array(), array $attributes = array()) { + parent::__construct($attributes); + $this->init = isset($subNodes['init']) ? $subNodes['init'] : array(); + $this->cond = isset($subNodes['cond']) ? $subNodes['cond'] : array(); + $this->loop = isset($subNodes['loop']) ? $subNodes['loop'] : array(); + $this->stmts = isset($subNodes['stmts']) ? $subNodes['stmts'] : array(); + } + + public function getSubNodeNames() { + return array('init', 'cond', 'loop', 'stmts'); + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Foreach_.php b/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Foreach_.php new file mode 100644 index 000000000..d2c643205 --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Foreach_.php @@ -0,0 +1,43 @@ + null : Variable to assign key to + * 'byRef' => false : Whether to assign value by reference + * 'stmts' => array(): Statements + * @param array $attributes Additional attributes + */ + public function __construct(Node\Expr $expr, Node\Expr $valueVar, array $subNodes = array(), array $attributes = array()) { + parent::__construct($attributes); + $this->expr = $expr; + $this->keyVar = isset($subNodes['keyVar']) ? $subNodes['keyVar'] : null; + $this->byRef = isset($subNodes['byRef']) ? $subNodes['byRef'] : false; + $this->valueVar = $valueVar; + $this->stmts = isset($subNodes['stmts']) ? $subNodes['stmts'] : array(); + } + + public function getSubNodeNames() { + return array('expr', 'keyVar', 'byRef', 'valueVar', 'stmts'); + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Function_.php b/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Function_.php new file mode 100644 index 000000000..4c1f48d84 --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Function_.php @@ -0,0 +1,60 @@ + false : Whether to return by reference + * 'params' => array(): Parameters + * 'returnType' => null : Return type + * 'stmts' => array(): Statements + * @param array $attributes Additional attributes + */ + public function __construct($name, array $subNodes = array(), array $attributes = array()) { + parent::__construct($attributes); + $this->byRef = isset($subNodes['byRef']) ? $subNodes['byRef'] : false; + $this->name = $name; + $this->params = isset($subNodes['params']) ? $subNodes['params'] : array(); + $this->returnType = isset($subNodes['returnType']) ? $subNodes['returnType'] : null; + $this->stmts = isset($subNodes['stmts']) ? $subNodes['stmts'] : array(); + } + + public function getSubNodeNames() { + return array('byRef', 'name', 'params', 'returnType', 'stmts'); + } + + public function returnsByRef() { + return $this->byRef; + } + + public function getParams() { + return $this->params; + } + + public function getReturnType() { + return $this->returnType; + } + + public function getStmts() { + return $this->stmts; + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Global_.php b/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Global_.php new file mode 100644 index 000000000..29fbc488e --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Global_.php @@ -0,0 +1,26 @@ +vars = $vars; + } + + public function getSubNodeNames() { + return array('vars'); + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Goto_.php b/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Goto_.php new file mode 100644 index 000000000..b087fe02b --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Goto_.php @@ -0,0 +1,26 @@ +name = $name; + } + + public function getSubNodeNames() { + return array('name'); + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/GroupUse.php b/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/GroupUse.php new file mode 100644 index 000000000..30837dd6b --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/GroupUse.php @@ -0,0 +1,35 @@ +type = $type; + $this->prefix = $prefix; + $this->uses = $uses; + } + + public function getSubNodeNames() { + return array('type', 'prefix', 'uses'); + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/HaltCompiler.php b/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/HaltCompiler.php new file mode 100644 index 000000000..c33ec9f1d --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/HaltCompiler.php @@ -0,0 +1,26 @@ +remaining = $remaining; + } + + public function getSubNodeNames() { + return array('remaining'); + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/If_.php b/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/If_.php new file mode 100644 index 000000000..98bda356f --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/If_.php @@ -0,0 +1,39 @@ + array(): Statements + * 'elseifs' => array(): Elseif clauses + * 'else' => null : Else clause + * @param array $attributes Additional attributes + */ + public function __construct(Node\Expr $cond, array $subNodes = array(), array $attributes = array()) { + parent::__construct($attributes); + $this->cond = $cond; + $this->stmts = isset($subNodes['stmts']) ? $subNodes['stmts'] : array(); + $this->elseifs = isset($subNodes['elseifs']) ? $subNodes['elseifs'] : array(); + $this->else = isset($subNodes['else']) ? $subNodes['else'] : null; + } + + public function getSubNodeNames() { + return array('cond', 'stmts', 'elseifs', 'else'); + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/InlineHTML.php b/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/InlineHTML.php new file mode 100644 index 000000000..accebe61e --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/InlineHTML.php @@ -0,0 +1,26 @@ +value = $value; + } + + public function getSubNodeNames() { + return array('value'); + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Interface_.php b/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Interface_.php new file mode 100644 index 000000000..efb5891fc --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Interface_.php @@ -0,0 +1,31 @@ + array(): Name of extended interfaces + * 'stmts' => array(): Statements + * @param array $attributes Additional attributes + */ + public function __construct($name, array $subNodes = array(), array $attributes = array()) { + parent::__construct($attributes); + $this->name = $name; + $this->extends = isset($subNodes['extends']) ? $subNodes['extends'] : array(); + $this->stmts = isset($subNodes['stmts']) ? $subNodes['stmts'] : array(); + } + + public function getSubNodeNames() { + return array('name', 'extends', 'stmts'); + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Label.php b/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Label.php new file mode 100644 index 000000000..edd0ee9a5 --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Label.php @@ -0,0 +1,26 @@ +name = $name; + } + + public function getSubNodeNames() { + return array('name'); + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Namespace_.php b/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Namespace_.php new file mode 100644 index 000000000..444855c39 --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Namespace_.php @@ -0,0 +1,34 @@ +name = $name; + $this->stmts = $stmts; + } + + public function getSubNodeNames() { + return array('name', 'stmts'); + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Nop.php b/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Nop.php new file mode 100644 index 000000000..270dd0995 --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Nop.php @@ -0,0 +1,13 @@ +flags = $flags; + $this->type = $flags; + $this->props = $props; + } + + public function getSubNodeNames() { + return array('flags', 'props'); + } + + public function isPublic() { + return ($this->flags & Class_::MODIFIER_PUBLIC) !== 0 + || ($this->flags & Class_::VISIBILITY_MODIFIER_MASK) === 0; + } + + public function isProtected() { + return (bool) ($this->flags & Class_::MODIFIER_PROTECTED); + } + + public function isPrivate() { + return (bool) ($this->flags & Class_::MODIFIER_PRIVATE); + } + + public function isStatic() { + return (bool) ($this->flags & Class_::MODIFIER_STATIC); + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/PropertyProperty.php b/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/PropertyProperty.php new file mode 100644 index 000000000..b2d29dc77 --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/PropertyProperty.php @@ -0,0 +1,30 @@ +name = $name; + $this->default = $default; + } + + public function getSubNodeNames() { + return array('name', 'default'); + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Return_.php b/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Return_.php new file mode 100644 index 000000000..b64284114 --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Return_.php @@ -0,0 +1,26 @@ +expr = $expr; + } + + public function getSubNodeNames() { + return array('expr'); + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/StaticVar.php b/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/StaticVar.php new file mode 100644 index 000000000..4bc5dd25c --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/StaticVar.php @@ -0,0 +1,30 @@ +name = $name; + $this->default = $default; + } + + public function getSubNodeNames() { + return array('name', 'default'); + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Static_.php b/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Static_.php new file mode 100644 index 000000000..37cc0b36f --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Static_.php @@ -0,0 +1,26 @@ +vars = $vars; + } + + public function getSubNodeNames() { + return array('vars'); + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Switch_.php b/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Switch_.php new file mode 100644 index 000000000..72d667b1e --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Switch_.php @@ -0,0 +1,30 @@ +cond = $cond; + $this->cases = $cases; + } + + public function getSubNodeNames() { + return array('cond', 'cases'); + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Throw_.php b/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Throw_.php new file mode 100644 index 000000000..f8ff6aa38 --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Throw_.php @@ -0,0 +1,26 @@ +expr = $expr; + } + + public function getSubNodeNames() { + return array('expr'); + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/TraitUse.php b/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/TraitUse.php new file mode 100644 index 000000000..a29874bea --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/TraitUse.php @@ -0,0 +1,31 @@ +traits = $traits; + $this->adaptations = $adaptations; + } + + public function getSubNodeNames() { + return array('traits', 'adaptations'); + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/TraitUseAdaptation.php b/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/TraitUseAdaptation.php new file mode 100644 index 000000000..c6038c8ca --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/TraitUseAdaptation.php @@ -0,0 +1,13 @@ +trait = $trait; + $this->method = $method; + $this->newModifier = $newModifier; + $this->newName = $newName; + } + + public function getSubNodeNames() { + return array('trait', 'method', 'newModifier', 'newName'); + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/TraitUseAdaptation/Precedence.php b/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/TraitUseAdaptation/Precedence.php new file mode 100644 index 000000000..1f6bc1f98 --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/TraitUseAdaptation/Precedence.php @@ -0,0 +1,30 @@ +trait = $trait; + $this->method = $method; + $this->insteadof = $insteadof; + } + + public function getSubNodeNames() { + return array('trait', 'method', 'insteadof'); + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Trait_.php b/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Trait_.php new file mode 100644 index 000000000..eed5844ae --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Trait_.php @@ -0,0 +1,26 @@ + array(): Statements + * @param array $attributes Additional attributes + */ + public function __construct($name, array $subNodes = array(), array $attributes = array()) { + parent::__construct($attributes); + $this->name = $name; + $this->stmts = isset($subNodes['stmts']) ? $subNodes['stmts'] : array(); + } + + public function getSubNodeNames() { + return array('name', 'stmts'); + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/TryCatch.php b/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/TryCatch.php new file mode 100644 index 000000000..0ff36cc77 --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/TryCatch.php @@ -0,0 +1,34 @@ +stmts = $stmts; + $this->catches = $catches; + $this->finally = $finally; + } + + public function getSubNodeNames() { + return array('stmts', 'catches', 'finally'); + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Unset_.php b/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Unset_.php new file mode 100644 index 000000000..0f00fe941 --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Unset_.php @@ -0,0 +1,26 @@ +vars = $vars; + } + + public function getSubNodeNames() { + return array('vars'); + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/UseUse.php b/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/UseUse.php new file mode 100644 index 000000000..2de8432d7 --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/UseUse.php @@ -0,0 +1,38 @@ +getLast(); + } + + parent::__construct($attributes); + $this->type = $type; + $this->name = $name; + $this->alias = $alias; + } + + public function getSubNodeNames() { + return array('type', 'name', 'alias'); + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Use_.php b/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Use_.php new file mode 100644 index 000000000..6c89ebb1b --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Use_.php @@ -0,0 +1,43 @@ +type = $type; + $this->uses = $uses; + } + + public function getSubNodeNames() { + return array('type', 'uses'); + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/While_.php b/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/While_.php new file mode 100644 index 000000000..afad1b259 --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/While_.php @@ -0,0 +1,30 @@ +cond = $cond; + $this->stmts = $stmts; + } + + public function getSubNodeNames() { + return array('cond', 'stmts'); + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/NodeAbstract.php b/lib/nikic/php-parser/lib/PhpParser/NodeAbstract.php new file mode 100644 index 000000000..1b757c7bc --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/NodeAbstract.php @@ -0,0 +1,120 @@ +attributes = $attributes; + } + + /** + * Gets the type of the node. + * + * @return string Type of the node + */ + public function getType() { + $className = rtrim(get_class($this), '_'); + return strtr( + substr($className, strlen(Node::class) + 1), + '\\', + '_' + ); + } + + /** + * Gets line the node started in. + * + * @return int Line + */ + public function getLine() { + return $this->getAttribute('startLine', -1); + } + + /** + * Sets line the node started in. + * + * @param int $line Line + * + * @deprecated + */ + public function setLine($line) { + $this->setAttribute('startLine', (int) $line); + } + + /** + * Gets the doc comment of the node. + * + * The doc comment has to be the last comment associated with the node. + * + * @return null|Comment\Doc Doc comment object or null + */ + public function getDocComment() { + $comments = $this->getAttribute('comments'); + if (!$comments) { + return null; + } + + $lastComment = $comments[count($comments) - 1]; + if (!$lastComment instanceof Comment\Doc) { + return null; + } + + return $lastComment; + } + + /** + * Sets the doc comment of the node. + * + * This will either replace an existing doc comment or add it to the comments array. + * + * @param Comment\Doc $docComment Doc comment to set + */ + public function setDocComment(Comment\Doc $docComment) { + $comments = $this->getAttribute('comments', []); + + $numComments = count($comments); + if ($numComments > 0 && $comments[$numComments - 1] instanceof Comment\Doc) { + // Replace existing doc comment + $comments[$numComments - 1] = $docComment; + } else { + // Append new comment + $comments[] = $docComment; + } + + $this->setAttribute('comments', $comments); + } + + public function setAttribute($key, $value) { + $this->attributes[$key] = $value; + } + + public function hasAttribute($key) { + return array_key_exists($key, $this->attributes); + } + + public function &getAttribute($key, $default = null) { + if (!array_key_exists($key, $this->attributes)) { + return $default; + } else { + return $this->attributes[$key]; + } + } + + public function getAttributes() { + return $this->attributes; + } + + public function jsonSerialize() { + return ['nodeType' => $this->getType()] + get_object_vars($this); + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/NodeDumper.php b/lib/nikic/php-parser/lib/PhpParser/NodeDumper.php new file mode 100644 index 000000000..9946eb853 --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/NodeDumper.php @@ -0,0 +1,196 @@ +dumpComments = !empty($options['dumpComments']); + $this->dumpPositions = !empty($options['dumpPositions']); + } + + /** + * Dumps a node or array. + * + * @param array|Node $node Node or array to dump + * @param string|null $code Code corresponding to dumped AST. This only needs to be passed if + * the dumpPositions option is enabled and the dumping of node offsets + * is desired. + * + * @return string Dumped value + */ + public function dump($node, $code = null) { + $this->code = $code; + return $this->dumpRecursive($node); + } + + protected function dumpRecursive($node) { + if ($node instanceof Node) { + $r = $node->getType(); + if ($this->dumpPositions && null !== $p = $this->dumpPosition($node)) { + $r .= $p; + } + $r .= '('; + + foreach ($node->getSubNodeNames() as $key) { + $r .= "\n " . $key . ': '; + + $value = $node->$key; + if (null === $value) { + $r .= 'null'; + } elseif (false === $value) { + $r .= 'false'; + } elseif (true === $value) { + $r .= 'true'; + } elseif (is_scalar($value)) { + if ('flags' === $key || 'newModifier' === $key) { + $r .= $this->dumpFlags($value); + } else if ('type' === $key && $node instanceof Include_) { + $r .= $this->dumpIncludeType($value); + } else if ('type' === $key + && ($node instanceof Use_ || $node instanceof UseUse || $node instanceof GroupUse)) { + $r .= $this->dumpUseType($value); + } else { + $r .= $value; + } + } else { + $r .= str_replace("\n", "\n ", $this->dumpRecursive($value)); + } + } + + if ($this->dumpComments && $comments = $node->getAttribute('comments')) { + $r .= "\n comments: " . str_replace("\n", "\n ", $this->dumpRecursive($comments)); + } + } elseif (is_array($node)) { + $r = 'array('; + + foreach ($node as $key => $value) { + $r .= "\n " . $key . ': '; + + if (null === $value) { + $r .= 'null'; + } elseif (false === $value) { + $r .= 'false'; + } elseif (true === $value) { + $r .= 'true'; + } elseif (is_scalar($value)) { + $r .= $value; + } else { + $r .= str_replace("\n", "\n ", $this->dumpRecursive($value)); + } + } + } elseif ($node instanceof Comment) { + return $node->getReformattedText(); + } else { + throw new \InvalidArgumentException('Can only dump nodes and arrays.'); + } + + return $r . "\n)"; + } + + protected function dumpFlags($flags) { + $strs = []; + if ($flags & Class_::MODIFIER_PUBLIC) { + $strs[] = 'MODIFIER_PUBLIC'; + } + if ($flags & Class_::MODIFIER_PROTECTED) { + $strs[] = 'MODIFIER_PROTECTED'; + } + if ($flags & Class_::MODIFIER_PRIVATE) { + $strs[] = 'MODIFIER_PRIVATE'; + } + if ($flags & Class_::MODIFIER_ABSTRACT) { + $strs[] = 'MODIFIER_ABSTRACT'; + } + if ($flags & Class_::MODIFIER_STATIC) { + $strs[] = 'MODIFIER_STATIC'; + } + if ($flags & Class_::MODIFIER_FINAL) { + $strs[] = 'MODIFIER_FINAL'; + } + + if ($strs) { + return implode(' | ', $strs) . ' (' . $flags . ')'; + } else { + return $flags; + } + } + + protected function dumpIncludeType($type) { + $map = [ + Include_::TYPE_INCLUDE => 'TYPE_INCLUDE', + Include_::TYPE_INCLUDE_ONCE => 'TYPE_INCLUDE_ONCE', + Include_::TYPE_REQUIRE => 'TYPE_REQUIRE', + Include_::TYPE_REQUIRE_ONCE => 'TYPE_REQURE_ONCE', + ]; + + if (!isset($map[$type])) { + return $type; + } + return $map[$type] . ' (' . $type . ')'; + } + + protected function dumpUseType($type) { + $map = [ + Use_::TYPE_UNKNOWN => 'TYPE_UNKNOWN', + Use_::TYPE_NORMAL => 'TYPE_NORMAL', + Use_::TYPE_FUNCTION => 'TYPE_FUNCTION', + Use_::TYPE_CONSTANT => 'TYPE_CONSTANT', + ]; + + if (!isset($map[$type])) { + return $type; + } + return $map[$type] . ' (' . $type . ')'; + } + + protected function dumpPosition(Node $node) { + if (!$node->hasAttribute('startLine') || !$node->hasAttribute('endLine')) { + return null; + } + + $start = $node->getAttribute('startLine'); + $end = $node->getAttribute('endLine'); + if ($node->hasAttribute('startFilePos') && $node->hasAttribute('endFilePos') + && null !== $this->code + ) { + $start .= ':' . $this->toColumn($this->code, $node->getAttribute('startFilePos')); + $end .= ':' . $this->toColumn($this->code, $node->getAttribute('endFilePos')); + } + return "[$start - $end]"; + } + + // Copied from Error class + private function toColumn($code, $pos) { + if ($pos > strlen($code)) { + throw new \RuntimeException('Invalid position information'); + } + + $lineStartPos = strrpos($code, "\n", $pos - strlen($code)); + if (false === $lineStartPos) { + $lineStartPos = -1; + } + + return $pos - $lineStartPos; + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/NodeTraverser.php b/lib/nikic/php-parser/lib/PhpParser/NodeTraverser.php new file mode 100644 index 000000000..cce43d926 --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/NodeTraverser.php @@ -0,0 +1,204 @@ +visitors = array(); + } + + /** + * Adds a visitor. + * + * @param NodeVisitor $visitor Visitor to add + */ + public function addVisitor(NodeVisitor $visitor) { + $this->visitors[] = $visitor; + } + + /** + * Removes an added visitor. + * + * @param NodeVisitor $visitor + */ + public function removeVisitor(NodeVisitor $visitor) { + foreach ($this->visitors as $index => $storedVisitor) { + if ($storedVisitor === $visitor) { + unset($this->visitors[$index]); + break; + } + } + } + + /** + * Traverses an array of nodes using the registered visitors. + * + * @param Node[] $nodes Array of nodes + * + * @return Node[] Traversed array of nodes + */ + public function traverse(array $nodes) { + $this->stopTraversal = false; + + foreach ($this->visitors as $visitor) { + if (null !== $return = $visitor->beforeTraverse($nodes)) { + $nodes = $return; + } + } + + $nodes = $this->traverseArray($nodes); + + foreach ($this->visitors as $visitor) { + if (null !== $return = $visitor->afterTraverse($nodes)) { + $nodes = $return; + } + } + + return $nodes; + } + + protected function traverseNode(Node $node) { + foreach ($node->getSubNodeNames() as $name) { + $subNode =& $node->$name; + + if (is_array($subNode)) { + $subNode = $this->traverseArray($subNode); + if ($this->stopTraversal) { + break; + } + } elseif ($subNode instanceof Node) { + $traverseChildren = true; + foreach ($this->visitors as $visitor) { + $return = $visitor->enterNode($subNode); + if (self::DONT_TRAVERSE_CHILDREN === $return) { + $traverseChildren = false; + } else if (self::STOP_TRAVERSAL === $return) { + $this->stopTraversal = true; + break 2; + } else if (null !== $return) { + $subNode = $return; + } + } + + if ($traverseChildren) { + $subNode = $this->traverseNode($subNode); + if ($this->stopTraversal) { + break; + } + } + + foreach ($this->visitors as $visitor) { + $return = $visitor->leaveNode($subNode); + if (self::STOP_TRAVERSAL === $return) { + $this->stopTraversal = true; + break 2; + } else if (null !== $return) { + if (is_array($return)) { + throw new \LogicException( + 'leaveNode() may only return an array ' . + 'if the parent structure is an array' + ); + } + $subNode = $return; + } + } + } + } + + return $node; + } + + protected function traverseArray(array $nodes) { + $doNodes = array(); + + foreach ($nodes as $i => &$node) { + if (is_array($node)) { + $node = $this->traverseArray($node); + if ($this->stopTraversal) { + break; + } + } elseif ($node instanceof Node) { + $traverseChildren = true; + foreach ($this->visitors as $visitor) { + $return = $visitor->enterNode($node); + if (self::DONT_TRAVERSE_CHILDREN === $return) { + $traverseChildren = false; + } else if (self::STOP_TRAVERSAL === $return) { + $this->stopTraversal = true; + break 2; + } else if (null !== $return) { + $node = $return; + } + } + + if ($traverseChildren) { + $node = $this->traverseNode($node); + if ($this->stopTraversal) { + break; + } + } + + foreach ($this->visitors as $visitor) { + $return = $visitor->leaveNode($node); + + if (self::REMOVE_NODE === $return) { + $doNodes[] = array($i, array()); + break; + } else if (self::STOP_TRAVERSAL === $return) { + $this->stopTraversal = true; + break 2; + } elseif (is_array($return)) { + $doNodes[] = array($i, $return); + break; + } elseif (null !== $return) { + $node = $return; + } + } + } + } + + if (!empty($doNodes)) { + while (list($i, $replace) = array_pop($doNodes)) { + array_splice($nodes, $i, 1, $replace); + } + } + + return $nodes; + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/NodeTraverserInterface.php b/lib/nikic/php-parser/lib/PhpParser/NodeTraverserInterface.php new file mode 100644 index 000000000..0f88e4671 --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/NodeTraverserInterface.php @@ -0,0 +1,30 @@ + $node stays as-is + * * NodeTraverser::DONT_TRAVERSE_CHILDREN + * => Children of $node are not traversed. $node stays as-is + * * NodeTraverser::STOP_TRAVERSAL + * => Traversal is aborted. $node stays as-is + * * otherwise + * => $node is set to the return value + * + * @param Node $node Node + * + * @return null|int|Node Node + */ + public function enterNode(Node $node); + + /** + * Called when leaving a node. + * + * Return value semantics: + * * null + * => $node stays as-is + * * NodeTraverser::REMOVE_NODE + * => $node is removed from the parent array + * * NodeTraverser::STOP_TRAVERSAL + * => Traversal is aborted. $node stays as-is + * * array (of Nodes) + * => The return value is merged into the parent array (at the position of the $node) + * * otherwise + * => $node is set to the return value + * + * @param Node $node Node + * + * @return null|false|int|Node|Node[] Node + */ + public function leaveNode(Node $node); + + /** + * Called once after traversal. + * + * Return value semantics: + * * null: $nodes stays as-is + * * otherwise: $nodes is set to the return value + * + * @param Node[] $nodes Array of nodes + * + * @return null|Node[] Array of nodes + */ + public function afterTraverse(array $nodes); +} \ No newline at end of file diff --git a/lib/nikic/php-parser/lib/PhpParser/NodeVisitor/NameResolver.php b/lib/nikic/php-parser/lib/PhpParser/NodeVisitor/NameResolver.php new file mode 100644 index 000000000..d56812bcc --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/NodeVisitor/NameResolver.php @@ -0,0 +1,272 @@ + [aliasName => originalName]] */ + protected $aliases; + + /** @var ErrorHandler Error handler */ + protected $errorHandler; + + /** @var bool Whether to preserve original names */ + protected $preserveOriginalNames; + + /** + * Constructs a name resolution visitor. + * + * Options: If "preserveOriginalNames" is enabled, an "originalName" attribute will be added to + * all name nodes that underwent resolution. + * + * @param ErrorHandler|null $errorHandler Error handler + * @param array $options Options + */ + public function __construct(ErrorHandler $errorHandler = null, array $options = []) { + $this->errorHandler = $errorHandler ?: new ErrorHandler\Throwing; + $this->preserveOriginalNames = !empty($options['preserveOriginalNames']); + } + + public function beforeTraverse(array $nodes) { + $this->resetState(); + } + + public function enterNode(Node $node) { + if ($node instanceof Stmt\Namespace_) { + $this->resetState($node->name); + } elseif ($node instanceof Stmt\Use_) { + foreach ($node->uses as $use) { + $this->addAlias($use, $node->type, null); + } + } elseif ($node instanceof Stmt\GroupUse) { + foreach ($node->uses as $use) { + $this->addAlias($use, $node->type, $node->prefix); + } + } elseif ($node instanceof Stmt\Class_) { + if (null !== $node->extends) { + $node->extends = $this->resolveClassName($node->extends); + } + + foreach ($node->implements as &$interface) { + $interface = $this->resolveClassName($interface); + } + + if (null !== $node->name) { + $this->addNamespacedName($node); + } + } elseif ($node instanceof Stmt\Interface_) { + foreach ($node->extends as &$interface) { + $interface = $this->resolveClassName($interface); + } + + $this->addNamespacedName($node); + } elseif ($node instanceof Stmt\Trait_) { + $this->addNamespacedName($node); + } elseif ($node instanceof Stmt\Function_) { + $this->addNamespacedName($node); + $this->resolveSignature($node); + } elseif ($node instanceof Stmt\ClassMethod + || $node instanceof Expr\Closure + ) { + $this->resolveSignature($node); + } elseif ($node instanceof Stmt\Const_) { + foreach ($node->consts as $const) { + $this->addNamespacedName($const); + } + } elseif ($node instanceof Expr\StaticCall + || $node instanceof Expr\StaticPropertyFetch + || $node instanceof Expr\ClassConstFetch + || $node instanceof Expr\New_ + || $node instanceof Expr\Instanceof_ + ) { + if ($node->class instanceof Name) { + $node->class = $this->resolveClassName($node->class); + } + } elseif ($node instanceof Stmt\Catch_) { + foreach ($node->types as &$type) { + $type = $this->resolveClassName($type); + } + } elseif ($node instanceof Expr\FuncCall) { + if ($node->name instanceof Name) { + $node->name = $this->resolveOtherName($node->name, Stmt\Use_::TYPE_FUNCTION); + } + } elseif ($node instanceof Expr\ConstFetch) { + $node->name = $this->resolveOtherName($node->name, Stmt\Use_::TYPE_CONSTANT); + } elseif ($node instanceof Stmt\TraitUse) { + foreach ($node->traits as &$trait) { + $trait = $this->resolveClassName($trait); + } + + foreach ($node->adaptations as $adaptation) { + if (null !== $adaptation->trait) { + $adaptation->trait = $this->resolveClassName($adaptation->trait); + } + + if ($adaptation instanceof Stmt\TraitUseAdaptation\Precedence) { + foreach ($adaptation->insteadof as &$insteadof) { + $insteadof = $this->resolveClassName($insteadof); + } + } + } + } + } + + protected function resetState(Name $namespace = null) { + $this->namespace = $namespace; + $this->aliases = array( + Stmt\Use_::TYPE_NORMAL => array(), + Stmt\Use_::TYPE_FUNCTION => array(), + Stmt\Use_::TYPE_CONSTANT => array(), + ); + } + + protected function addAlias(Stmt\UseUse $use, $type, Name $prefix = null) { + // Add prefix for group uses + $name = $prefix ? Name::concat($prefix, $use->name) : $use->name; + // Type is determined either by individual element or whole use declaration + $type |= $use->type; + + // Constant names are case sensitive, everything else case insensitive + if ($type === Stmt\Use_::TYPE_CONSTANT) { + $aliasName = $use->alias; + } else { + $aliasName = strtolower($use->alias); + } + + if (isset($this->aliases[$type][$aliasName])) { + $typeStringMap = array( + Stmt\Use_::TYPE_NORMAL => '', + Stmt\Use_::TYPE_FUNCTION => 'function ', + Stmt\Use_::TYPE_CONSTANT => 'const ', + ); + + $this->errorHandler->handleError(new Error( + sprintf( + 'Cannot use %s%s as %s because the name is already in use', + $typeStringMap[$type], $name, $use->alias + ), + $use->getAttributes() + )); + return; + } + + $this->aliases[$type][$aliasName] = $name; + } + + /** @param Stmt\Function_|Stmt\ClassMethod|Expr\Closure $node */ + private function resolveSignature($node) { + foreach ($node->params as $param) { + $param->type = $this->resolveType($param->type); + } + $node->returnType = $this->resolveType($node->returnType); + } + + private function resolveType($node) { + if ($node instanceof Node\NullableType) { + $node->type = $this->resolveType($node->type); + return $node; + } + if ($node instanceof Name) { + return $this->resolveClassName($node); + } + return $node; + } + + protected function resolveClassName(Name $name) { + if ($this->preserveOriginalNames) { + // Save the original name + $originalName = $name; + $name = clone $originalName; + $name->setAttribute('originalName', $originalName); + } + + // don't resolve special class names + if (in_array(strtolower($name->toString()), array('self', 'parent', 'static'))) { + if (!$name->isUnqualified()) { + $this->errorHandler->handleError(new Error( + sprintf("'\\%s' is an invalid class name", $name->toString()), + $name->getAttributes() + )); + } + return $name; + } + + // fully qualified names are already resolved + if ($name->isFullyQualified()) { + return $name; + } + + $aliasName = strtolower($name->getFirst()); + if (!$name->isRelative() && isset($this->aliases[Stmt\Use_::TYPE_NORMAL][$aliasName])) { + // resolve aliases (for non-relative names) + $alias = $this->aliases[Stmt\Use_::TYPE_NORMAL][$aliasName]; + return FullyQualified::concat($alias, $name->slice(1), $name->getAttributes()); + } + + // if no alias exists prepend current namespace + return FullyQualified::concat($this->namespace, $name, $name->getAttributes()); + } + + protected function resolveOtherName(Name $name, $type) { + if ($this->preserveOriginalNames) { + // Save the original name + $originalName = $name; + $name = clone $originalName; + $name->setAttribute('originalName', $originalName); + } + + // fully qualified names are already resolved + if ($name->isFullyQualified()) { + return $name; + } + + // resolve aliases for qualified names + $aliasName = strtolower($name->getFirst()); + if ($name->isQualified() && isset($this->aliases[Stmt\Use_::TYPE_NORMAL][$aliasName])) { + $alias = $this->aliases[Stmt\Use_::TYPE_NORMAL][$aliasName]; + return FullyQualified::concat($alias, $name->slice(1), $name->getAttributes()); + } + + if ($name->isUnqualified()) { + if ($type === Stmt\Use_::TYPE_CONSTANT) { + // constant aliases are case-sensitive, function aliases case-insensitive + $aliasName = $name->getFirst(); + } + + if (isset($this->aliases[$type][$aliasName])) { + // resolve unqualified aliases + return new FullyQualified($this->aliases[$type][$aliasName], $name->getAttributes()); + } + + if (null === $this->namespace) { + // outside of a namespace unaliased unqualified is same as fully qualified + return new FullyQualified($name, $name->getAttributes()); + } + + // unqualified names inside a namespace cannot be resolved at compile-time + // add the namespaced version of the name as an attribute + $name->setAttribute('namespacedName', + FullyQualified::concat($this->namespace, $name, $name->getAttributes())); + return $name; + } + + // if no alias exists prepend current namespace + return FullyQualified::concat($this->namespace, $name, $name->getAttributes()); + } + + protected function addNamespacedName(Node $node) { + $node->namespacedName = Name::concat($this->namespace, $node->name); + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/NodeVisitorAbstract.php b/lib/nikic/php-parser/lib/PhpParser/NodeVisitorAbstract.php new file mode 100644 index 000000000..3e1743a74 --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/NodeVisitorAbstract.php @@ -0,0 +1,14 @@ +parsers = $parsers; + } + + public function parse($code, ErrorHandler $errorHandler = null) { + if (null === $errorHandler) { + $errorHandler = new ErrorHandler\Throwing; + } + + list($firstStmts, $firstError) = $this->tryParse($this->parsers[0], $errorHandler, $code); + if ($firstError === null) { + return $firstStmts; + } + + for ($i = 1, $c = count($this->parsers); $i < $c; ++$i) { + list($stmts, $error) = $this->tryParse($this->parsers[$i], $errorHandler, $code); + if ($error === null) { + return $stmts; + } + } + + throw $firstError; + } + + private function tryParse(Parser $parser, ErrorHandler $errorHandler, $code) { + $stmts = null; + $error = null; + try { + $stmts = $parser->parse($code, $errorHandler); + } catch (Error $error) {} + return [$stmts, $error]; + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/Parser/Php5.php b/lib/nikic/php-parser/lib/PhpParser/Parser/Php5.php new file mode 100644 index 000000000..4fbddaa70 --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Parser/Php5.php @@ -0,0 +1,3153 @@ +'", + "T_IS_GREATER_OR_EQUAL", + "T_SL", + "T_SR", + "'+'", + "'-'", + "'.'", + "'*'", + "'/'", + "'%'", + "'!'", + "T_INSTANCEOF", + "'~'", + "T_INC", + "T_DEC", + "T_INT_CAST", + "T_DOUBLE_CAST", + "T_STRING_CAST", + "T_ARRAY_CAST", + "T_OBJECT_CAST", + "T_BOOL_CAST", + "T_UNSET_CAST", + "'@'", + "T_POW", + "'['", + "T_NEW", + "T_CLONE", + "T_EXIT", + "T_IF", + "T_ELSEIF", + "T_ELSE", + "T_ENDIF", + "T_LNUMBER", + "T_DNUMBER", + "T_STRING", + "T_STRING_VARNAME", + "T_VARIABLE", + "T_NUM_STRING", + "T_INLINE_HTML", + "T_ENCAPSED_AND_WHITESPACE", + "T_CONSTANT_ENCAPSED_STRING", + "T_ECHO", + "T_DO", + "T_WHILE", + "T_ENDWHILE", + "T_FOR", + "T_ENDFOR", + "T_FOREACH", + "T_ENDFOREACH", + "T_DECLARE", + "T_ENDDECLARE", + "T_AS", + "T_SWITCH", + "T_ENDSWITCH", + "T_CASE", + "T_DEFAULT", + "T_BREAK", + "T_CONTINUE", + "T_GOTO", + "T_FUNCTION", + "T_CONST", + "T_RETURN", + "T_TRY", + "T_CATCH", + "T_FINALLY", + "T_THROW", + "T_USE", + "T_INSTEADOF", + "T_GLOBAL", + "T_STATIC", + "T_ABSTRACT", + "T_FINAL", + "T_PRIVATE", + "T_PROTECTED", + "T_PUBLIC", + "T_VAR", + "T_UNSET", + "T_ISSET", + "T_EMPTY", + "T_HALT_COMPILER", + "T_CLASS", + "T_TRAIT", + "T_INTERFACE", + "T_EXTENDS", + "T_IMPLEMENTS", + "T_OBJECT_OPERATOR", + "T_LIST", + "T_ARRAY", + "T_CALLABLE", + "T_CLASS_C", + "T_TRAIT_C", + "T_METHOD_C", + "T_FUNC_C", + "T_LINE", + "T_FILE", + "T_START_HEREDOC", + "T_END_HEREDOC", + "T_DOLLAR_OPEN_CURLY_BRACES", + "T_CURLY_OPEN", + "T_PAAMAYIM_NEKUDOTAYIM", + "T_NAMESPACE", + "T_NS_C", + "T_DIR", + "T_NS_SEPARATOR", + "T_ELLIPSIS", + "';'", + "'{'", + "'}'", + "'('", + "')'", + "'$'", + "'`'", + "']'", + "'\"'" + ); + + protected $tokenToSymbol = array( + 0, 157, 157, 157, 157, 157, 157, 157, 157, 157, + 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, + 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, + 157, 157, 157, 53, 156, 157, 153, 52, 35, 157, + 151, 152, 50, 47, 7, 48, 49, 51, 157, 157, + 157, 157, 157, 157, 157, 157, 157, 157, 29, 148, + 41, 15, 43, 28, 65, 157, 157, 157, 157, 157, + 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, + 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, + 157, 67, 157, 155, 34, 157, 154, 157, 157, 157, + 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, + 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, + 157, 157, 157, 149, 33, 150, 55, 157, 157, 157, + 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, + 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, + 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, + 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, + 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, + 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, + 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, + 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, + 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, + 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, + 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, + 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, + 157, 157, 157, 157, 157, 157, 1, 2, 3, 4, + 5, 6, 8, 9, 10, 11, 12, 13, 14, 16, + 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, + 27, 30, 31, 32, 36, 37, 38, 39, 40, 42, + 44, 45, 46, 54, 56, 57, 58, 59, 60, 61, + 62, 63, 64, 66, 68, 69, 70, 71, 72, 73, + 74, 75, 76, 77, 78, 79, 80, 81, 157, 157, + 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, + 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, + 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, + 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, + 132, 133, 134, 135, 136, 137, 157, 157, 157, 157, + 157, 157, 138, 139, 140, 141, 142, 143, 144, 145, + 146, 147 + ); + + protected $action = array( + 674, 675, 676, 677, 678,-32766, 679, 680, 681, 717, + 718, 218, 219, 220, 221, 222, 223, 224, 225, 226, + 0, 227, 228, 229, 230, 231, 232, 233, 234, 235, + 236, 237, 238,-32766,-32766,-32766,-32766,-32766,-32766,-32766, + -32766,-32767,-32767,-32767,-32767, 442, 239, 240,-32766,-32766, + -32766,-32766, 682,-32766, 308,-32766,-32766,-32766,-32766,-32766, + -32766,-32767,-32767,-32767,-32767,-32767, 683, 684, 685, 686, + 687, 688, 689, 1174, 462, 749,-32766,-32766,-32766,-32766, + -32766, 25, 690, 691, 692, 693, 694, 695, 696, 697, + 698, 699, 700, 720, 721, 722, 723, 724, 712, 713, + 714, 715, 716, 701, 702, 703, 704, 705, 706, 707, + 743, 744, 745, 746, 747, 748, 708, 709, 710, 711, + 741, 732, 730, 731, 727, 728, 520, 719, 725, 726, + 733, 734, 736, 735, 737, 738, 54, 55, 422, 56, + 57, 729, 740, 739, 421, 58, 59, 341, 60,-32766, + -32766,-32766,-32766,-32766,-32766,-32766,-32766,-32766, 9,-32767, + -32767,-32767,-32767, 52, 327,-32766, 331, 947, 948, 949, + 946, 945, 944, 939, 1215, 29, 1217, 1216, 765, 766, + 823, 61, 62, 1101, -269, 1180, 764, 63, 1174, 64, + 293, 294, 65, 66, 67, 68, 69, 70, 71, 72, + 129, 26, 301, 73, 415,-32766,-32766,-32766,-32766, 1089, + 1090, 751, 635, 1180,-32766, 920, 206, 466,-32766,-32766, + -32766, 824, 409,-32766, 313,-32766, 902,-32766,-32766,-32766, + -32766,-32766,-32766, 215, 216, 217, 430,-32766,-32766,-32766, + -32766,-32766,-32766,-32766,-32766, 122, 493, 947, 948, 949, + 946, 945, 944, 202, 475, 476, 284, 625, 127, 336, + 895, 896, 341, 479, 480, 1187, 1095, 1096, 1097, 1098, + 1092, 1093, 309, 494, 10, 443, 427, 494, 1099, 1094, + 427, 587, -220, 1212, 123, 41, 449, 336, 323, 1056, + 324, 423, -122, -122, -122, -4, 824, 465, 101, 102, + 103, 813, 303, 282, 40, 21, 424, -122, 467, -122, + 468, -122, 469, -122, 104, 425, 215, 216, 217, 30, + 31, 470, 426, 626, 32, 471, 427, 814, 74, 871, + 925, 351, 352, 472, 473, 358, 202, 243, 1101, 474, + 414, 1184, 795, 842, 477, 478, 300, 236, 237, 238, + 35, 105, 106, 107, 108, 109, 110, 111, 112, 113, + 114, 115, 116, 239, 240, 1038, 423, 350, 826, 640, + -122, 824, 465, 215, 216, 217, 813, 1140, 241, 40, + 21, 424, 48, 467, 440, 468, 334, 469, 297, 1038, + 425, 977, 979, 202, 30, 31, 470, 426, 416, 32, + 471, 1188, 1038, 74, 322, 1038, 351, 352, 472, 473, + -32766,-32766,-32766, 128, 474, 921, 811, 757, 842, 477, + 478,-32767,-32767,-32767,-32767, 96, 97, 98, 99, 100, + -32766, 20,-32766,-32766,-32766,-32766, 895, 896, 335, 1038, + 479, 423, -216, 826, 640, -4, 824, 465, 872, 494, + 1207, 813, 427, 1206, 40, 21, 424, 299, 467, 121, + 468, 1038, 469, -497, 118, 425, -201, -201, -201, 30, + 31, 470, 426, 297, 32, 471, 810, 911, 74, 216, + 217, 351, 352, 472, 473,-32766,-32766,-32766, 36, 474, + 51, 340, 795, 842, 477, 478, 207, 751, 202, 1180, + 126,-32766,-32766,-32766, 441,-32766, 417,-32766,-32766,-32766, + 49, 33, 296,-32766,-32766,-32766, 423, 208, 826, 640, + -201,-32766, 465,-32766,-32766, 807, 813, 379, 117, 40, + 21, 424, 1066, 467,-32766, 468, 217, 469, 805, 245, + 425, -200, -200, -200, 30, 31, 470, 426, 1038, 32, + 471, 286, 548, 74, 202, 824, 351, 352, 472, 473, + -32766,-32766,-32766, 494, 474, 125, 427, 795, 842, 477, + 478, 431, 120, 336, 1038, 803, 78, 79, 80, 494, + -32766, 436, 427, 646, 642, 126,-32766,-32766,-32766, 244, + 901, 246, 119, 826, 640, -200, 34, 298, 81, 82, + 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, + 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, + 103, 209, 303, 202, 824, 423, 822, 1038, 215, 216, + 217, 465, 131, 130, 104, 813, 578, 1038, 40, 21, + 424, 650, 467, 835, 468, 647, 469, 315, 202, 425, + 285, 104, 643, 30, 31, 470, 824,-32766, 32, 471, + 295, 303, 74,-32766,-32766, 351, 352, 215, 216, 217, + -32766,-32766, 50, 474, 98, 99, 100, 233, 234, 235, + 239, 240, 456, 593, 644, 451, 22, 202, 132, 359, + 765, 766, 601, 602, 423, 758, 645, 924, 668, 301, + 465, 47, 858, 640, 813, 936, 656, 40, 21, 424, + 43, 467, 46, 468, 45, 469, 44, 53, 425, 751, + 607, 514, 30, 31, 470, 824, 423, 32, 471, 778, + 752, 74, 465, 437, 351, 352, 813, 535, 519, 40, + 21, 424, 474, 467, 536, 468, 1210, 469, 515, 435, + 425, 439, 518, 648, 30, 31, 470, 824, 624, 32, + 471, 614, 604, 74, 1059, 581, 351, 352,-32766, 526, + 634, 826, 640, 611, 474, 1139, 460, 434, 281, 621, + 328, 844, 314, 539, 14, 653, -80, 597, 837, 584, + 330, 843, 325, -398, 395, 423, 1146, 0, 0, 0, + 0, 465, 1100, 826, 640, 813, 598, 0, 40, 21, + 424, 0, 467, 0, 468, 0, 469, 0, 372, 425, + 0, 326, 0, 30, 31, 470, 824, 423, 32, 471, + 312, -498, 74, 465, -497, 351, 352, 813, 479, 0, + 40, 21, 424, 474, 467, 374, 468, 5, 469, 6, + 11, 425, -407, 13, -406, 30, 31, 470, 1036, 386, + 32, 471, 411, 410, 74, 387, 528, 351, 352, 436, + 856, 1213, 826, 640, 866, 474, 865, 874, 815, 800, + 821, 809, 763, 661, 660, 39, 38, 854, 931, 932, + 929, 859, 930, 820, 808, 761, 423, 928, 806, 804, + 798, 812, 465, 762, 826, 640, 813, 649, 77, 40, + 21, 424, 651, 467, 652, 468, 242, 469, 654, 655, + 425, 658, 663, 664, 30, 31, 470, 665, 124, 32, + 471, 332, 333, 74, 210, 211, 351, 352, 407, 641, + 212, 408, 213, 768, 474, 767, 864, 455, 1211, 1181, + 1179, 1165, 1177, 1080, 204, 913, 1185, 1175, 838, 210, + 211, 1040, 1089, 1090, 1041, 212,-32766, 213, 829, 863, + 1091, 1052, 759, 826, 640, 306, 839, 840, 760, 204, + 1214, 796, 662, 841, 770, 769, 937, 1089, 1090, 831, + 1042,-32766, 305, 304, 24, 1091, 27, 292, 291, 283, + 307, 338, 413, 419, 28, 205, 37, 42, 76, 75, + -32766, 0, 1018, 1017, 1082, 571, -216, 567, 1105, 1095, + 1096, 1097, 1098, 1092, 1093, 385, 903, 1046, 1043, 631, + 561, 1099, 1094, 463, 459, 457, 452, 380, 214, 0, + -32766, 18, 567, -217, 1095, 1096, 1097, 1098, 1092, 1093, + 385, 17, 16, 605, 0, -416, 1099, 1094, 1160, 1159, + 1106, 1209, 1079, 214, 1176,-32766, 1047, 0, 1164, 1178, + 1065, 1050, 1051, 1048, 1049, 0, 1145 + ); + + protected $actionCheck = array( + 2, 3, 4, 5, 6, 8, 8, 9, 10, 11, + 12, 31, 32, 33, 34, 35, 36, 37, 38, 39, + 0, 41, 42, 43, 44, 45, 46, 47, 48, 49, + 50, 51, 52, 8, 9, 10, 31, 32, 33, 34, + 35, 36, 37, 38, 39, 7, 66, 67, 31, 32, + 33, 34, 54, 28, 7, 30, 31, 32, 33, 34, + 35, 36, 37, 38, 39, 40, 68, 69, 70, 71, + 72, 73, 74, 79, 7, 77, 31, 32, 33, 34, + 35, 7, 84, 85, 86, 87, 88, 89, 90, 91, + 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, + 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, + 122, 123, 124, 125, 126, 127, 82, 129, 130, 131, + 132, 133, 134, 135, 136, 137, 2, 3, 4, 5, + 6, 143, 144, 145, 7, 11, 12, 153, 14, 31, + 32, 33, 34, 35, 36, 37, 38, 39, 103, 41, + 42, 43, 44, 67, 109, 79, 7, 112, 113, 114, + 115, 116, 117, 118, 77, 7, 79, 80, 102, 103, + 1, 47, 48, 139, 79, 79, 148, 53, 79, 55, + 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, + 67, 67, 68, 69, 70, 8, 9, 10, 103, 75, + 76, 77, 77, 79, 109, 148, 7, 83, 8, 9, + 10, 1, 146, 118, 128, 28, 152, 30, 31, 32, + 33, 34, 35, 8, 9, 10, 102, 151, 28, 153, + 30, 31, 32, 33, 34, 149, 112, 112, 113, 114, + 115, 116, 117, 28, 120, 121, 7, 77, 149, 153, + 130, 131, 153, 129, 130, 1, 132, 133, 134, 135, + 136, 137, 138, 143, 7, 7, 146, 143, 144, 145, + 146, 82, 152, 150, 7, 151, 7, 153, 154, 152, + 156, 71, 72, 73, 74, 0, 1, 77, 50, 51, + 52, 81, 54, 13, 84, 85, 86, 87, 88, 89, + 90, 91, 92, 93, 66, 95, 8, 9, 10, 99, + 100, 101, 102, 143, 104, 105, 146, 148, 108, 29, + 150, 111, 112, 113, 114, 7, 28, 29, 139, 119, + 7, 77, 122, 123, 124, 125, 35, 50, 51, 52, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 66, 67, 12, 71, 7, 148, 149, + 150, 1, 77, 8, 9, 10, 81, 152, 13, 84, + 85, 86, 67, 88, 29, 90, 7, 92, 35, 12, + 95, 56, 57, 28, 99, 100, 101, 102, 103, 104, + 105, 152, 12, 108, 109, 12, 111, 112, 113, 114, + 8, 9, 10, 149, 119, 148, 148, 122, 123, 124, + 125, 41, 42, 43, 44, 45, 46, 47, 48, 49, + 28, 152, 30, 31, 32, 33, 130, 131, 143, 12, + 129, 71, 152, 148, 149, 150, 1, 77, 148, 143, + 79, 81, 146, 82, 84, 85, 86, 7, 88, 13, + 90, 12, 92, 128, 149, 95, 96, 97, 98, 99, + 100, 101, 102, 35, 104, 105, 148, 79, 108, 9, + 10, 111, 112, 113, 114, 8, 9, 10, 13, 119, + 67, 67, 122, 123, 124, 125, 15, 77, 28, 79, + 147, 8, 9, 10, 149, 28, 123, 30, 31, 32, + 67, 140, 141, 8, 9, 10, 71, 15, 148, 149, + 150, 28, 77, 30, 31, 148, 81, 78, 15, 84, + 85, 86, 112, 88, 151, 90, 10, 92, 148, 15, + 95, 96, 97, 98, 99, 100, 101, 102, 12, 104, + 105, 153, 128, 108, 28, 1, 111, 112, 113, 114, + 8, 9, 10, 143, 119, 29, 146, 122, 123, 124, + 125, 151, 149, 153, 12, 148, 8, 9, 10, 143, + 28, 146, 146, 29, 149, 147, 31, 32, 33, 15, + 152, 15, 149, 148, 149, 150, 28, 35, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, + 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, + 52, 15, 54, 28, 1, 71, 29, 12, 8, 9, + 10, 77, 149, 29, 66, 81, 153, 12, 84, 85, + 86, 29, 88, 35, 90, 29, 92, 29, 28, 95, + 35, 66, 29, 99, 100, 101, 1, 31, 104, 105, + 35, 54, 108, 31, 32, 111, 112, 8, 9, 10, + 8, 9, 67, 119, 47, 48, 49, 47, 48, 49, + 66, 67, 72, 73, 29, 72, 73, 28, 97, 98, + 102, 103, 106, 107, 71, 148, 149, 148, 149, 68, + 77, 67, 148, 149, 81, 148, 149, 84, 85, 86, + 67, 88, 67, 90, 67, 92, 67, 67, 95, 77, + 74, 77, 99, 100, 101, 1, 71, 104, 105, 77, + 77, 108, 77, 77, 111, 112, 81, 77, 77, 84, + 85, 86, 119, 88, 77, 90, 77, 92, 77, 77, + 95, 86, 79, 29, 99, 100, 101, 1, 79, 104, + 105, 79, 79, 108, 79, 87, 111, 112, 82, 82, + 89, 148, 149, 93, 119, 155, 102, 102, 94, 91, + 110, 123, 128, 94, 94, 29, 94, 96, 147, 96, + 126, 123, 126, 142, 146, 71, 139, -1, -1, -1, + -1, 77, 139, 148, 149, 81, 109, -1, 84, 85, + 86, -1, 88, -1, 90, -1, 92, -1, 142, 95, + -1, 127, -1, 99, 100, 101, 1, 71, 104, 105, + 128, 128, 108, 77, 128, 111, 112, 81, 129, -1, + 84, 85, 86, 119, 88, 146, 90, 142, 92, 142, + 142, 95, 142, 142, 142, 99, 100, 101, 154, 146, + 104, 105, 146, 146, 108, 146, 146, 111, 112, 146, + 148, 150, 148, 149, 148, 119, 148, 148, 148, 148, + 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, + 148, 148, 148, 148, 148, 148, 71, 148, 148, 148, + 148, 148, 77, 148, 148, 149, 81, 149, 149, 84, + 85, 86, 149, 88, 149, 90, 29, 92, 149, 149, + 95, 149, 149, 149, 99, 100, 101, 149, 149, 104, + 105, 149, 149, 108, 47, 48, 111, 112, 149, 149, + 53, 149, 55, 150, 119, 150, 150, 150, 150, 150, + 150, 150, 150, 150, 67, 150, 150, 150, 150, 47, + 48, 150, 75, 76, 150, 53, 79, 55, 150, 150, + 83, 150, 150, 148, 149, 151, 150, 150, 150, 67, + 150, 150, 150, 150, 150, 150, 150, 75, 76, 150, + 152, 79, 151, 151, 151, 83, 151, 151, 151, 151, + 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, + 151, -1, 152, 152, 152, 152, 152, 130, 152, 132, + 133, 134, 135, 136, 137, 138, 152, 152, 152, 152, + 152, 144, 145, 152, 152, 152, 152, 152, 151, -1, + 153, 152, 130, 152, 132, 133, 134, 135, 136, 137, + 138, 152, 152, 155, -1, 154, 144, 145, 155, 155, + 155, 155, 155, 151, 155, 153, 155, -1, 155, 155, + 155, 155, 155, 155, 155, -1, 156 + ); + + protected $actionBase = array( + 0, 220, 295, 370, 445, 109, 109, 180, 744, -2, + -2, -2, -2, -2, 135, 655, 724, 756, 724, 623, + 554, 825, 825, 825, 438, 353, 625, 625, 862, 625, + 427, 390, 377, 449, 536, 615, 562, 393, 393, 393, + 393, 134, 134, 393, 393, 393, 393, 393, 393, 393, + 393, 393, 393, 393, 393, 393, 393, 393, 393, 393, + 393, 393, 393, 393, 393, 393, 393, 393, 393, 393, + 393, 393, 393, 393, 393, 393, 393, 393, 393, 393, + 393, 393, 393, 393, 393, 393, 393, 393, 393, 393, + 393, 393, 393, 393, 393, 393, 393, 393, 393, 393, + 393, 393, 393, 393, 393, 393, 393, 393, 393, 393, + 393, 393, 393, 393, 393, 393, 393, 393, 393, 393, + 393, 393, 393, 393, 393, 393, 393, 393, 393, 393, + 393, 393, 393, 300, 179, 446, 475, 751, 750, 746, + 745, 838, 684, 860, 798, 799, 604, 800, 801, 802, + 803, 805, 797, 806, 898, 807, 568, 568, 568, 568, + 568, 568, 568, 568, 568, 568, 568, -3, 365, 225, + 308, 620, 662, 659, 659, 659, 659, 659, 659, 659, + 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, + 505, 505, 505, 505, 505, 505, 505, 470, 552, 552, + 552, 526, 887, 595, 912, 912, 912, 912, 912, 912, + 912, 912, 912, 912, 912, 912, 912, 912, 912, 912, + 912, 912, 912, 912, 912, 912, 912, 912, 912, 912, + 912, 912, 912, 912, 912, 912, 912, 912, 912, 912, + 912, 912, 912, 912, 912, 912, 912, 493, -20, -20, + 477, 626, 402, 632, 210, 555, 197, 25, 25, 25, + 25, 25, 17, 45, 5, 5, 5, 5, 335, 380, + 380, 380, 380, 118, 118, 118, 118, 833, 827, 826, + 821, 311, 311, 709, 709, 631, 779, 627, 627, 630, + 630, 420, 420, 420, 420, 420, 420, 420, 420, 420, + 420, 383, 105, 859, 130, 130, 130, 130, 306, 44, + 657, 920, 264, 264, 264, 306, 248, 248, 248, 297, + 297, 297, 76, 687, 371, 86, 86, 86, 86, 371, + 86, 86, 588, 588, 588, 435, 759, 686, 436, 443, + 97, 483, 693, 819, 691, 796, 549, 710, 96, 717, + 716, 398, 675, 613, 610, 586, 651, 355, 398, 300, + 557, 423, 607, 753, 667, 38, 747, 328, 268, 424, + 547, 315, -6, 279, 782, 755, 863, 861, 249, 133, + 703, 607, 607, 607, 74, 199, 783, 789, 315, 290, + 614, 614, 614, 614, 835, 792, 614, 614, 614, 614, + 834, 795, 267, 67, 793, 137, 749, 642, 642, 642, + 642, 642, 642, 608, 642, 853, 671, 843, 843, 660, + 683, 608, 856, 856, 856, 856, 608, 642, 843, 843, + 608, 631, 843, 168, 608, 666, 642, 664, 664, 856, + 736, 735, 671, 673, 694, 843, 843, 843, 694, 660, + 608, 856, 697, 641, 209, 843, 856, 618, 618, 697, + 608, 618, 683, 618, 20, 597, 643, 855, 858, 852, + 644, 790, 668, 658, 847, 846, 857, 661, 672, 848, + 845, 720, 734, 733, 656, 513, 649, 647, 645, 634, + 705, 605, 702, 675, 723, 585, 585, 585, 706, 707, + 706, 585, 585, 585, 585, 585, 585, 585, 585, 911, + 712, 676, 654, 665, 732, 481, 699, 689, 502, 772, + 663, 720, 720, 831, 876, 885, 901, 704, 653, 842, + 878, 706, 919, 738, 277, 606, 841, 832, 713, 652, + 719, 706, 824, 706, 773, 706, 875, 830, 669, 720, + 828, 585, 874, 918, 917, 916, 915, 914, 913, 903, + 909, 650, 907, 731, 678, 884, 47, 854, 651, 708, + 648, 730, 159, 906, 822, 706, 706, 774, 759, 706, + 778, 729, 737, 900, 728, 883, 905, 663, 882, 706, + 674, 904, 159, 616, 646, 891, 680, 726, 851, 682, + 866, 850, 758, 574, 524, 721, 612, 752, 899, 889, + 864, 743, 763, 765, 576, 688, 685, 679, 839, 769, + 849, 722, 808, 811, 877, 692, 723, 711, 670, 690, + 681, 770, 814, 881, 739, 740, 741, 818, 742, 836, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 134, 134, 134, 134, -2, -2, -2, -2, 0, 0, + 0, 0, 0, -2, 134, 134, 134, 134, 134, 134, + 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, + 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, + 0, 0, 134, 134, 134, 134, 134, 134, 134, 134, + 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, + 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, + 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, + 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, + 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, + 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, + 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, + 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, + 134, 134, 568, 568, 568, 568, 568, 568, 568, 568, + 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, + 568, 568, 568, 568, 568, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 568, -20, -20, -20, + -20, 568, -20, -20, -20, -20, -20, -20, -20, 568, + 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, + 568, 568, 568, 568, 568, 568, -20, 568, 568, 568, + -20, 420, -20, 420, 420, 420, 420, 420, 420, 420, + 420, 420, 420, 420, 420, 420, 420, 420, 420, 420, + 420, 420, 420, 420, 420, 420, 420, 420, 420, 420, + 420, 420, 420, 420, 420, 420, 420, 420, 420, 420, + 420, 420, 420, 420, 420, 420, 568, 0, 0, 568, + -20, 568, -20, 568, -20, 568, 568, 568, 568, 568, + 568, -20, -20, -20, -20, -20, -20, 0, 248, 248, + 248, 248, -20, -20, -20, -20, 55, 55, 55, 55, + 420, 420, 420, 420, 420, 420, 248, 248, 297, 297, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 420, 55, 420, 642, 642, 642, 642, 642, 371, 371, + 371, 106, 106, 106, 642, 0, 0, 0, 0, 0, + 0, 642, 371, 0, 420, 420, 420, 420, 0, 420, + 420, 642, 642, 642, 642, 106, 371, 642, 843, 0, + 106, 591, 591, 591, 591, 159, 315, 0, 642, 642, + 0, 673, 0, 0, 0, 843, 0, 0, 0, 0, + 0, 585, 277, 842, 0, 360, 0, 0, 0, 0, + 0, 0, 0, 653, 360, 450, 450, 0, 0, 650, + 585, 585, 585, 0, 0, 653, 653, 0, 0, 0, + 0, 0, 0, 379, 653, 0, 0, 0, 0, 379, + 333, 0, 0, 333, 0, 159 + ); + + protected $actionDefault = array( + 3,32767,32767,32767,32767,32767,32767,32767,32767,32767, + 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, + 32767,32767,32767,32767,32767,32767, 525, 525,32767, 481, + 32767,32767,32767,32767,32767,32767,32767, 287, 287, 287, + 32767,32767,32767, 513, 513, 513, 513, 513, 513, 513, + 513, 513, 513, 513,32767,32767,32767,32767,32767, 369, + 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, + 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, + 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, + 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, + 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, + 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, + 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, + 32767,32767,32767,32767,32767, 375, 530,32767,32767,32767, + 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, + 32767,32767,32767,32767,32767,32767, 350, 351, 353, 354, + 286, 514, 237, 376, 529, 285, 239, 314, 485,32767, + 32767,32767, 316, 116, 248, 193, 484, 119, 284, 224, + 368, 370, 315, 291, 296, 297, 298, 299, 300, 301, + 302, 303, 304, 305, 306, 307, 290, 441, 347, 346, + 345, 443,32767, 442, 478, 478, 481,32767,32767,32767, + 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, + 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, + 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, + 32767,32767,32767,32767,32767,32767,32767, 312, 469, 468, + 313, 439, 317, 440, 319, 444, 318, 335, 336, 333, + 334, 337, 446, 445, 462, 463, 460, 461, 289, 338, + 339, 340, 341, 464, 465, 466, 467, 271, 271, 271, + 271,32767,32767, 524, 524,32767,32767, 326, 327, 453, + 454,32767,32767,32767,32767,32767,32767,32767,32767,32767, + 32767,32767, 272,32767, 228, 228, 228, 228, 228,32767, + 32767,32767,32767,32767,32767,32767, 321, 322, 320, 448, + 449, 447,32767, 415,32767,32767,32767,32767,32767, 417, + 32767,32767,32767,32767,32767,32767,32767,32767,32767, 486, + 32767,32767,32767,32767,32767,32767,32767, 499, 404,32767, + 32767,32767, 397, 212, 214, 161, 472,32767,32767,32767, + 32767, 504, 331,32767,32767,32767,32767,32767,32767, 539, + 32767, 499,32767,32767,32767,32767,32767,32767,32767,32767, + 344, 323, 324, 325,32767,32767,32767,32767, 503, 497, + 456, 457, 458, 459,32767,32767, 450, 451, 452, 455, + 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, + 32767,32767,32767, 165,32767, 412,32767, 418, 418,32767, + 32767, 165,32767,32767,32767,32767, 165,32767, 502, 501, + 165,32767, 398, 480, 165, 178,32767, 176, 176,32767, + 198, 198,32767,32767, 180, 473, 492,32767, 180,32767, + 165,32767, 386, 167, 480,32767,32767, 230, 230, 386, + 165, 230,32767, 230,32767, 82, 422,32767,32767,32767, + 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, + 32767, 399,32767,32767,32767,32767, 365, 366, 475, 488, + 32767, 489,32767, 397,32767, 329, 330, 332, 309,32767, + 311, 355, 356, 357, 358, 359, 360, 361, 363,32767, + 402,32767, 405,32767,32767,32767, 84, 108, 247,32767, + 537, 84, 400,32767,32767, 294, 537,32767,32767,32767, + 32767, 532,32767,32767, 288,32767,32767,32767, 84,32767, + 84, 243,32767, 163,32767, 522,32767, 497,32767, 401, + 32767, 328,32767,32767,32767,32767,32767,32767,32767,32767, + 32767, 498,32767,32767,32767,32767, 219,32767, 435,32767, + 84,32767, 179,32767,32767, 292, 238,32767,32767, 531, + 32767,32767,32767,32767,32767,32767,32767,32767,32767, 164, + 32767,32767, 181,32767,32767, 497,32767,32767,32767,32767, + 32767,32767,32767,32767, 283,32767,32767,32767,32767,32767, + 497,32767,32767,32767, 223,32767,32767,32767,32767,32767, + 32767,32767,32767,32767,32767, 82, 60,32767, 265,32767, + 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, + 121, 121, 3, 121, 121, 3, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 206, 250, 209, + 198, 198, 158, 250, 250, 250, 121, 121, 257 + ); + + protected $goto = array( + 162, 162, 136, 136, 141, 136, 137, 138, 139, 144, + 146, 183, 164, 160, 160, 160, 160, 141, 141, 161, + 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, + 156, 157, 158, 159, 180, 135, 181, 495, 496, 362, + 497, 501, 502, 503, 504, 505, 506, 507, 508, 964, + 140, 142, 143, 145, 167, 172, 182, 198, 247, 250, + 252, 254, 256, 257, 258, 259, 260, 261, 269, 270, + 271, 272, 287, 288, 316, 317, 318, 381, 382, 383, + 551, 184, 185, 186, 187, 188, 189, 190, 191, 192, + 193, 194, 195, 196, 147, 148, 149, 163, 150, 165, + 151, 199, 166, 152, 153, 154, 200, 155, 133, 627, + 569, 786, 569, 569, 569, 569, 569, 569, 569, 569, + 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, + 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, + 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, + 569, 569, 569, 569, 569, 1102, 636, 1102, 1102, 1102, + 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, + 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, + 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, + 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, + 525, 817, 499, 499, 499, 499, 499, 499, 1171, 510, + 1171, 510, 499, 499, 499, 499, 499, 499, 499, 499, + 499, 499, 511, 552, 511, 582, 608, 524, 887, 887, + 1192, 1192, 755, 851, 851, 851, 851, 170, 846, 852, + 524, 524, 173, 174, 175, 390, 391, 392, 393, 169, + 197, 201, 203, 251, 253, 255, 262, 263, 264, 265, + 266, 267, 273, 274, 275, 276, 289, 290, 319, 320, + 321, 396, 397, 398, 399, 171, 176, 248, 249, 177, + 178, 179, 389, 610, 545, 545, 575, 541, 8, 343, + 1078, 1077, 543, 543, 498, 500, 531, 547, 576, 579, + 589, 595, 550, 756, 568, 574, 568, 568, 568, 568, + 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, + 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, + 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, + 568, 568, 568, 568, 568, 568, 568, 568, 568, 516, + 445, 447, 935, 638, 329, 311, 1103, 620, 933, 521, + 521, 521, 521, 779, 553, 554, 555, 556, 557, 558, + 559, 560, 562, 591, 857, 613, 540, 521, 619, 512, + 360, 512, 905, 432, 432, 432, 432, 432, 432, 546, + 779, 779, 1196, 432, 432, 432, 432, 432, 432, 432, + 432, 432, 432, 1067, 1163, 1067, 894, 894, 894, 894, + 894, 1170, 363, 1170, 585, 588, 633, 894, 371, 371, + 371, 1060, 1186, 1186, 1186, 3, 4, 1067, 1067, 1067, + 1067, 600, 1067, 1067, 521, 521, 538, 570, 521, 521, + 617, 521, 371, 1151, 962, 609, 1169, 388, 772, 772, + 780, 780, 780, 782, 522, 771, 1189, 1202, 1202, 537, + 377, 659, 564, 549, 596, 884, 615, 618, 880, 622, + 623, 630, 632, 637, 639, 900, 1202, 1203, 1203, 364, + 592, 346, 406, 529, 1205, 754, 891, 542, 278, 279, + 280, 1011, 349, 1063, 1064, 400, 1203, 1060, 873, 855, + 853, 855, 657, 453, 513, 882, 877, 1083, 344, 345, + 1061, 1162, 1061, 12, 1021, 19, 15, 357, 775, 773, + 1062, 370, 375, 909, 404, 666, 1053, 448, 1058, 783, + 580, 563, 861, 914, 1148, 461, 951, 0, 0, 0, + 0, 0, 0, 23, 0, 0, 0, 0, 606, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 943, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 530 + ); + + protected $gotoCheck = array( + 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, 39, 53, + 63, 25, 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 119, 5, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, + 94, 46, 110, 110, 110, 110, 110, 110, 111, 63, + 111, 63, 110, 110, 110, 110, 110, 110, 110, 110, + 110, 110, 110, 40, 110, 36, 36, 40, 71, 71, + 71, 71, 11, 63, 63, 63, 63, 23, 63, 63, + 40, 40, 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 47, 47, 47, 47, 47, 47, 91, 66, + 117, 117, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 2, 12, 53, 2, 53, 53, 53, 53, + 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, + 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, + 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, + 53, 53, 53, 53, 53, 53, 53, 53, 53, 8, + 7, 7, 7, 7, 118, 118, 7, 7, 7, 8, + 8, 8, 8, 19, 103, 103, 103, 103, 103, 103, + 103, 103, 103, 103, 29, 57, 8, 8, 57, 115, + 57, 115, 78, 53, 53, 53, 53, 53, 53, 102, + 19, 19, 132, 53, 53, 53, 53, 53, 53, 53, + 53, 53, 53, 53, 76, 53, 53, 53, 53, 53, + 53, 112, 43, 112, 56, 56, 56, 53, 116, 116, + 116, 76, 112, 112, 112, 26, 26, 53, 53, 53, + 53, 120, 53, 53, 8, 8, 8, 8, 8, 8, + 53, 8, 116, 124, 94, 45, 112, 116, 19, 19, + 19, 19, 19, 19, 8, 19, 130, 133, 133, 28, + 44, 28, 28, 8, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 75, 133, 134, 134, 54, + 64, 64, 64, 54, 133, 10, 73, 54, 61, 61, + 61, 95, 14, 76, 76, 18, 134, 76, 10, 10, + 10, 10, 10, 54, 10, 10, 10, 30, 66, 66, + 76, 76, 76, 54, 30, 30, 30, 30, 21, 20, + 76, 9, 13, 79, 17, 68, 106, 59, 108, 22, + 60, 30, 65, 80, 123, 101, 93, -1, -1, -1, + -1, -1, -1, 30, -1, -1, -1, -1, 30, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 91, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 94 + ); + + protected $gotoBase = array( + 0, 0, -340, 0, 0, 142, 0, 345, 27, 186, + 483, 230, 301, 173, 170, 0, 0, 116, 162, 41, + 169, 184, 87, 35, 0, 101, -241, 0, -182, 354, + 92, 0, 0, 0, 0, 0, 187, 0, 0, -24, + 199, 0, 0, 372, 168, 163, 183, 1, 0, 0, + 0, 0, 0, 102, 53, 0, 109, -83, 0, 89, + 82, -175, 0, -92, 154, 83, -152, 0, 166, 0, + 0, -53, 0, 178, 0, 160, 65, 0, 357, 165, + 90, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 274, 0, 74, 159, 188, 0, 0, 0, 0, + 0, 76, 362, 320, 0, 0, 108, 0, 107, 0, + -79, -93, 110, 0, 0, 78, 106, -23, 31, -47, + 226, 0, 0, 80, 237, 0, 0, 0, 0, 0, + 172, 0, 363, 147, 167, 0, 0 + ); + + protected $gotoDefault = array( + -32768, 464, 670, 2, 671, 742, 750, 603, 481, 517, + 792, 793, 794, 366, 412, 482, 365, 401, 394, 781, + 774, 776, 784, 168, 402, 787, 1, 789, 523, 825, + 1012, 353, 797, 354, 594, 799, 533, 801, 802, 134, + 483, 367, 368, 534, 376, 583, 816, 268, 373, 818, + 355, 819, 828, 356, 616, 599, 565, 612, 484, 444, + 577, 277, 544, 1075, 572, 860, 342, 868, 667, 876, + 879, 485, 566, 890, 450, 898, 1088, 384, 904, 910, + 915, 918, 420, 403, 590, 922, 923, 7, 927, 628, + 629, 942, 302, 950, 963, 418, 1031, 1033, 486, 487, + 527, 458, 509, 532, 488, 1054, 438, 405, 1057, 489, + 490, 428, 429, 1072, 348, 1156, 347, 446, 310, 1143, + 586, 1107, 454, 1195, 1152, 339, 491, 492, 361, 378, + 1190, 433, 1197, 1204, 337, 369, 573 + ); + + protected $ruleToNonTerminal = array( + 0, 1, 3, 3, 2, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, + 7, 7, 8, 8, 9, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 14, 14, 15, 15, + 15, 15, 17, 17, 13, 13, 18, 18, 19, 19, + 20, 20, 21, 21, 16, 16, 22, 24, 24, 25, + 26, 26, 28, 27, 27, 27, 27, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 10, 10, 50, 50, + 52, 51, 51, 44, 44, 54, 54, 55, 55, 11, + 12, 12, 12, 58, 58, 58, 59, 59, 62, 62, + 60, 60, 64, 64, 37, 37, 46, 46, 49, 49, + 49, 48, 48, 65, 38, 38, 38, 38, 66, 66, + 67, 67, 68, 68, 35, 35, 31, 31, 69, 33, + 33, 70, 32, 32, 34, 34, 45, 45, 45, 56, + 56, 72, 72, 73, 73, 75, 75, 75, 74, 74, + 57, 57, 76, 76, 76, 77, 77, 78, 78, 78, + 41, 41, 79, 79, 79, 42, 42, 80, 80, 61, + 61, 81, 81, 81, 81, 86, 86, 87, 87, 88, + 88, 88, 88, 88, 89, 90, 90, 85, 85, 82, + 82, 84, 84, 92, 92, 91, 91, 91, 91, 91, + 91, 83, 83, 93, 93, 43, 43, 36, 36, 39, + 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 30, 30, 40, 40, 98, 98, 99, + 99, 99, 99, 105, 94, 94, 101, 101, 107, 107, + 108, 109, 109, 109, 109, 109, 109, 63, 63, 53, + 53, 53, 95, 95, 113, 113, 110, 110, 114, 114, + 114, 114, 96, 96, 96, 100, 100, 100, 106, 106, + 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 23, 23, 23, 23, 23, 23, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 104, 104, 97, 97, 97, 97, 120, 120, + 123, 123, 122, 122, 124, 124, 47, 47, 47, 47, + 126, 126, 125, 125, 125, 125, 125, 127, 127, 112, + 112, 115, 115, 111, 111, 128, 128, 128, 128, 116, + 116, 116, 116, 103, 103, 117, 117, 117, 117, 71, + 129, 129, 130, 130, 130, 102, 102, 131, 131, 132, + 132, 132, 132, 118, 118, 118, 118, 134, 135, 133, + 133, 133, 133, 133, 133, 133, 136, 136, 136 + ); + + protected $ruleToLength = array( + 1, 1, 2, 0, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 3, 1, 1, 1, 1, 1, 3, + 5, 4, 3, 4, 2, 3, 1, 1, 7, 8, + 6, 7, 3, 1, 3, 1, 3, 1, 1, 3, + 1, 2, 1, 2, 3, 1, 3, 3, 1, 3, + 2, 0, 1, 1, 1, 1, 1, 3, 5, 8, + 3, 5, 9, 3, 2, 3, 2, 3, 2, 3, + 2, 3, 3, 3, 1, 2, 5, 7, 9, 5, + 6, 3, 3, 2, 2, 1, 1, 1, 0, 2, + 8, 0, 4, 1, 3, 0, 1, 0, 1, 10, + 7, 6, 5, 1, 2, 2, 0, 2, 0, 2, + 0, 2, 1, 3, 1, 4, 1, 4, 1, 1, + 4, 1, 3, 3, 3, 4, 4, 5, 0, 2, + 4, 3, 1, 1, 1, 4, 0, 2, 3, 0, + 2, 4, 0, 2, 0, 3, 1, 2, 1, 1, + 0, 1, 3, 4, 6, 1, 1, 1, 0, 1, + 0, 2, 2, 3, 3, 1, 3, 1, 2, 2, + 3, 1, 1, 2, 4, 3, 1, 1, 3, 2, + 0, 3, 3, 9, 3, 1, 3, 0, 2, 4, + 5, 4, 4, 4, 3, 1, 1, 1, 3, 1, + 1, 0, 1, 1, 2, 1, 1, 1, 1, 1, + 1, 1, 3, 1, 3, 3, 1, 0, 1, 1, + 3, 3, 4, 4, 1, 2, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, + 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, + 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 1, 3, 5, 4, 3, 4, 4, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 1, 1, 1, 3, 2, 1, + 2, 10, 11, 3, 3, 2, 4, 4, 3, 4, + 4, 4, 4, 7, 3, 2, 0, 4, 1, 3, + 2, 2, 4, 6, 2, 2, 4, 1, 1, 1, + 2, 3, 1, 1, 1, 1, 1, 1, 3, 3, + 4, 4, 0, 2, 1, 0, 1, 1, 0, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 3, 2, 1, 3, 1, 4, 3, 1, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, + 3, 3, 3, 3, 3, 3, 3, 3, 5, 4, + 4, 3, 1, 3, 1, 1, 3, 3, 0, 2, + 0, 1, 3, 1, 3, 1, 1, 1, 1, 1, + 6, 4, 3, 4, 2, 4, 4, 1, 3, 1, + 2, 1, 1, 4, 1, 3, 6, 4, 4, 4, + 4, 1, 4, 0, 1, 1, 3, 1, 1, 4, + 3, 1, 1, 1, 0, 0, 2, 3, 1, 3, + 1, 4, 2, 2, 2, 1, 2, 1, 1, 1, + 4, 3, 3, 3, 6, 3, 1, 1, 1 + ); + + protected function reduceRule0() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule1() { + $this->semValue = $this->handleNamespaces($this->semStack[$this->stackPos-(1-1)]); + } + + protected function reduceRule2() { + if (is_array($this->semStack[$this->stackPos-(2-2)])) { $this->semValue = array_merge($this->semStack[$this->stackPos-(2-1)], $this->semStack[$this->stackPos-(2-2)]); } else { $this->semStack[$this->stackPos-(2-1)][] = $this->semStack[$this->stackPos-(2-2)]; $this->semValue = $this->semStack[$this->stackPos-(2-1)]; }; + } + + protected function reduceRule3() { + $this->semValue = array(); + } + + protected function reduceRule4() { + $startAttributes = $this->lookaheadStartAttributes; if (isset($startAttributes['comments'])) { $nop = new Stmt\Nop(['comments' => $startAttributes['comments']]); } else { $nop = null; }; + if ($nop !== null) { $this->semStack[$this->stackPos-(1-1)][] = $nop; } $this->semValue = $this->semStack[$this->stackPos-(1-1)]; + } + + protected function reduceRule5() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule6() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule7() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule8() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule9() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule10() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule11() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule12() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule13() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule14() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule15() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule16() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule17() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule18() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule19() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule20() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule21() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule22() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule23() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule24() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule25() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule26() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule27() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule28() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule29() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule30() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule31() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule32() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule33() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule34() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule35() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule36() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule37() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule38() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule39() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule40() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule41() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule42() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule43() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule44() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule45() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule46() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule47() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule48() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule49() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule50() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule51() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule52() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule53() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule54() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule55() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule56() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule57() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule58() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule59() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule60() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule61() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule62() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule63() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule64() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule65() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule66() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule67() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule68() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule69() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule70() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule71() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule72() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule73() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule74() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule75() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule76() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule77() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule78() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule79() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule80() { + $this->semValue = $this->semStack[$this->stackPos-(1-1)]; + } + + protected function reduceRule81() { + $this->semValue = $this->semStack[$this->stackPos-(1-1)]; + } + + protected function reduceRule82() { + $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); + } + + protected function reduceRule83() { + $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; + } + + protected function reduceRule84() { + $this->semValue = new Name($this->semStack[$this->stackPos-(1-1)], $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); + } + + protected function reduceRule85() { + $this->semValue = $this->semStack[$this->stackPos-(1-1)]; + } + + protected function reduceRule86() { + $this->semValue = $this->semStack[$this->stackPos-(1-1)]; + } + + protected function reduceRule87() { + $this->semValue = $this->semStack[$this->stackPos-(1-1)]; + } + + protected function reduceRule88() { + $this->semValue = new Stmt\HaltCompiler($this->lexer->handleHaltCompiler(), $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); + } + + protected function reduceRule89() { + $this->semValue = new Stmt\Namespace_($this->semStack[$this->stackPos-(3-2)], null, $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + $this->semValue->setAttribute('kind', Stmt\Namespace_::KIND_SEMICOLON); + $this->checkNamespace($this->semValue); + } + + protected function reduceRule90() { + $this->semValue = new Stmt\Namespace_($this->semStack[$this->stackPos-(5-2)], $this->semStack[$this->stackPos-(5-4)], $this->startAttributeStack[$this->stackPos-(5-1)] + $this->endAttributes); + $this->semValue->setAttribute('kind', Stmt\Namespace_::KIND_BRACED); + $this->checkNamespace($this->semValue); + } + + protected function reduceRule91() { + $this->semValue = new Stmt\Namespace_(null, $this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); + $this->semValue->setAttribute('kind', Stmt\Namespace_::KIND_BRACED); + $this->checkNamespace($this->semValue); + } + + protected function reduceRule92() { + $this->semValue = new Stmt\Use_($this->semStack[$this->stackPos-(3-2)], Stmt\Use_::TYPE_NORMAL, $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule93() { + $this->semValue = new Stmt\Use_($this->semStack[$this->stackPos-(4-3)], $this->semStack[$this->stackPos-(4-2)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); + } + + protected function reduceRule94() { + $this->semValue = $this->semStack[$this->stackPos-(2-1)]; + } + + protected function reduceRule95() { + $this->semValue = new Stmt\Const_($this->semStack[$this->stackPos-(3-2)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule96() { + $this->semValue = Stmt\Use_::TYPE_FUNCTION; + } + + protected function reduceRule97() { + $this->semValue = Stmt\Use_::TYPE_CONSTANT; + } + + protected function reduceRule98() { + $this->semValue = new Stmt\GroupUse(new Name($this->semStack[$this->stackPos-(7-3)], $this->startAttributeStack[$this->stackPos-(7-3)] + $this->endAttributeStack[$this->stackPos-(7-3)]), $this->semStack[$this->stackPos-(7-6)], $this->semStack[$this->stackPos-(7-2)], $this->startAttributeStack[$this->stackPos-(7-1)] + $this->endAttributes); + } + + protected function reduceRule99() { + $this->semValue = new Stmt\GroupUse(new Name($this->semStack[$this->stackPos-(8-4)], $this->startAttributeStack[$this->stackPos-(8-4)] + $this->endAttributeStack[$this->stackPos-(8-4)]), $this->semStack[$this->stackPos-(8-7)], $this->semStack[$this->stackPos-(8-2)], $this->startAttributeStack[$this->stackPos-(8-1)] + $this->endAttributes); + } + + protected function reduceRule100() { + $this->semValue = new Stmt\GroupUse(new Name($this->semStack[$this->stackPos-(6-2)], $this->startAttributeStack[$this->stackPos-(6-2)] + $this->endAttributeStack[$this->stackPos-(6-2)]), $this->semStack[$this->stackPos-(6-5)], Stmt\Use_::TYPE_UNKNOWN, $this->startAttributeStack[$this->stackPos-(6-1)] + $this->endAttributes); + } + + protected function reduceRule101() { + $this->semValue = new Stmt\GroupUse(new Name($this->semStack[$this->stackPos-(7-3)], $this->startAttributeStack[$this->stackPos-(7-3)] + $this->endAttributeStack[$this->stackPos-(7-3)]), $this->semStack[$this->stackPos-(7-6)], Stmt\Use_::TYPE_UNKNOWN, $this->startAttributeStack[$this->stackPos-(7-1)] + $this->endAttributes); + } + + protected function reduceRule102() { + $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; + } + + protected function reduceRule103() { + $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); + } + + protected function reduceRule104() { + $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; + } + + protected function reduceRule105() { + $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); + } + + protected function reduceRule106() { + $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; + } + + protected function reduceRule107() { + $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); + } + + protected function reduceRule108() { + $this->semValue = new Stmt\UseUse($this->semStack[$this->stackPos-(1-1)], null, Stmt\Use_::TYPE_UNKNOWN, $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); $this->checkUseUse($this->semValue, $this->stackPos-(1-1)); + } + + protected function reduceRule109() { + $this->semValue = new Stmt\UseUse($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], Stmt\Use_::TYPE_UNKNOWN, $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); $this->checkUseUse($this->semValue, $this->stackPos-(3-3)); + } + + protected function reduceRule110() { + $this->semValue = $this->semStack[$this->stackPos-(1-1)]; + } + + protected function reduceRule111() { + $this->semValue = $this->semStack[$this->stackPos-(2-2)]; + } + + protected function reduceRule112() { + $this->semValue = $this->semStack[$this->stackPos-(1-1)]; $this->semValue->type = Stmt\Use_::TYPE_NORMAL; + } + + protected function reduceRule113() { + $this->semValue = $this->semStack[$this->stackPos-(2-2)]; $this->semValue->type = $this->semStack[$this->stackPos-(2-1)]; + } + + protected function reduceRule114() { + $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; + } + + protected function reduceRule115() { + $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); + } + + protected function reduceRule116() { + $this->semValue = new Node\Const_($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule117() { + $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; + } + + protected function reduceRule118() { + $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); + } + + protected function reduceRule119() { + $this->semValue = new Node\Const_($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule120() { + if (is_array($this->semStack[$this->stackPos-(2-2)])) { $this->semValue = array_merge($this->semStack[$this->stackPos-(2-1)], $this->semStack[$this->stackPos-(2-2)]); } else { $this->semStack[$this->stackPos-(2-1)][] = $this->semStack[$this->stackPos-(2-2)]; $this->semValue = $this->semStack[$this->stackPos-(2-1)]; }; + } + + protected function reduceRule121() { + $this->semValue = array(); + } + + protected function reduceRule122() { + $startAttributes = $this->lookaheadStartAttributes; if (isset($startAttributes['comments'])) { $nop = new Stmt\Nop(['comments' => $startAttributes['comments']]); } else { $nop = null; }; + if ($nop !== null) { $this->semStack[$this->stackPos-(1-1)][] = $nop; } $this->semValue = $this->semStack[$this->stackPos-(1-1)]; + } + + protected function reduceRule123() { + $this->semValue = $this->semStack[$this->stackPos-(1-1)]; + } + + protected function reduceRule124() { + $this->semValue = $this->semStack[$this->stackPos-(1-1)]; + } + + protected function reduceRule125() { + $this->semValue = $this->semStack[$this->stackPos-(1-1)]; + } + + protected function reduceRule126() { + throw new Error('__HALT_COMPILER() can only be used from the outermost scope', $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); + } + + protected function reduceRule127() { + + if ($this->semStack[$this->stackPos-(3-2)]) { + $this->semValue = $this->semStack[$this->stackPos-(3-2)]; $attrs = $this->startAttributeStack[$this->stackPos-(3-1)]; $stmts = $this->semValue; if (!empty($attrs['comments'])) {$stmts[0]->setAttribute('comments', array_merge($attrs['comments'], $stmts[0]->getAttribute('comments', []))); }; + } else { + $startAttributes = $this->startAttributeStack[$this->stackPos-(3-1)]; if (isset($startAttributes['comments'])) { $this->semValue = new Stmt\Nop(['comments' => $startAttributes['comments']]); } else { $this->semValue = null; }; + if (null === $this->semValue) { $this->semValue = array(); } + } + + } + + protected function reduceRule128() { + $this->semValue = new Stmt\If_($this->semStack[$this->stackPos-(5-2)], ['stmts' => is_array($this->semStack[$this->stackPos-(5-3)]) ? $this->semStack[$this->stackPos-(5-3)] : array($this->semStack[$this->stackPos-(5-3)]), 'elseifs' => $this->semStack[$this->stackPos-(5-4)], 'else' => $this->semStack[$this->stackPos-(5-5)]], $this->startAttributeStack[$this->stackPos-(5-1)] + $this->endAttributes); + } + + protected function reduceRule129() { + $this->semValue = new Stmt\If_($this->semStack[$this->stackPos-(8-2)], ['stmts' => $this->semStack[$this->stackPos-(8-4)], 'elseifs' => $this->semStack[$this->stackPos-(8-5)], 'else' => $this->semStack[$this->stackPos-(8-6)]], $this->startAttributeStack[$this->stackPos-(8-1)] + $this->endAttributes); + } + + protected function reduceRule130() { + $this->semValue = new Stmt\While_($this->semStack[$this->stackPos-(3-2)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule131() { + $this->semValue = new Stmt\Do_($this->semStack[$this->stackPos-(5-4)], is_array($this->semStack[$this->stackPos-(5-2)]) ? $this->semStack[$this->stackPos-(5-2)] : array($this->semStack[$this->stackPos-(5-2)]), $this->startAttributeStack[$this->stackPos-(5-1)] + $this->endAttributes); + } + + protected function reduceRule132() { + $this->semValue = new Stmt\For_(['init' => $this->semStack[$this->stackPos-(9-3)], 'cond' => $this->semStack[$this->stackPos-(9-5)], 'loop' => $this->semStack[$this->stackPos-(9-7)], 'stmts' => $this->semStack[$this->stackPos-(9-9)]], $this->startAttributeStack[$this->stackPos-(9-1)] + $this->endAttributes); + } + + protected function reduceRule133() { + $this->semValue = new Stmt\Switch_($this->semStack[$this->stackPos-(3-2)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule134() { + $this->semValue = new Stmt\Break_(null, $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); + } + + protected function reduceRule135() { + $this->semValue = new Stmt\Break_($this->semStack[$this->stackPos-(3-2)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule136() { + $this->semValue = new Stmt\Continue_(null, $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); + } + + protected function reduceRule137() { + $this->semValue = new Stmt\Continue_($this->semStack[$this->stackPos-(3-2)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule138() { + $this->semValue = new Stmt\Return_(null, $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); + } + + protected function reduceRule139() { + $this->semValue = new Stmt\Return_($this->semStack[$this->stackPos-(3-2)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule140() { + $this->semValue = $this->semStack[$this->stackPos-(2-1)]; + } + + protected function reduceRule141() { + $this->semValue = new Stmt\Global_($this->semStack[$this->stackPos-(3-2)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule142() { + $this->semValue = new Stmt\Static_($this->semStack[$this->stackPos-(3-2)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule143() { + $this->semValue = new Stmt\Echo_($this->semStack[$this->stackPos-(3-2)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule144() { + $this->semValue = new Stmt\InlineHTML($this->semStack[$this->stackPos-(1-1)], $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); + } + + protected function reduceRule145() { + $this->semValue = $this->semStack[$this->stackPos-(2-1)]; + } + + protected function reduceRule146() { + $this->semValue = new Stmt\Unset_($this->semStack[$this->stackPos-(5-3)], $this->startAttributeStack[$this->stackPos-(5-1)] + $this->endAttributes); + } + + protected function reduceRule147() { + $this->semValue = new Stmt\Foreach_($this->semStack[$this->stackPos-(7-3)], $this->semStack[$this->stackPos-(7-5)][0], ['keyVar' => null, 'byRef' => $this->semStack[$this->stackPos-(7-5)][1], 'stmts' => $this->semStack[$this->stackPos-(7-7)]], $this->startAttributeStack[$this->stackPos-(7-1)] + $this->endAttributes); + } + + protected function reduceRule148() { + $this->semValue = new Stmt\Foreach_($this->semStack[$this->stackPos-(9-3)], $this->semStack[$this->stackPos-(9-7)][0], ['keyVar' => $this->semStack[$this->stackPos-(9-5)], 'byRef' => $this->semStack[$this->stackPos-(9-7)][1], 'stmts' => $this->semStack[$this->stackPos-(9-9)]], $this->startAttributeStack[$this->stackPos-(9-1)] + $this->endAttributes); + } + + protected function reduceRule149() { + $this->semValue = new Stmt\Declare_($this->semStack[$this->stackPos-(5-3)], $this->semStack[$this->stackPos-(5-5)], $this->startAttributeStack[$this->stackPos-(5-1)] + $this->endAttributes); + } + + protected function reduceRule150() { + $this->semValue = new Stmt\TryCatch($this->semStack[$this->stackPos-(6-3)], $this->semStack[$this->stackPos-(6-5)], $this->semStack[$this->stackPos-(6-6)], $this->startAttributeStack[$this->stackPos-(6-1)] + $this->endAttributes); $this->checkTryCatch($this->semValue); + } + + protected function reduceRule151() { + $this->semValue = new Stmt\Throw_($this->semStack[$this->stackPos-(3-2)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule152() { + $this->semValue = new Stmt\Goto_($this->semStack[$this->stackPos-(3-2)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule153() { + $this->semValue = new Stmt\Label($this->semStack[$this->stackPos-(2-1)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); + } + + protected function reduceRule154() { + $this->semValue = $this->semStack[$this->stackPos-(2-1)]; + } + + protected function reduceRule155() { + $this->semValue = array(); /* means: no statement */ + } + + protected function reduceRule156() { + $this->semValue = $this->semStack[$this->stackPos-(1-1)]; + } + + protected function reduceRule157() { + $startAttributes = $this->startAttributeStack[$this->stackPos-(1-1)]; if (isset($startAttributes['comments'])) { $this->semValue = new Stmt\Nop(['comments' => $startAttributes['comments']]); } else { $this->semValue = null; }; + if ($this->semValue === null) $this->semValue = array(); /* means: no statement */ + } + + protected function reduceRule158() { + $this->semValue = array(); + } + + protected function reduceRule159() { + $this->semStack[$this->stackPos-(2-1)][] = $this->semStack[$this->stackPos-(2-2)]; $this->semValue = $this->semStack[$this->stackPos-(2-1)]; + } + + protected function reduceRule160() { + $this->semValue = new Stmt\Catch_(array($this->semStack[$this->stackPos-(8-3)]), substr($this->semStack[$this->stackPos-(8-4)], 1), $this->semStack[$this->stackPos-(8-7)], $this->startAttributeStack[$this->stackPos-(8-1)] + $this->endAttributes); + } + + protected function reduceRule161() { + $this->semValue = null; + } + + protected function reduceRule162() { + $this->semValue = new Stmt\Finally_($this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); + } + + protected function reduceRule163() { + $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); + } + + protected function reduceRule164() { + $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; + } + + protected function reduceRule165() { + $this->semValue = false; + } + + protected function reduceRule166() { + $this->semValue = true; + } + + protected function reduceRule167() { + $this->semValue = false; + } + + protected function reduceRule168() { + $this->semValue = true; + } + + protected function reduceRule169() { + $this->semValue = new Stmt\Function_($this->semStack[$this->stackPos-(10-3)], ['byRef' => $this->semStack[$this->stackPos-(10-2)], 'params' => $this->semStack[$this->stackPos-(10-5)], 'returnType' => $this->semStack[$this->stackPos-(10-7)], 'stmts' => $this->semStack[$this->stackPos-(10-9)]], $this->startAttributeStack[$this->stackPos-(10-1)] + $this->endAttributes); + } + + protected function reduceRule170() { + $this->semValue = new Stmt\Class_($this->semStack[$this->stackPos-(7-2)], ['type' => $this->semStack[$this->stackPos-(7-1)], 'extends' => $this->semStack[$this->stackPos-(7-3)], 'implements' => $this->semStack[$this->stackPos-(7-4)], 'stmts' => $this->semStack[$this->stackPos-(7-6)]], $this->startAttributeStack[$this->stackPos-(7-1)] + $this->endAttributes); + $this->checkClass($this->semValue, $this->stackPos-(7-2)); + } + + protected function reduceRule171() { + $this->semValue = new Stmt\Interface_($this->semStack[$this->stackPos-(6-2)], ['extends' => $this->semStack[$this->stackPos-(6-3)], 'stmts' => $this->semStack[$this->stackPos-(6-5)]], $this->startAttributeStack[$this->stackPos-(6-1)] + $this->endAttributes); + $this->checkInterface($this->semValue, $this->stackPos-(6-2)); + } + + protected function reduceRule172() { + $this->semValue = new Stmt\Trait_($this->semStack[$this->stackPos-(5-2)], ['stmts' => $this->semStack[$this->stackPos-(5-4)]], $this->startAttributeStack[$this->stackPos-(5-1)] + $this->endAttributes); + } + + protected function reduceRule173() { + $this->semValue = 0; + } + + protected function reduceRule174() { + $this->semValue = Stmt\Class_::MODIFIER_ABSTRACT; + } + + protected function reduceRule175() { + $this->semValue = Stmt\Class_::MODIFIER_FINAL; + } + + protected function reduceRule176() { + $this->semValue = null; + } + + protected function reduceRule177() { + $this->semValue = $this->semStack[$this->stackPos-(2-2)]; + } + + protected function reduceRule178() { + $this->semValue = array(); + } + + protected function reduceRule179() { + $this->semValue = $this->semStack[$this->stackPos-(2-2)]; + } + + protected function reduceRule180() { + $this->semValue = array(); + } + + protected function reduceRule181() { + $this->semValue = $this->semStack[$this->stackPos-(2-2)]; + } + + protected function reduceRule182() { + $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); + } + + protected function reduceRule183() { + $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; + } + + protected function reduceRule184() { + $this->semValue = is_array($this->semStack[$this->stackPos-(1-1)]) ? $this->semStack[$this->stackPos-(1-1)] : array($this->semStack[$this->stackPos-(1-1)]); + } + + protected function reduceRule185() { + $this->semValue = $this->semStack[$this->stackPos-(4-2)]; + } + + protected function reduceRule186() { + $this->semValue = is_array($this->semStack[$this->stackPos-(1-1)]) ? $this->semStack[$this->stackPos-(1-1)] : array($this->semStack[$this->stackPos-(1-1)]); + } + + protected function reduceRule187() { + $this->semValue = $this->semStack[$this->stackPos-(4-2)]; + } + + protected function reduceRule188() { + $this->semValue = is_array($this->semStack[$this->stackPos-(1-1)]) ? $this->semStack[$this->stackPos-(1-1)] : array($this->semStack[$this->stackPos-(1-1)]); + } + + protected function reduceRule189() { + $this->semValue = null; + } + + protected function reduceRule190() { + $this->semValue = $this->semStack[$this->stackPos-(4-2)]; + } + + protected function reduceRule191() { + $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); + } + + protected function reduceRule192() { + $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; + } + + protected function reduceRule193() { + $this->semValue = new Stmt\DeclareDeclare($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule194() { + $this->semValue = $this->semStack[$this->stackPos-(3-2)]; + } + + protected function reduceRule195() { + $this->semValue = $this->semStack[$this->stackPos-(4-3)]; + } + + protected function reduceRule196() { + $this->semValue = $this->semStack[$this->stackPos-(4-2)]; + } + + protected function reduceRule197() { + $this->semValue = $this->semStack[$this->stackPos-(5-3)]; + } + + protected function reduceRule198() { + $this->semValue = array(); + } + + protected function reduceRule199() { + $this->semStack[$this->stackPos-(2-1)][] = $this->semStack[$this->stackPos-(2-2)]; $this->semValue = $this->semStack[$this->stackPos-(2-1)]; + } + + protected function reduceRule200() { + $this->semValue = new Stmt\Case_($this->semStack[$this->stackPos-(4-2)], $this->semStack[$this->stackPos-(4-4)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); + } + + protected function reduceRule201() { + $this->semValue = new Stmt\Case_(null, $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule202() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule203() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule204() { + $this->semValue = is_array($this->semStack[$this->stackPos-(1-1)]) ? $this->semStack[$this->stackPos-(1-1)] : array($this->semStack[$this->stackPos-(1-1)]); + } + + protected function reduceRule205() { + $this->semValue = $this->semStack[$this->stackPos-(4-2)]; + } + + protected function reduceRule206() { + $this->semValue = array(); + } + + protected function reduceRule207() { + $this->semStack[$this->stackPos-(2-1)][] = $this->semStack[$this->stackPos-(2-2)]; $this->semValue = $this->semStack[$this->stackPos-(2-1)]; + } + + protected function reduceRule208() { + $this->semValue = new Stmt\ElseIf_($this->semStack[$this->stackPos-(3-2)], is_array($this->semStack[$this->stackPos-(3-3)]) ? $this->semStack[$this->stackPos-(3-3)] : array($this->semStack[$this->stackPos-(3-3)]), $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule209() { + $this->semValue = array(); + } + + protected function reduceRule210() { + $this->semStack[$this->stackPos-(2-1)][] = $this->semStack[$this->stackPos-(2-2)]; $this->semValue = $this->semStack[$this->stackPos-(2-1)]; + } + + protected function reduceRule211() { + $this->semValue = new Stmt\ElseIf_($this->semStack[$this->stackPos-(4-2)], $this->semStack[$this->stackPos-(4-4)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); + } + + protected function reduceRule212() { + $this->semValue = null; + } + + protected function reduceRule213() { + $this->semValue = new Stmt\Else_(is_array($this->semStack[$this->stackPos-(2-2)]) ? $this->semStack[$this->stackPos-(2-2)] : array($this->semStack[$this->stackPos-(2-2)]), $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); + } + + protected function reduceRule214() { + $this->semValue = null; + } + + protected function reduceRule215() { + $this->semValue = new Stmt\Else_($this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule216() { + $this->semValue = array($this->semStack[$this->stackPos-(1-1)], false); + } + + protected function reduceRule217() { + $this->semValue = array($this->semStack[$this->stackPos-(2-2)], true); + } + + protected function reduceRule218() { + $this->semValue = array($this->semStack[$this->stackPos-(1-1)], false); + } + + protected function reduceRule219() { + $this->semValue = $this->semStack[$this->stackPos-(1-1)]; + } + + protected function reduceRule220() { + $this->semValue = array(); + } + + protected function reduceRule221() { + $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); + } + + protected function reduceRule222() { + $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; + } + + protected function reduceRule223() { + $this->semValue = new Node\Param(substr($this->semStack[$this->stackPos-(4-4)], 1), null, $this->semStack[$this->stackPos-(4-1)], $this->semStack[$this->stackPos-(4-2)], $this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); $this->checkParam($this->semValue); + } + + protected function reduceRule224() { + $this->semValue = new Node\Param(substr($this->semStack[$this->stackPos-(6-4)], 1), $this->semStack[$this->stackPos-(6-6)], $this->semStack[$this->stackPos-(6-1)], $this->semStack[$this->stackPos-(6-2)], $this->semStack[$this->stackPos-(6-3)], $this->startAttributeStack[$this->stackPos-(6-1)] + $this->endAttributes); $this->checkParam($this->semValue); + } + + protected function reduceRule225() { + $this->semValue = $this->semStack[$this->stackPos-(1-1)]; + } + + protected function reduceRule226() { + $this->semValue = 'array'; + } + + protected function reduceRule227() { + $this->semValue = 'callable'; + } + + protected function reduceRule228() { + $this->semValue = null; + } + + protected function reduceRule229() { + $this->semValue = $this->semStack[$this->stackPos-(1-1)]; + } + + protected function reduceRule230() { + $this->semValue = null; + } + + protected function reduceRule231() { + $this->semValue = $this->semStack[$this->stackPos-(2-2)]; + } + + protected function reduceRule232() { + $this->semValue = array(); + } + + protected function reduceRule233() { + $this->semValue = $this->semStack[$this->stackPos-(3-2)]; + } + + protected function reduceRule234() { + $this->semValue = array(new Node\Arg($this->semStack[$this->stackPos-(3-2)], false, false, $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes)); + } + + protected function reduceRule235() { + $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); + } + + protected function reduceRule236() { + $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; + } + + protected function reduceRule237() { + $this->semValue = new Node\Arg($this->semStack[$this->stackPos-(1-1)], false, false, $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); + } + + protected function reduceRule238() { + $this->semValue = new Node\Arg($this->semStack[$this->stackPos-(2-2)], true, false, $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); + } + + protected function reduceRule239() { + $this->semValue = new Node\Arg($this->semStack[$this->stackPos-(2-2)], false, true, $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); + } + + protected function reduceRule240() { + $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; + } + + protected function reduceRule241() { + $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); + } + + protected function reduceRule242() { + $this->semValue = new Expr\Variable(substr($this->semStack[$this->stackPos-(1-1)], 1), $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); + } + + protected function reduceRule243() { + $this->semValue = new Expr\Variable($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); + } + + protected function reduceRule244() { + $this->semValue = new Expr\Variable($this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); + } + + protected function reduceRule245() { + $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; + } + + protected function reduceRule246() { + $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); + } + + protected function reduceRule247() { + $this->semValue = new Stmt\StaticVar(substr($this->semStack[$this->stackPos-(1-1)], 1), null, $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); + } + + protected function reduceRule248() { + $this->semValue = new Stmt\StaticVar(substr($this->semStack[$this->stackPos-(3-1)], 1), $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule249() { + $this->semStack[$this->stackPos-(2-1)][] = $this->semStack[$this->stackPos-(2-2)]; $this->semValue = $this->semStack[$this->stackPos-(2-1)]; + } + + protected function reduceRule250() { + $this->semValue = array(); + } + + protected function reduceRule251() { + $this->semValue = new Stmt\Property($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-2)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); $this->checkProperty($this->semValue, $this->stackPos-(3-1)); + } + + protected function reduceRule252() { + $this->semValue = new Stmt\ClassConst($this->semStack[$this->stackPos-(3-2)], 0, $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule253() { + $this->semValue = new Stmt\ClassMethod($this->semStack[$this->stackPos-(9-4)], ['type' => $this->semStack[$this->stackPos-(9-1)], 'byRef' => $this->semStack[$this->stackPos-(9-3)], 'params' => $this->semStack[$this->stackPos-(9-6)], 'returnType' => $this->semStack[$this->stackPos-(9-8)], 'stmts' => $this->semStack[$this->stackPos-(9-9)]], $this->startAttributeStack[$this->stackPos-(9-1)] + $this->endAttributes); + $this->checkClassMethod($this->semValue, $this->stackPos-(9-1)); + } + + protected function reduceRule254() { + $this->semValue = new Stmt\TraitUse($this->semStack[$this->stackPos-(3-2)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule255() { + $this->semValue = array(); + } + + protected function reduceRule256() { + $this->semValue = $this->semStack[$this->stackPos-(3-2)]; + } + + protected function reduceRule257() { + $this->semValue = array(); + } + + protected function reduceRule258() { + $this->semStack[$this->stackPos-(2-1)][] = $this->semStack[$this->stackPos-(2-2)]; $this->semValue = $this->semStack[$this->stackPos-(2-1)]; + } + + protected function reduceRule259() { + $this->semValue = new Stmt\TraitUseAdaptation\Precedence($this->semStack[$this->stackPos-(4-1)][0], $this->semStack[$this->stackPos-(4-1)][1], $this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); + } + + protected function reduceRule260() { + $this->semValue = new Stmt\TraitUseAdaptation\Alias($this->semStack[$this->stackPos-(5-1)][0], $this->semStack[$this->stackPos-(5-1)][1], $this->semStack[$this->stackPos-(5-3)], $this->semStack[$this->stackPos-(5-4)], $this->startAttributeStack[$this->stackPos-(5-1)] + $this->endAttributes); + } + + protected function reduceRule261() { + $this->semValue = new Stmt\TraitUseAdaptation\Alias($this->semStack[$this->stackPos-(4-1)][0], $this->semStack[$this->stackPos-(4-1)][1], $this->semStack[$this->stackPos-(4-3)], null, $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); + } + + protected function reduceRule262() { + $this->semValue = new Stmt\TraitUseAdaptation\Alias($this->semStack[$this->stackPos-(4-1)][0], $this->semStack[$this->stackPos-(4-1)][1], null, $this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); + } + + protected function reduceRule263() { + $this->semValue = new Stmt\TraitUseAdaptation\Alias($this->semStack[$this->stackPos-(4-1)][0], $this->semStack[$this->stackPos-(4-1)][1], null, $this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); + } + + protected function reduceRule264() { + $this->semValue = array($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)]); + } + + protected function reduceRule265() { + $this->semValue = $this->semStack[$this->stackPos-(1-1)]; + } + + protected function reduceRule266() { + $this->semValue = array(null, $this->semStack[$this->stackPos-(1-1)]); + } + + protected function reduceRule267() { + $this->semValue = null; + } + + protected function reduceRule268() { + $this->semValue = $this->semStack[$this->stackPos-(3-2)]; + } + + protected function reduceRule269() { + $this->semValue = $this->semStack[$this->stackPos-(1-1)]; + } + + protected function reduceRule270() { + $this->semValue = 0; + } + + protected function reduceRule271() { + $this->semValue = 0; + } + + protected function reduceRule272() { + $this->semValue = $this->semStack[$this->stackPos-(1-1)]; + } + + protected function reduceRule273() { + $this->semValue = $this->semStack[$this->stackPos-(1-1)]; + } + + protected function reduceRule274() { + $this->checkModifier($this->semStack[$this->stackPos-(2-1)], $this->semStack[$this->stackPos-(2-2)], $this->stackPos-(2-2)); $this->semValue = $this->semStack[$this->stackPos-(2-1)] | $this->semStack[$this->stackPos-(2-2)]; + } + + protected function reduceRule275() { + $this->semValue = Stmt\Class_::MODIFIER_PUBLIC; + } + + protected function reduceRule276() { + $this->semValue = Stmt\Class_::MODIFIER_PROTECTED; + } + + protected function reduceRule277() { + $this->semValue = Stmt\Class_::MODIFIER_PRIVATE; + } + + protected function reduceRule278() { + $this->semValue = Stmt\Class_::MODIFIER_STATIC; + } + + protected function reduceRule279() { + $this->semValue = Stmt\Class_::MODIFIER_ABSTRACT; + } + + protected function reduceRule280() { + $this->semValue = Stmt\Class_::MODIFIER_FINAL; + } + + protected function reduceRule281() { + $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); + } + + protected function reduceRule282() { + $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; + } + + protected function reduceRule283() { + $this->semValue = new Stmt\PropertyProperty(substr($this->semStack[$this->stackPos-(1-1)], 1), null, $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); + } + + protected function reduceRule284() { + $this->semValue = new Stmt\PropertyProperty(substr($this->semStack[$this->stackPos-(3-1)], 1), $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule285() { + $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; + } + + protected function reduceRule286() { + $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); + } + + protected function reduceRule287() { + $this->semValue = array(); + } + + protected function reduceRule288() { + $this->semValue = $this->semStack[$this->stackPos-(1-1)]; + } + + protected function reduceRule289() { + $this->semValue = $this->semStack[$this->stackPos-(1-1)]; + } + + protected function reduceRule290() { + $this->semValue = new Expr\Assign($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule291() { + $this->semValue = new Expr\Assign($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule292() { + $this->semValue = new Expr\AssignRef($this->semStack[$this->stackPos-(4-1)], $this->semStack[$this->stackPos-(4-4)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); + } + + protected function reduceRule293() { + $this->semValue = new Expr\AssignRef($this->semStack[$this->stackPos-(4-1)], $this->semStack[$this->stackPos-(4-4)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); + } + + protected function reduceRule294() { + $this->semValue = $this->semStack[$this->stackPos-(1-1)]; + } + + protected function reduceRule295() { + $this->semValue = new Expr\Clone_($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); + } + + protected function reduceRule296() { + $this->semValue = new Expr\AssignOp\Plus($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule297() { + $this->semValue = new Expr\AssignOp\Minus($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule298() { + $this->semValue = new Expr\AssignOp\Mul($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule299() { + $this->semValue = new Expr\AssignOp\Div($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule300() { + $this->semValue = new Expr\AssignOp\Concat($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule301() { + $this->semValue = new Expr\AssignOp\Mod($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule302() { + $this->semValue = new Expr\AssignOp\BitwiseAnd($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule303() { + $this->semValue = new Expr\AssignOp\BitwiseOr($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule304() { + $this->semValue = new Expr\AssignOp\BitwiseXor($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule305() { + $this->semValue = new Expr\AssignOp\ShiftLeft($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule306() { + $this->semValue = new Expr\AssignOp\ShiftRight($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule307() { + $this->semValue = new Expr\AssignOp\Pow($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule308() { + $this->semValue = new Expr\PostInc($this->semStack[$this->stackPos-(2-1)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); + } + + protected function reduceRule309() { + $this->semValue = new Expr\PreInc($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); + } + + protected function reduceRule310() { + $this->semValue = new Expr\PostDec($this->semStack[$this->stackPos-(2-1)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); + } + + protected function reduceRule311() { + $this->semValue = new Expr\PreDec($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); + } + + protected function reduceRule312() { + $this->semValue = new Expr\BinaryOp\BooleanOr($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule313() { + $this->semValue = new Expr\BinaryOp\BooleanAnd($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule314() { + $this->semValue = new Expr\BinaryOp\LogicalOr($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule315() { + $this->semValue = new Expr\BinaryOp\LogicalAnd($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule316() { + $this->semValue = new Expr\BinaryOp\LogicalXor($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule317() { + $this->semValue = new Expr\BinaryOp\BitwiseOr($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule318() { + $this->semValue = new Expr\BinaryOp\BitwiseAnd($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule319() { + $this->semValue = new Expr\BinaryOp\BitwiseXor($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule320() { + $this->semValue = new Expr\BinaryOp\Concat($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule321() { + $this->semValue = new Expr\BinaryOp\Plus($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule322() { + $this->semValue = new Expr\BinaryOp\Minus($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule323() { + $this->semValue = new Expr\BinaryOp\Mul($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule324() { + $this->semValue = new Expr\BinaryOp\Div($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule325() { + $this->semValue = new Expr\BinaryOp\Mod($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule326() { + $this->semValue = new Expr\BinaryOp\ShiftLeft($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule327() { + $this->semValue = new Expr\BinaryOp\ShiftRight($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule328() { + $this->semValue = new Expr\BinaryOp\Pow($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule329() { + $this->semValue = new Expr\UnaryPlus($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); + } + + protected function reduceRule330() { + $this->semValue = new Expr\UnaryMinus($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); + } + + protected function reduceRule331() { + $this->semValue = new Expr\BooleanNot($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); + } + + protected function reduceRule332() { + $this->semValue = new Expr\BitwiseNot($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); + } + + protected function reduceRule333() { + $this->semValue = new Expr\BinaryOp\Identical($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule334() { + $this->semValue = new Expr\BinaryOp\NotIdentical($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule335() { + $this->semValue = new Expr\BinaryOp\Equal($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule336() { + $this->semValue = new Expr\BinaryOp\NotEqual($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule337() { + $this->semValue = new Expr\BinaryOp\Spaceship($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule338() { + $this->semValue = new Expr\BinaryOp\Smaller($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule339() { + $this->semValue = new Expr\BinaryOp\SmallerOrEqual($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule340() { + $this->semValue = new Expr\BinaryOp\Greater($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule341() { + $this->semValue = new Expr\BinaryOp\GreaterOrEqual($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule342() { + $this->semValue = new Expr\Instanceof_($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule343() { + $this->semValue = $this->semStack[$this->stackPos-(1-1)]; + } + + protected function reduceRule344() { + $this->semValue = $this->semStack[$this->stackPos-(3-2)]; + } + + protected function reduceRule345() { + $this->semValue = new Expr\Ternary($this->semStack[$this->stackPos-(5-1)], $this->semStack[$this->stackPos-(5-3)], $this->semStack[$this->stackPos-(5-5)], $this->startAttributeStack[$this->stackPos-(5-1)] + $this->endAttributes); + } + + protected function reduceRule346() { + $this->semValue = new Expr\Ternary($this->semStack[$this->stackPos-(4-1)], null, $this->semStack[$this->stackPos-(4-4)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); + } + + protected function reduceRule347() { + $this->semValue = new Expr\BinaryOp\Coalesce($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule348() { + $this->semValue = new Expr\Isset_($this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); + } + + protected function reduceRule349() { + $this->semValue = new Expr\Empty_($this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); + } + + protected function reduceRule350() { + $this->semValue = new Expr\Include_($this->semStack[$this->stackPos-(2-2)], Expr\Include_::TYPE_INCLUDE, $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); + } + + protected function reduceRule351() { + $this->semValue = new Expr\Include_($this->semStack[$this->stackPos-(2-2)], Expr\Include_::TYPE_INCLUDE_ONCE, $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); + } + + protected function reduceRule352() { + $this->semValue = new Expr\Eval_($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); + } + + protected function reduceRule353() { + $this->semValue = new Expr\Include_($this->semStack[$this->stackPos-(2-2)], Expr\Include_::TYPE_REQUIRE, $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); + } + + protected function reduceRule354() { + $this->semValue = new Expr\Include_($this->semStack[$this->stackPos-(2-2)], Expr\Include_::TYPE_REQUIRE_ONCE, $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); + } + + protected function reduceRule355() { + $this->semValue = new Expr\Cast\Int_($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); + } + + protected function reduceRule356() { + $this->semValue = new Expr\Cast\Double($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); + } + + protected function reduceRule357() { + $this->semValue = new Expr\Cast\String_($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); + } + + protected function reduceRule358() { + $this->semValue = new Expr\Cast\Array_($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); + } + + protected function reduceRule359() { + $this->semValue = new Expr\Cast\Object_($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); + } + + protected function reduceRule360() { + $this->semValue = new Expr\Cast\Bool_($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); + } + + protected function reduceRule361() { + $this->semValue = new Expr\Cast\Unset_($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); + } + + protected function reduceRule362() { + $attrs = $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes; + $attrs['kind'] = strtolower($this->semStack[$this->stackPos-(2-1)]) === 'exit' ? Expr\Exit_::KIND_EXIT : Expr\Exit_::KIND_DIE; + $this->semValue = new Expr\Exit_($this->semStack[$this->stackPos-(2-2)], $attrs); + } + + protected function reduceRule363() { + $this->semValue = new Expr\ErrorSuppress($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); + } + + protected function reduceRule364() { + $this->semValue = $this->semStack[$this->stackPos-(1-1)]; + } + + protected function reduceRule365() { + $this->semValue = $this->semStack[$this->stackPos-(1-1)]; + } + + protected function reduceRule366() { + $this->semValue = $this->semStack[$this->stackPos-(1-1)]; + } + + protected function reduceRule367() { + $this->semValue = new Expr\ShellExec($this->semStack[$this->stackPos-(3-2)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule368() { + $this->semValue = new Expr\Print_($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); + } + + protected function reduceRule369() { + $this->semValue = new Expr\Yield_(null, null, $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); + } + + protected function reduceRule370() { + $this->semValue = new Expr\YieldFrom($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); + } + + protected function reduceRule371() { + $this->semValue = new Expr\Closure(['static' => false, 'byRef' => $this->semStack[$this->stackPos-(10-2)], 'params' => $this->semStack[$this->stackPos-(10-4)], 'uses' => $this->semStack[$this->stackPos-(10-6)], 'returnType' => $this->semStack[$this->stackPos-(10-7)], 'stmts' => $this->semStack[$this->stackPos-(10-9)]], $this->startAttributeStack[$this->stackPos-(10-1)] + $this->endAttributes); + } + + protected function reduceRule372() { + $this->semValue = new Expr\Closure(['static' => true, 'byRef' => $this->semStack[$this->stackPos-(11-3)], 'params' => $this->semStack[$this->stackPos-(11-5)], 'uses' => $this->semStack[$this->stackPos-(11-7)], 'returnType' => $this->semStack[$this->stackPos-(11-8)], 'stmts' => $this->semStack[$this->stackPos-(11-10)]], $this->startAttributeStack[$this->stackPos-(11-1)] + $this->endAttributes); + } + + protected function reduceRule373() { + $this->semValue = $this->semStack[$this->stackPos-(3-2)]; + } + + protected function reduceRule374() { + $this->semValue = $this->semStack[$this->stackPos-(3-2)]; + } + + protected function reduceRule375() { + $this->semValue = new Expr\Yield_($this->semStack[$this->stackPos-(2-2)], null, $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); + } + + protected function reduceRule376() { + $this->semValue = new Expr\Yield_($this->semStack[$this->stackPos-(4-4)], $this->semStack[$this->stackPos-(4-2)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); + } + + protected function reduceRule377() { + $attrs = $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes; $attrs['kind'] = Expr\Array_::KIND_LONG; + $this->semValue = new Expr\Array_($this->semStack[$this->stackPos-(4-3)], $attrs); + } + + protected function reduceRule378() { + $attrs = $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes; $attrs['kind'] = Expr\Array_::KIND_SHORT; + $this->semValue = new Expr\Array_($this->semStack[$this->stackPos-(3-2)], $attrs); + } + + protected function reduceRule379() { + $this->semValue = new Expr\ArrayDimFetch($this->semStack[$this->stackPos-(4-1)], $this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); + } + + protected function reduceRule380() { + $attrs = $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes; $attrs['kind'] = ($this->semStack[$this->stackPos-(4-1)][0] === "'" || ($this->semStack[$this->stackPos-(4-1)][1] === "'" && ($this->semStack[$this->stackPos-(4-1)][0] === 'b' || $this->semStack[$this->stackPos-(4-1)][0] === 'B')) ? Scalar\String_::KIND_SINGLE_QUOTED : Scalar\String_::KIND_DOUBLE_QUOTED); + $this->semValue = new Expr\ArrayDimFetch(new Scalar\String_(Scalar\String_::parse($this->semStack[$this->stackPos-(4-1)]), $attrs), $this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); + } + + protected function reduceRule381() { + $this->semValue = new Expr\ArrayDimFetch($this->semStack[$this->stackPos-(4-1)], $this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); + } + + protected function reduceRule382() { + $this->semValue = new Expr\ArrayDimFetch($this->semStack[$this->stackPos-(4-1)], $this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); + } + + protected function reduceRule383() { + $this->semValue = array(new Stmt\Class_(null, ['type' => 0, 'extends' => $this->semStack[$this->stackPos-(7-3)], 'implements' => $this->semStack[$this->stackPos-(7-4)], 'stmts' => $this->semStack[$this->stackPos-(7-6)]], $this->startAttributeStack[$this->stackPos-(7-1)] + $this->endAttributes), $this->semStack[$this->stackPos-(7-2)]); + $this->checkClass($this->semValue[0], -1); + } + + protected function reduceRule384() { + $this->semValue = new Expr\New_($this->semStack[$this->stackPos-(3-2)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule385() { + list($class, $ctorArgs) = $this->semStack[$this->stackPos-(2-2)]; $this->semValue = new Expr\New_($class, $ctorArgs, $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); + } + + protected function reduceRule386() { + $this->semValue = array(); + } + + protected function reduceRule387() { + $this->semValue = $this->semStack[$this->stackPos-(4-3)]; + } + + protected function reduceRule388() { + $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); + } + + protected function reduceRule389() { + $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; + } + + protected function reduceRule390() { + $this->semValue = new Expr\ClosureUse(substr($this->semStack[$this->stackPos-(2-2)], 1), $this->semStack[$this->stackPos-(2-1)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); + } + + protected function reduceRule391() { + $this->semValue = new Expr\FuncCall($this->semStack[$this->stackPos-(2-1)], $this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); + } + + protected function reduceRule392() { + $this->semValue = new Expr\StaticCall($this->semStack[$this->stackPos-(4-1)], $this->semStack[$this->stackPos-(4-3)], $this->semStack[$this->stackPos-(4-4)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); + } + + protected function reduceRule393() { + $this->semValue = new Expr\StaticCall($this->semStack[$this->stackPos-(6-1)], $this->semStack[$this->stackPos-(6-4)], $this->semStack[$this->stackPos-(6-6)], $this->startAttributeStack[$this->stackPos-(6-1)] + $this->endAttributes); + } + + protected function reduceRule394() { + + if ($this->semStack[$this->stackPos-(2-1)] instanceof Node\Expr\StaticPropertyFetch) { + $this->semValue = new Expr\StaticCall($this->semStack[$this->stackPos-(2-1)]->class, new Expr\Variable($this->semStack[$this->stackPos-(2-1)]->name, $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes), $this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); + } elseif ($this->semStack[$this->stackPos-(2-1)] instanceof Node\Expr\ArrayDimFetch) { + $tmp = $this->semStack[$this->stackPos-(2-1)]; + while ($tmp->var instanceof Node\Expr\ArrayDimFetch) { + $tmp = $tmp->var; + } + + $this->semValue = new Expr\StaticCall($tmp->var->class, $this->semStack[$this->stackPos-(2-1)], $this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); + $tmp->var = new Expr\Variable($tmp->var->name, $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); + } else { + throw new \Exception; + } + + } + + protected function reduceRule395() { + $this->semValue = new Expr\FuncCall($this->semStack[$this->stackPos-(2-1)], $this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); + } + + protected function reduceRule396() { + $this->semValue = new Expr\ArrayDimFetch($this->semStack[$this->stackPos-(4-1)], $this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); + } + + protected function reduceRule397() { + $this->semValue = new Name($this->semStack[$this->stackPos-(1-1)], $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); + } + + protected function reduceRule398() { + $this->semValue = $this->semStack[$this->stackPos-(1-1)]; + } + + protected function reduceRule399() { + $this->semValue = new Name($this->semStack[$this->stackPos-(1-1)], $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); + } + + protected function reduceRule400() { + $this->semValue = new Name\FullyQualified($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); + } + + protected function reduceRule401() { + $this->semValue = new Name\Relative($this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule402() { + $this->semValue = $this->semStack[$this->stackPos-(1-1)]; + } + + protected function reduceRule403() { + $this->semValue = $this->semStack[$this->stackPos-(1-1)]; + } + + protected function reduceRule404() { + $this->semValue = $this->semStack[$this->stackPos-(1-1)]; + } + + protected function reduceRule405() { + $this->semValue = $this->semStack[$this->stackPos-(1-1)]; + } + + protected function reduceRule406() { + $this->semValue = $this->semStack[$this->stackPos-(1-1)]; + } + + protected function reduceRule407() { + $this->semValue = $this->semStack[$this->stackPos-(1-1)]; + } + + protected function reduceRule408() { + $this->semValue = new Expr\PropertyFetch($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule409() { + $this->semValue = new Expr\PropertyFetch($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule410() { + $this->semValue = new Expr\ArrayDimFetch($this->semStack[$this->stackPos-(4-1)], $this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); + } + + protected function reduceRule411() { + $this->semValue = new Expr\ArrayDimFetch($this->semStack[$this->stackPos-(4-1)], $this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); + } + + protected function reduceRule412() { + $this->semValue = null; + } + + protected function reduceRule413() { + $this->semValue = null; + } + + protected function reduceRule414() { + $this->semValue = $this->semStack[$this->stackPos-(1-1)]; + } + + protected function reduceRule415() { + $this->semValue = array(); + } + + protected function reduceRule416() { + $this->semValue = array(new Scalar\EncapsedStringPart(Scalar\String_::parseEscapeSequences($this->semStack[$this->stackPos-(1-1)], '`', false), $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes)); + } + + protected function reduceRule417() { + foreach ($this->semStack[$this->stackPos-(1-1)] as $s) { if ($s instanceof Node\Scalar\EncapsedStringPart) { $s->value = Node\Scalar\String_::parseEscapeSequences($s->value, '`', false); } }; $this->semValue = $this->semStack[$this->stackPos-(1-1)]; + } + + protected function reduceRule418() { + $this->semValue = array(); + } + + protected function reduceRule419() { + $this->semValue = $this->semStack[$this->stackPos-(1-1)]; + } + + protected function reduceRule420() { + $this->semValue = $this->parseLNumber($this->semStack[$this->stackPos-(1-1)], $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes, true); + } + + protected function reduceRule421() { + $this->semValue = new Scalar\DNumber(Scalar\DNumber::parse($this->semStack[$this->stackPos-(1-1)]), $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); + } + + protected function reduceRule422() { + $attrs = $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes; $attrs['kind'] = ($this->semStack[$this->stackPos-(1-1)][0] === "'" || ($this->semStack[$this->stackPos-(1-1)][1] === "'" && ($this->semStack[$this->stackPos-(1-1)][0] === 'b' || $this->semStack[$this->stackPos-(1-1)][0] === 'B')) ? Scalar\String_::KIND_SINGLE_QUOTED : Scalar\String_::KIND_DOUBLE_QUOTED); + $this->semValue = new Scalar\String_(Scalar\String_::parse($this->semStack[$this->stackPos-(1-1)], false), $attrs); + } + + protected function reduceRule423() { + $this->semValue = new Scalar\MagicConst\Line($this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); + } + + protected function reduceRule424() { + $this->semValue = new Scalar\MagicConst\File($this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); + } + + protected function reduceRule425() { + $this->semValue = new Scalar\MagicConst\Dir($this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); + } + + protected function reduceRule426() { + $this->semValue = new Scalar\MagicConst\Class_($this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); + } + + protected function reduceRule427() { + $this->semValue = new Scalar\MagicConst\Trait_($this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); + } + + protected function reduceRule428() { + $this->semValue = new Scalar\MagicConst\Method($this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); + } + + protected function reduceRule429() { + $this->semValue = new Scalar\MagicConst\Function_($this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); + } + + protected function reduceRule430() { + $this->semValue = new Scalar\MagicConst\Namespace_($this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); + } + + protected function reduceRule431() { + $attrs = $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes; $attrs['kind'] = strpos($this->semStack[$this->stackPos-(3-1)], "'") === false ? Scalar\String_::KIND_HEREDOC : Scalar\String_::KIND_NOWDOC; preg_match('/\A[bB]?<<<[ \t]*[\'"]?([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)[\'"]?(?:\r\n|\n|\r)\z/', $this->semStack[$this->stackPos-(3-1)], $matches); $attrs['docLabel'] = $matches[1];; + $this->semValue = new Scalar\String_(Scalar\String_::parseDocString($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-2)], false), $attrs); + } + + protected function reduceRule432() { + $attrs = $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes; $attrs['kind'] = strpos($this->semStack[$this->stackPos-(2-1)], "'") === false ? Scalar\String_::KIND_HEREDOC : Scalar\String_::KIND_NOWDOC; preg_match('/\A[bB]?<<<[ \t]*[\'"]?([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)[\'"]?(?:\r\n|\n|\r)\z/', $this->semStack[$this->stackPos-(2-1)], $matches); $attrs['docLabel'] = $matches[1];; + $this->semValue = new Scalar\String_('', $attrs); + } + + protected function reduceRule433() { + $this->semValue = $this->semStack[$this->stackPos-(1-1)]; + } + + protected function reduceRule434() { + $this->semValue = new Expr\ClassConstFetch($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule435() { + $this->semValue = new Expr\ConstFetch($this->semStack[$this->stackPos-(1-1)], $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); + } + + protected function reduceRule436() { + $this->semValue = new Expr\Array_($this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); + } + + protected function reduceRule437() { + $this->semValue = new Expr\Array_($this->semStack[$this->stackPos-(3-2)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule438() { + $this->semValue = $this->semStack[$this->stackPos-(1-1)]; + } + + protected function reduceRule439() { + $this->semValue = new Expr\BinaryOp\BooleanOr($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule440() { + $this->semValue = new Expr\BinaryOp\BooleanAnd($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule441() { + $this->semValue = new Expr\BinaryOp\LogicalOr($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule442() { + $this->semValue = new Expr\BinaryOp\LogicalAnd($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule443() { + $this->semValue = new Expr\BinaryOp\LogicalXor($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule444() { + $this->semValue = new Expr\BinaryOp\BitwiseOr($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule445() { + $this->semValue = new Expr\BinaryOp\BitwiseAnd($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule446() { + $this->semValue = new Expr\BinaryOp\BitwiseXor($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule447() { + $this->semValue = new Expr\BinaryOp\Concat($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule448() { + $this->semValue = new Expr\BinaryOp\Plus($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule449() { + $this->semValue = new Expr\BinaryOp\Minus($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule450() { + $this->semValue = new Expr\BinaryOp\Mul($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule451() { + $this->semValue = new Expr\BinaryOp\Div($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule452() { + $this->semValue = new Expr\BinaryOp\Mod($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule453() { + $this->semValue = new Expr\BinaryOp\ShiftLeft($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule454() { + $this->semValue = new Expr\BinaryOp\ShiftRight($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule455() { + $this->semValue = new Expr\BinaryOp\Pow($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule456() { + $this->semValue = new Expr\UnaryPlus($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); + } + + protected function reduceRule457() { + $this->semValue = new Expr\UnaryMinus($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); + } + + protected function reduceRule458() { + $this->semValue = new Expr\BooleanNot($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); + } + + protected function reduceRule459() { + $this->semValue = new Expr\BitwiseNot($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); + } + + protected function reduceRule460() { + $this->semValue = new Expr\BinaryOp\Identical($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule461() { + $this->semValue = new Expr\BinaryOp\NotIdentical($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule462() { + $this->semValue = new Expr\BinaryOp\Equal($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule463() { + $this->semValue = new Expr\BinaryOp\NotEqual($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule464() { + $this->semValue = new Expr\BinaryOp\Smaller($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule465() { + $this->semValue = new Expr\BinaryOp\SmallerOrEqual($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule466() { + $this->semValue = new Expr\BinaryOp\Greater($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule467() { + $this->semValue = new Expr\BinaryOp\GreaterOrEqual($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule468() { + $this->semValue = new Expr\Ternary($this->semStack[$this->stackPos-(5-1)], $this->semStack[$this->stackPos-(5-3)], $this->semStack[$this->stackPos-(5-5)], $this->startAttributeStack[$this->stackPos-(5-1)] + $this->endAttributes); + } + + protected function reduceRule469() { + $this->semValue = new Expr\Ternary($this->semStack[$this->stackPos-(4-1)], null, $this->semStack[$this->stackPos-(4-4)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); + } + + protected function reduceRule470() { + $this->semValue = new Expr\ArrayDimFetch($this->semStack[$this->stackPos-(4-1)], $this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); + } + + protected function reduceRule471() { + $this->semValue = $this->semStack[$this->stackPos-(3-2)]; + } + + protected function reduceRule472() { + $this->semValue = new Expr\ConstFetch($this->semStack[$this->stackPos-(1-1)], $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); + } + + protected function reduceRule473() { + $this->semValue = new Expr\ClassConstFetch($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule474() { + $this->semValue = $this->semStack[$this->stackPos-(1-1)]; + } + + protected function reduceRule475() { + $this->semValue = $this->semStack[$this->stackPos-(1-1)]; + } + + protected function reduceRule476() { + $attrs = $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes; $attrs['kind'] = Scalar\String_::KIND_DOUBLE_QUOTED; + foreach ($this->semStack[$this->stackPos-(3-2)] as $s) { if ($s instanceof Node\Scalar\EncapsedStringPart) { $s->value = Node\Scalar\String_::parseEscapeSequences($s->value, '"', true); } }; $this->semValue = new Scalar\Encapsed($this->semStack[$this->stackPos-(3-2)], $attrs); + } + + protected function reduceRule477() { + $attrs = $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes; $attrs['kind'] = strpos($this->semStack[$this->stackPos-(3-1)], "'") === false ? Scalar\String_::KIND_HEREDOC : Scalar\String_::KIND_NOWDOC; preg_match('/\A[bB]?<<<[ \t]*[\'"]?([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)[\'"]?(?:\r\n|\n|\r)\z/', $this->semStack[$this->stackPos-(3-1)], $matches); $attrs['docLabel'] = $matches[1];; + foreach ($this->semStack[$this->stackPos-(3-2)] as $s) { if ($s instanceof Node\Scalar\EncapsedStringPart) { $s->value = Node\Scalar\String_::parseEscapeSequences($s->value, null, true); } } $s->value = preg_replace('~(\r\n|\n|\r)\z~', '', $s->value); if ('' === $s->value) array_pop($this->semStack[$this->stackPos-(3-2)]);; $this->semValue = new Scalar\Encapsed($this->semStack[$this->stackPos-(3-2)], $attrs); + } + + protected function reduceRule478() { + $this->semValue = array(); + } + + protected function reduceRule479() { + $this->semValue = $this->semStack[$this->stackPos-(2-1)]; + } + + protected function reduceRule480() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule481() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule482() { + $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; + } + + protected function reduceRule483() { + $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); + } + + protected function reduceRule484() { + $this->semValue = new Expr\ArrayItem($this->semStack[$this->stackPos-(3-3)], $this->semStack[$this->stackPos-(3-1)], false, $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule485() { + $this->semValue = new Expr\ArrayItem($this->semStack[$this->stackPos-(1-1)], null, false, $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); + } + + protected function reduceRule486() { + $this->semValue = $this->semStack[$this->stackPos-(1-1)]; + } + + protected function reduceRule487() { + $this->semValue = $this->semStack[$this->stackPos-(1-1)]; + } + + protected function reduceRule488() { + $this->semValue = $this->semStack[$this->stackPos-(1-1)]; + } + + protected function reduceRule489() { + $this->semValue = $this->semStack[$this->stackPos-(1-1)]; + } + + protected function reduceRule490() { + $this->semValue = new Expr\ArrayDimFetch($this->semStack[$this->stackPos-(6-2)], $this->semStack[$this->stackPos-(6-5)], $this->startAttributeStack[$this->stackPos-(6-1)] + $this->endAttributes); + } + + protected function reduceRule491() { + $this->semValue = new Expr\ArrayDimFetch($this->semStack[$this->stackPos-(4-1)], $this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); + } + + protected function reduceRule492() { + $this->semValue = new Expr\PropertyFetch($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule493() { + $this->semValue = new Expr\MethodCall($this->semStack[$this->stackPos-(4-1)], $this->semStack[$this->stackPos-(4-3)], $this->semStack[$this->stackPos-(4-4)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); + } + + protected function reduceRule494() { + $this->semValue = new Expr\FuncCall($this->semStack[$this->stackPos-(2-1)], $this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); + } + + protected function reduceRule495() { + $this->semValue = new Expr\ArrayDimFetch($this->semStack[$this->stackPos-(4-1)], $this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); + } + + protected function reduceRule496() { + $this->semValue = new Expr\ArrayDimFetch($this->semStack[$this->stackPos-(4-1)], $this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); + } + + protected function reduceRule497() { + $this->semValue = $this->semStack[$this->stackPos-(1-1)]; + } + + protected function reduceRule498() { + $this->semValue = $this->semStack[$this->stackPos-(3-2)]; + } + + protected function reduceRule499() { + $this->semValue = $this->semStack[$this->stackPos-(1-1)]; + } + + protected function reduceRule500() { + $this->semValue = new Expr\Variable($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); + } + + protected function reduceRule501() { + $this->semValue = $this->semStack[$this->stackPos-(1-1)]; + } + + protected function reduceRule502() { + $this->semValue = $this->semStack[$this->stackPos-(1-1)]; + } + + protected function reduceRule503() { + $this->semValue = new Expr\StaticPropertyFetch($this->semStack[$this->stackPos-(4-1)], $this->semStack[$this->stackPos-(4-4)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); + } + + protected function reduceRule504() { + $this->semValue = $this->semStack[$this->stackPos-(1-1)]; + } + + protected function reduceRule505() { + $this->semValue = new Expr\StaticPropertyFetch($this->semStack[$this->stackPos-(3-1)], substr($this->semStack[$this->stackPos-(3-3)], 1), $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule506() { + $this->semValue = new Expr\StaticPropertyFetch($this->semStack[$this->stackPos-(6-1)], $this->semStack[$this->stackPos-(6-5)], $this->startAttributeStack[$this->stackPos-(6-1)] + $this->endAttributes); + } + + protected function reduceRule507() { + $this->semValue = new Expr\ArrayDimFetch($this->semStack[$this->stackPos-(4-1)], $this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); + } + + protected function reduceRule508() { + $this->semValue = new Expr\ArrayDimFetch($this->semStack[$this->stackPos-(4-1)], $this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); + } + + protected function reduceRule509() { + $this->semValue = new Expr\ArrayDimFetch($this->semStack[$this->stackPos-(4-1)], $this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); + } + + protected function reduceRule510() { + $this->semValue = new Expr\ArrayDimFetch($this->semStack[$this->stackPos-(4-1)], $this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); + } + + protected function reduceRule511() { + $this->semValue = new Expr\Variable(substr($this->semStack[$this->stackPos-(1-1)], 1), $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); + } + + protected function reduceRule512() { + $this->semValue = new Expr\Variable($this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); + } + + protected function reduceRule513() { + $this->semValue = null; + } + + protected function reduceRule514() { + $this->semValue = $this->semStack[$this->stackPos-(1-1)]; + } + + protected function reduceRule515() { + $this->semValue = $this->semStack[$this->stackPos-(1-1)]; + } + + protected function reduceRule516() { + $this->semValue = $this->semStack[$this->stackPos-(3-2)]; + } + + protected function reduceRule517() { + $this->semValue = $this->semStack[$this->stackPos-(1-1)]; + } + + protected function reduceRule518() { + $this->semValue = new Expr\Error($this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); $this->errorState = 2; + } + + protected function reduceRule519() { + $this->semValue = new Expr\List_($this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); + } + + protected function reduceRule520() { + $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; + } + + protected function reduceRule521() { + $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); + } + + protected function reduceRule522() { + $this->semValue = new Expr\ArrayItem($this->semStack[$this->stackPos-(1-1)], null, false, $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); + } + + protected function reduceRule523() { + $this->semValue = new Expr\ArrayItem($this->semStack[$this->stackPos-(1-1)], null, false, $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); + } + + protected function reduceRule524() { + $this->semValue = null; + } + + protected function reduceRule525() { + $this->semValue = array(); + } + + protected function reduceRule526() { + $this->semValue = $this->semStack[$this->stackPos-(2-1)]; + } + + protected function reduceRule527() { + $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; + } + + protected function reduceRule528() { + $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); + } + + protected function reduceRule529() { + $this->semValue = new Expr\ArrayItem($this->semStack[$this->stackPos-(3-3)], $this->semStack[$this->stackPos-(3-1)], false, $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule530() { + $this->semValue = new Expr\ArrayItem($this->semStack[$this->stackPos-(1-1)], null, false, $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); + } + + protected function reduceRule531() { + $this->semValue = new Expr\ArrayItem($this->semStack[$this->stackPos-(4-4)], $this->semStack[$this->stackPos-(4-1)], true, $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); + } + + protected function reduceRule532() { + $this->semValue = new Expr\ArrayItem($this->semStack[$this->stackPos-(2-2)], null, true, $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); + } + + protected function reduceRule533() { + $this->semStack[$this->stackPos-(2-1)][] = $this->semStack[$this->stackPos-(2-2)]; $this->semValue = $this->semStack[$this->stackPos-(2-1)]; + } + + protected function reduceRule534() { + $this->semStack[$this->stackPos-(2-1)][] = $this->semStack[$this->stackPos-(2-2)]; $this->semValue = $this->semStack[$this->stackPos-(2-1)]; + } + + protected function reduceRule535() { + $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); + } + + protected function reduceRule536() { + $this->semValue = array($this->semStack[$this->stackPos-(2-1)], $this->semStack[$this->stackPos-(2-2)]); + } + + protected function reduceRule537() { + $this->semValue = new Scalar\EncapsedStringPart($this->semStack[$this->stackPos-(1-1)], $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); + } + + protected function reduceRule538() { + $this->semValue = new Expr\Variable(substr($this->semStack[$this->stackPos-(1-1)], 1), $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); + } + + protected function reduceRule539() { + $this->semValue = $this->semStack[$this->stackPos-(1-1)]; + } + + protected function reduceRule540() { + $this->semValue = new Expr\ArrayDimFetch($this->semStack[$this->stackPos-(4-1)], $this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); + } + + protected function reduceRule541() { + $this->semValue = new Expr\PropertyFetch($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule542() { + $this->semValue = new Expr\Variable($this->semStack[$this->stackPos-(3-2)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule543() { + $this->semValue = new Expr\Variable($this->semStack[$this->stackPos-(3-2)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule544() { + $this->semValue = new Expr\ArrayDimFetch(new Expr\Variable($this->semStack[$this->stackPos-(6-2)], $this->startAttributeStack[$this->stackPos-(6-1)] + $this->endAttributes), $this->semStack[$this->stackPos-(6-4)], $this->startAttributeStack[$this->stackPos-(6-1)] + $this->endAttributes); + } + + protected function reduceRule545() { + $this->semValue = $this->semStack[$this->stackPos-(3-2)]; + } + + protected function reduceRule546() { + $this->semValue = new Scalar\String_($this->semStack[$this->stackPos-(1-1)], $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); + } + + protected function reduceRule547() { + $this->semValue = $this->parseNumString($this->semStack[$this->stackPos-(1-1)], $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); + } + + protected function reduceRule548() { + $this->semValue = new Expr\Variable(substr($this->semStack[$this->stackPos-(1-1)], 1), $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/Parser/Php7.php b/lib/nikic/php-parser/lib/PhpParser/Parser/Php7.php new file mode 100644 index 000000000..591bd61fc --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Parser/Php7.php @@ -0,0 +1,2872 @@ +'", + "T_IS_GREATER_OR_EQUAL", + "T_SL", + "T_SR", + "'+'", + "'-'", + "'.'", + "'*'", + "'/'", + "'%'", + "'!'", + "T_INSTANCEOF", + "'~'", + "T_INC", + "T_DEC", + "T_INT_CAST", + "T_DOUBLE_CAST", + "T_STRING_CAST", + "T_ARRAY_CAST", + "T_OBJECT_CAST", + "T_BOOL_CAST", + "T_UNSET_CAST", + "'@'", + "T_POW", + "'['", + "T_NEW", + "T_CLONE", + "T_EXIT", + "T_IF", + "T_ELSEIF", + "T_ELSE", + "T_ENDIF", + "T_LNUMBER", + "T_DNUMBER", + "T_STRING", + "T_STRING_VARNAME", + "T_VARIABLE", + "T_NUM_STRING", + "T_INLINE_HTML", + "T_ENCAPSED_AND_WHITESPACE", + "T_CONSTANT_ENCAPSED_STRING", + "T_ECHO", + "T_DO", + "T_WHILE", + "T_ENDWHILE", + "T_FOR", + "T_ENDFOR", + "T_FOREACH", + "T_ENDFOREACH", + "T_DECLARE", + "T_ENDDECLARE", + "T_AS", + "T_SWITCH", + "T_ENDSWITCH", + "T_CASE", + "T_DEFAULT", + "T_BREAK", + "T_CONTINUE", + "T_GOTO", + "T_FUNCTION", + "T_CONST", + "T_RETURN", + "T_TRY", + "T_CATCH", + "T_FINALLY", + "T_THROW", + "T_USE", + "T_INSTEADOF", + "T_GLOBAL", + "T_STATIC", + "T_ABSTRACT", + "T_FINAL", + "T_PRIVATE", + "T_PROTECTED", + "T_PUBLIC", + "T_VAR", + "T_UNSET", + "T_ISSET", + "T_EMPTY", + "T_HALT_COMPILER", + "T_CLASS", + "T_TRAIT", + "T_INTERFACE", + "T_EXTENDS", + "T_IMPLEMENTS", + "T_OBJECT_OPERATOR", + "T_LIST", + "T_ARRAY", + "T_CALLABLE", + "T_CLASS_C", + "T_TRAIT_C", + "T_METHOD_C", + "T_FUNC_C", + "T_LINE", + "T_FILE", + "T_START_HEREDOC", + "T_END_HEREDOC", + "T_DOLLAR_OPEN_CURLY_BRACES", + "T_CURLY_OPEN", + "T_PAAMAYIM_NEKUDOTAYIM", + "T_NAMESPACE", + "T_NS_C", + "T_DIR", + "T_NS_SEPARATOR", + "T_ELLIPSIS", + "';'", + "'{'", + "'}'", + "'('", + "')'", + "'`'", + "']'", + "'\"'", + "'$'" + ); + + protected $tokenToSymbol = array( + 0, 157, 157, 157, 157, 157, 157, 157, 157, 157, + 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, + 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, + 157, 157, 157, 53, 155, 157, 156, 52, 35, 157, + 151, 152, 50, 47, 7, 48, 49, 51, 157, 157, + 157, 157, 157, 157, 157, 157, 157, 157, 29, 148, + 41, 15, 43, 28, 65, 157, 157, 157, 157, 157, + 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, + 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, + 157, 67, 157, 154, 34, 157, 153, 157, 157, 157, + 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, + 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, + 157, 157, 157, 149, 33, 150, 55, 157, 157, 157, + 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, + 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, + 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, + 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, + 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, + 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, + 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, + 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, + 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, + 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, + 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, + 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, + 157, 157, 157, 157, 157, 157, 1, 2, 3, 4, + 5, 6, 8, 9, 10, 11, 12, 13, 14, 16, + 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, + 27, 30, 31, 32, 36, 37, 38, 39, 40, 42, + 44, 45, 46, 54, 56, 57, 58, 59, 60, 61, + 62, 63, 64, 66, 68, 69, 70, 71, 72, 73, + 74, 75, 76, 77, 78, 79, 80, 81, 157, 157, + 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, + 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, + 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, + 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, + 132, 133, 134, 135, 136, 137, 157, 157, 157, 157, + 157, 157, 138, 139, 140, 141, 142, 143, 144, 145, + 146, 147 + ); + + protected $action = array( + 583, 584, 585, 586, 587, 1037, 588, 589, 590, 626, + 627, 479, 29, 101, 102, 103, 104, 105, 106, 107, + 108, 109, 110, 111, 112,-32766,-32766,-32766, 97, 98, + 99, 0, 241, 387, -282,-32766,-32766,-32766,-32766, -487, + 1081, 544, 1084, 1082, 100,-32766, 664,-32766,-32766,-32766, + -32766,-32766, 591, 901, 903,-32766, 30,-32766,-32766,-32766, + -32766,-32766,-32766, 1034,-32766, 295, 592, 593, 594, 595, + 596, 597, 598,-32766, 274, 658, 869, 870, 871, 868, + 867, 866, 599, 600, 601, 602, 603, 604, 605, 606, + 607, 608, 609, 629, 630, 631, 632, 633, 621, 622, + 623, 624, 625, 610, 611, 612, 613, 614, 615, 616, + 652, 653, 654, 655, 656, 657, 617, 618, 619, 620, + 650, 641, 639, 640, 636, 637, -251, 628, 634, 635, + 642, 643, 645, 644, 646, 647, 74, 75, 76, 556, + 266, 638, 649, 648, 739, 44, 45, 392, 46, 47, + 375, 680, 681, 73, 48, 49, 28, 50, 77, 78, + 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, + 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, + 99, 218, 241, 996, -487, -443, -487,-32766,-32766,-32766, + 51, 52, 116, 663, 100, 339, 53, 242, 54, 221, + 222, 55, 56, 57, 58, 59, 60, 61, 62, -173, + 24, 234, 63, 347, 393,-32766,-32766,-32766, 1001, 1002, + 394, 228, 1034, 217, 729,-32766, 1000, 34, 19, 395, + 1051, 396, 127, 397, 118, 398, -442, 24, 399, 984, + 43, 267, 36, 37, 400, 351, -443, 38, 401, 1034, + 248, 64, 289, 1000, 288, 290, 248,-32766, 741, 226, + -443, 1034, 404, 405, 406, 442, 291, -443, 371, -446, + 376, -251, 409, 410, 26, 1006, 1007, 1008, 1009, 1003, + 1004, 245, 977,-32766,-32766,-32766, 419, 1010, 1005, 349, + -488, 226, 549, 278, 65,-32766, 257, -442, 262, 266, + 410, 660, 467,-32766, 1073,-32766, 1048, 1072,-32766,-32766, + -32766, -442,-32766,-32766,-32766, 1078,-32766, 1034, -442,-32766, + -445, 67, 1014,-32766,-32766,-32766, 266,-32766,-32766,-32766, + -479, 123,-32766, 660, -172,-32766, 418,-32766, 266, 531, + -32766,-32766,-32766,-32766,-32766,-32766,-32766, 223,-32766, 560, + 977,-32766, 818, 819, -173,-32766,-32766,-32766, 818, 819, + -32766,-32766, -227, 561,-32766, 27, 224,-32766, 418,-32766, + -32766, 122, -441,-32766, -232,-32766, 824, 40, 124, 227, + -88, 791, 265,-32766, 984, 1052,-32766,-32766,-32766, 660, + 94, 95, 96,-32766, 266, 364,-32766,-32766,-32766, 42, + -32766, 553,-32766, 122,-32766,-32766,-32766,-32766,-32766,-32766, + -32766,-32766,-32766,-32766,-32766,-32766,-32766,-32766, 363, 532, + -32766, 660, 554,-32766, 418,-32766, -477, 9,-32766,-32766, + -32766,-32766,-32766, -441,-32766, -488,-32766, -488, 249,-32766, + 248, 660, 121,-32766,-32766,-32766,-32766, -441,-32766,-32766, + 359, 555,-32766, 551, -441,-32766, 418, 517, 518, 115, + 250,-32766, 1034,-32766,-32767,-32767,-32767,-32767, 92, 93, + 94, 95, 96, 23, 308, -479, 504, 20, 344, -172, + 225, 117, 741, 126,-32766, 533, -441, 564, 349,-32766, + 660, 133, 847,-32766,-32766, 977, 120,-32766,-32766,-32766, + 792,-32766, 119,-32766, 114,-32766, 345, 419,-32766, 113, + 349, 130,-32766,-32766,-32766, 132,-32766,-32766,-32766, 738, + 741,-32766, 660, 241,-32766, 418,-32766, 244,-32766,-32766, + -32766,-32766,-32766,-32766, 128,-32766, 753,-32766, 527, 266, + -32766, 741, 818, 819,-32766,-32766,-32766, -441, 100,-32766, + -32766, 129, 313,-32766, 680, 681,-32766, 418, 41,-32766, + 660, -441,-32766, 453,-32766, 660, 321,-32766, -441,-32766, + 777, -477,-32766,-32766,-32766, 1083,-32766, 261,-32766, 441, + -32766, 385, 8,-32766, 437, 24, 360,-32766,-32766,-32766, + 497, 498,-32766,-32766,-32766, 501,-32766, 1034,-32766,-32766, + 418, 1000, 818, 819, 660, 846, 575,-32766,-32766, 358, + -4,-32766,-32766,-32766, 301,-32766, 1076,-32766, 661,-32766, + 455, 696,-32766, 858, 565, 513,-32766,-32766,-32766, 440, + 977,-32766,-32766, 973, 446,-32766, 505,-32766,-32766, 418, + -133, -133, -133,-32766,-32766,-32766,-32766, 409, 410, 451, + 542, 528, 509, 521, 510, -133, 12, -133, -80, -133, + 216, -133, 495,-32766, 458,-32766,-32766,-32766,-32766, 67, + 348, 356, 259, 258, 266, 1016,-32766,-32766,-32766,-32766, + 260, 402, 403, 869, 870, 871, 868, 867, 866, 861, + 715, 760, 407, 408, 977, 761, 762,-32766, 11,-32766, + -32766,-32766,-32766,-32766,-32766,-32767,-32767,-32767,-32767,-32767, + 264, 229, 348, 337, 1013, 852, 741, 17, -133, 256, + -212, -212, -212, 402, 403, -400, 348, 5, 307, 775, + 758, 21, 672, 760, 407, 408, 329, 402, 403, -211, + -211, -211, 448, 24, 326, 348, 715, 760, 407, 408, + 341, 340, 318, 276, 325, 1034, 402, 403, 741, 1000, + -4,-32766,-32766,-32766, 359, 715, 760, 407, 408, 755, + 552, 33, 741, 573, -212, 574, 720, 842, 794, 778, + 32,-32766, 851,-32766,-32766, 854, 853, 850, 977, 773, + 785, 741, 718, -211, 786, 843, 741, 252, 334, 550, + 557, 558, 559, 562, 272, 409, 410, 273, 571, 570, + 568, 566, 563, 335, 0, 757, 965, 783, 859, 0, + 746, 964, 963, 756, 748, 683, 0, 67, 1079, 682, + 685, 784, 266, 567, 716, 1080, 675, 674, 684, 759, + 1049, 1046, 1041, 1077, 1035, 1028, 0, -444, -467, -446, + -445, 22, 25, 31, 35, 39, 66, 338, 336, 275, + 240, 239, 238, 237, 220, 219, 134, 131, 125, 72, + 71, 70, 69, 68, -469, 0, 310, 475, 941, 491, + 541, 944, 13, 969, 825, 998, 940, 988, -230, -88, + 538, 390, 383, 380, 377, 311, 18, 16, 15, 14, + -227, -228, 0, 957, -412, 0, 503, 0, 1040, 1075, + 1026, 1027, 997, 0, 1015 + ); + + protected $actionCheck = array( + 2, 3, 4, 5, 6, 1, 8, 9, 10, 11, + 12, 48, 15, 16, 17, 18, 19, 20, 21, 22, + 23, 24, 25, 26, 27, 8, 9, 10, 50, 51, + 52, 0, 54, 7, 79, 8, 9, 10, 8, 7, + 77, 77, 79, 80, 66, 28, 1, 30, 31, 32, + 33, 34, 54, 56, 57, 28, 13, 30, 31, 32, + 33, 34, 35, 79, 109, 7, 68, 69, 70, 71, + 72, 73, 74, 118, 7, 77, 112, 113, 114, 115, + 116, 117, 84, 85, 86, 87, 88, 89, 90, 91, + 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, + 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, + 122, 123, 124, 125, 126, 127, 7, 129, 130, 131, + 132, 133, 134, 135, 136, 137, 8, 9, 10, 29, + 156, 143, 144, 145, 1, 2, 3, 4, 5, 6, + 29, 102, 103, 149, 11, 12, 28, 14, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, + 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, + 52, 13, 54, 1, 152, 67, 154, 8, 9, 10, + 47, 48, 13, 148, 66, 146, 53, 7, 55, 56, + 57, 58, 59, 60, 61, 62, 63, 64, 65, 7, + 67, 68, 69, 70, 71, 8, 9, 10, 75, 76, + 77, 7, 79, 13, 81, 1, 83, 84, 85, 86, + 1, 88, 67, 90, 7, 92, 67, 67, 95, 1, + 7, 67, 99, 100, 101, 102, 128, 104, 105, 79, + 28, 108, 7, 83, 111, 112, 28, 1, 148, 35, + 142, 79, 119, 120, 121, 82, 7, 149, 7, 151, + 149, 152, 129, 130, 7, 132, 133, 134, 135, 136, + 137, 138, 112, 8, 9, 10, 143, 144, 145, 146, + 7, 35, 149, 33, 151, 71, 153, 128, 155, 156, + 130, 77, 128, 28, 79, 81, 77, 82, 84, 85, + 86, 142, 88, 1, 90, 150, 92, 79, 149, 95, + 151, 151, 139, 99, 100, 101, 156, 71, 104, 105, + 7, 149, 108, 77, 7, 111, 112, 81, 156, 79, + 84, 85, 86, 119, 88, 1, 90, 35, 92, 29, + 112, 95, 130, 131, 152, 99, 100, 101, 130, 131, + 104, 105, 152, 29, 108, 140, 141, 111, 112, 8, + 9, 147, 67, 149, 152, 119, 152, 67, 149, 35, + 152, 29, 7, 71, 1, 152, 8, 9, 10, 77, + 47, 48, 49, 81, 156, 7, 84, 85, 86, 67, + 88, 29, 90, 147, 92, 149, 28, 95, 30, 31, + 32, 99, 100, 101, 1, 71, 104, 105, 7, 77, + 108, 77, 29, 111, 112, 81, 7, 7, 84, 85, + 86, 119, 88, 128, 90, 152, 92, 154, 128, 95, + 28, 77, 29, 99, 100, 101, 1, 142, 104, 105, + 146, 29, 108, 149, 149, 111, 112, 72, 73, 149, + 128, 149, 79, 119, 41, 42, 43, 44, 45, 46, + 47, 48, 49, 7, 142, 152, 72, 73, 7, 152, + 35, 149, 148, 15, 71, 143, 67, 29, 146, 1, + 77, 15, 150, 149, 81, 112, 15, 84, 85, 86, + 148, 88, 15, 90, 15, 92, 123, 143, 95, 15, + 146, 15, 99, 100, 101, 15, 71, 104, 105, 29, + 148, 108, 77, 54, 111, 112, 81, 29, 1, 84, + 85, 86, 119, 88, 29, 90, 35, 92, 74, 156, + 95, 148, 130, 131, 99, 100, 101, 128, 66, 104, + 105, 97, 98, 108, 102, 103, 111, 112, 67, 71, + 77, 142, 149, 77, 119, 77, 78, 82, 149, 81, + 148, 152, 84, 85, 86, 80, 88, 110, 90, 77, + 92, 102, 103, 95, 77, 67, 77, 99, 100, 101, + 106, 107, 104, 105, 149, 79, 108, 79, 71, 111, + 112, 83, 130, 131, 77, 148, 149, 119, 81, 77, + 0, 84, 85, 86, 77, 88, 77, 90, 77, 92, + 77, 77, 95, 148, 149, 79, 99, 100, 101, 79, + 112, 104, 105, 79, 82, 108, 87, 149, 111, 112, + 72, 73, 74, 8, 9, 10, 119, 129, 130, 86, + 89, 91, 93, 96, 96, 87, 94, 89, 94, 91, + 94, 93, 109, 28, 94, 30, 31, 32, 33, 151, + 102, 102, 127, 126, 156, 139, 149, 8, 9, 10, + 109, 113, 114, 112, 113, 114, 115, 116, 117, 118, + 122, 123, 124, 125, 112, 123, 123, 28, 142, 30, + 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 126, 35, 102, 103, 139, 148, 148, 152, 150, 109, + 96, 97, 98, 113, 114, 142, 102, 142, 142, 148, + 150, 152, 122, 123, 124, 125, 146, 113, 114, 96, + 97, 98, 146, 67, 146, 102, 122, 123, 124, 125, + 146, 146, 146, 143, 146, 79, 113, 114, 148, 83, + 150, 8, 9, 10, 146, 122, 123, 124, 125, 147, + 149, 148, 148, 148, 150, 148, 148, 148, 148, 148, + 148, 28, 148, 30, 31, 148, 148, 148, 112, 148, + 148, 148, 148, 150, 148, 148, 148, 152, 149, 149, + 149, 149, 149, 149, 149, 129, 130, 149, 149, 149, + 149, 149, 149, 149, -1, 150, 150, 150, 150, -1, + 150, 150, 150, 150, 150, 150, -1, 151, 150, 150, + 150, 150, 156, 150, 150, 150, 150, 150, 150, 150, + 150, 150, 150, 150, 150, 150, -1, 151, 151, 151, + 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, + 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, + 151, 151, 151, 151, 151, -1, 152, 152, 152, 152, + 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, + 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, + 152, 152, -1, 153, 153, -1, 154, -1, 154, 154, + 154, 154, 154, -1, 155 + ); + + protected $actionBase = array( + 0, 568, 610, 624, 643, 182, 342, 567, -2, -2, + -2, -2, -36, 393, 110, 334, 110, 372, 422, 648, + 648, 648, 224, 256, 312, 312, 312, 488, 413, 445, + 344, 527, 527, 527, 527, 527, 527, 527, 527, 527, + 527, 527, 527, 527, 527, 527, 527, 527, 527, 527, + 527, 527, 527, 527, 527, 527, 527, 527, 527, 527, + 527, 527, 527, 527, 527, 527, 527, 527, 527, 527, + 527, 527, 527, 527, 527, 527, 527, 527, 527, 527, + 527, 527, 527, 527, 527, 527, 527, 527, 527, 527, + 527, 527, 527, 527, 527, 527, 527, 527, 527, 527, + 527, 527, 527, 527, 527, 527, 527, 527, 527, 527, + 527, 527, 527, 527, 527, 527, 527, 527, 527, 527, + 527, 527, 527, 527, 527, 527, 527, 527, 527, 527, + 527, 527, 527, 527, 527, 45, 45, 352, 43, 645, + 729, 725, 565, 730, 566, 724, 726, 168, 693, 694, + 505, 695, 692, 691, 690, 727, 752, 579, 728, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 30, 179, 361, 207, 207, + 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, + 207, 207, 207, 207, 207, 207, 207, 275, 275, 275, + 753, 378, 419, 635, 17, 305, 27, 669, 669, 669, + 669, 669, 423, 423, 423, 423, 676, 676, 518, 170, + 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, + 689, 580, 665, 666, 383, 343, 343, 222, 222, 222, + 222, 238, 228, -45, 412, 183, 536, 759, 472, 229, + 229, 118, 169, -22, -22, -22, 49, 552, 582, 582, + 582, 582, 225, 225, 582, 582, 4, -37, 305, 305, + 332, 305, 452, 452, 452, 364, 304, 485, 364, 621, + 558, 667, 557, 681, 310, 283, 32, 605, -16, 604, + 569, -16, 484, 404, 385, 737, 45, 583, 45, 45, + 45, 45, 45, 45, 45, 45, 45, -16, -16, 45, + 121, 45, 457, 352, 475, 469, 543, 174, 655, 327, + 233, 165, 469, 469, 469, 658, 649, 119, 210, 664, + 202, 479, 323, 260, 483, 483, 501, 507, 486, 483, + 483, 483, 483, 516, 483, 700, 700, 704, 501, 483, + 700, 501, 227, 411, 245, 259, 501, 388, 547, 483, + 584, 584, 261, 507, 550, 214, 466, 545, 700, 700, + 545, 486, 190, 501, 375, 625, 627, 553, 622, 67, + 498, 498, 471, 553, 26, 501, 498, 516, 420, 58, + 498, 31, 705, 722, 490, 721, 702, 720, 706, 719, + 537, 650, 572, 573, 714, 713, 718, 502, 532, 703, + 701, 596, 509, 494, 489, 585, 491, 696, 569, 618, + 482, 482, 482, 491, 698, 482, 482, 482, 482, 482, + 482, 482, 482, 758, 267, 586, 563, 487, 606, 570, + 481, 662, 575, 596, 596, 684, 751, 750, 541, 712, + 735, 717, 632, 468, 744, 711, 683, 608, 544, 598, + 710, 743, 734, 661, 494, 733, 685, 539, 596, 686, + 482, 697, 723, 756, 757, 699, 754, 742, 590, 495, + 755, 687, 732, 660, 659, 623, 747, 736, 741, 688, + 740, 628, 549, 749, 559, 707, 546, 708, 651, 680, + 679, 496, 629, 678, 716, 630, 746, 745, 748, 631, + 642, 652, 653, 500, 675, 476, 647, 715, 320, 464, + 560, 646, 554, 731, 674, 654, 709, 644, 581, 673, + 672, 738, 564, 618, 556, 467, 562, 561, 663, 671, + 739, 458, 641, 639, 638, 637, 670, 634, 668, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 143, + 143, 143, 143, -2, -2, -2, 0, 0, 0, 0, + -2, 143, 143, 143, 143, 143, 143, 143, 143, 143, + 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, + 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, + 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, + 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, + 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, + 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, + 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, + 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, + 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, + 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, + 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, + 143, 143, 143, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + -3, 128, 128, -3, 128, 128, 128, 128, 128, 128, + -22, -22, -22, -22, 364, 364, 364, 364, 364, 364, + 364, 364, 364, 364, 364, 364, 364, 364, 571, 571, + 571, 571, 364, -22, -22, 364, 364, 364, 364, 364, + 364, 571, 364, 225, 225, 225, 364, -16, -16, 0, + 0, 0, 0, 0, 483, 225, 364, 364, 364, 364, + 0, 0, 364, 364, -16, 0, 0, 0, 0, 0, + 483, 483, 483, 0, 483, 225, 0, 45, 454, 454, + 454, 454, 0, 0, 0, 483, 0, 483, 550, 0, + 0, 0, 0, 501, 0, 700, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 482, 712, 0, 541, 0, 0, 0, + 482, 482, 482, 541, 541, 0, 0, 541 + ); + + protected $actionDefault = array( + 3,32767,32767,32767,32767,32767,32767,32767,32767, 88, + 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, + 32767,32767,32767, 88, 489, 489, 489,32767,32767,32767, + 32767, 302, 302, 302,32767, 481, 439, 439, 439, 439, + 439, 439, 439, 481,32767,32767,32767,32767,32767, 381, + 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, + 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, + 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, + 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, + 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, + 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, + 32767,32767,32767,32767,32767,32767,32767,32767, 88,32767, + 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, + 32767,32767,32767,32767,32767,32767,32767,32767, 486,32767, + 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, + 32767,32767,32767,32767,32767,32767,32767,32767,32767, 364, + 365, 367, 368, 301, 440, 250, 485, 300, 126, 261, + 252, 204, 298, 236, 130, 329, 382, 331, 380, 384, + 330, 307, 311, 312, 313, 314, 315, 316, 317, 318, + 319, 320, 321, 322, 305, 306, 383, 361, 360, 359, + 327, 328, 304, 332, 334, 304, 333, 350, 351, 348, + 349, 352, 353, 354, 355, 356,32767,32767,32767,32767, + 32767,32767,32767,32767,32767,32767,32767,32767, 88,32767, + 284, 284, 284, 284,32767, 341, 342, 242, 242, 242, + 242,32767, 242, 285,32767,32767,32767,32767,32767,32767, + 32767, 433, 358, 336, 337, 335,32767, 411,32767,32767, + 32767,32767,32767, 413,32767, 88,32767,32767, 324, 326, + 405, 308,32767,32767, 90,32767,32767,32767,32767,32767, + 32767,32767,32767,32767, 408, 441, 441,32767,32767, 88, + 399, 88, 169, 223, 225, 174,32767, 416,32767,32767, + 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, + 32767,32767,32767,32767,32767, 346,32767, 496,32767, 441, + 32767,32767, 338, 339, 340,32767,32767, 441, 441,32767, + 441,32767, 441,32767,32767,32767, 174,32767,32767,32767, + 32767,32767,32767,32767, 90, 414, 414, 409, 174,32767, + 32767, 174, 87, 87, 87, 87, 174, 87, 187,32767, + 185, 185, 87, 88, 88, 87, 87, 189,32767, 455, + 189, 88, 87, 174, 87, 209, 209, 390, 176, 89, + 244, 244, 89, 390, 87, 174, 244, 88, 87, 87, + 244,32767,32767,32767, 82,32767,32767,32767,32767,32767, + 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, + 32767, 401,32767,32767, 421,32767, 434, 453, 399,32767, + 344, 345, 347,32767, 443, 369, 370, 371, 372, 373, + 374, 375, 377,32767, 482, 404,32767,32767, 84, 117, + 260,32767, 494, 84, 402,32767, 494,32767,32767,32767, + 32767,32767,32767,32767,32767,32767,32767, 84,32767, 84, + 32767,32767,32767,32767, 478,32767, 441,32767, 403,32767, + 343, 417, 460,32767,32767, 442,32767,32767, 84,32767, + 32767,32767,32767,32767,32767,32767,32767, 421,32767,32767, + 32767,32767,32767, 441,32767,32767,32767,32767,32767,32767, + 32767, 297,32767,32767,32767,32767,32767,32767, 441,32767, + 32767,32767,32767, 235,32767,32767,32767,32767,32767,32767, + 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, + 32767,32767, 82, 60,32767, 278,32767,32767,32767,32767, + 32767,32767,32767,32767,32767,32767,32767,32767,32767, 132, + 132, 3, 3, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 263, 164, 263, 217, + 263, 263, 220, 209, 209, 270, 132, 132 + ); + + protected $goto = array( + 165, 165, 138, 138, 138, 148, 150, 181, 166, 163, + 163, 163, 163, 147, 164, 164, 164, 164, 164, 164, + 164, 147, 159, 160, 161, 162, 178, 176, 179, 420, + 421, 315, 422, 425, 426, 427, 428, 429, 430, 431, + 432, 888, 136, 139, 140, 141, 142, 143, 144, 145, + 146, 149, 175, 177, 180, 197, 200, 201, 203, 204, + 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, + 235, 236, 253, 254, 255, 322, 323, 324, 470, 182, + 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, + 193, 194, 195, 151, 196, 152, 167, 168, 169, 198, + 170, 153, 154, 155, 171, 156, 199, 137, 172, 157, + 173, 174, 158, 534, 202, 438, 736, 281, 471, 857, + 547, 7, 202, 526, 855, 472, 669, 231, 464, 232, + 233, 443, 443, 443, 671, 443, 464, 793, 774, 772, + 774, 569, 670, 436, 802, 797, 459, 456, 443, 545, + 572, 492, 494, 520, 524, 529, 530, 804, 537, 539, + 546, 800, 548, 424, 424, 424, 424, 424, 424, 424, + 424, 424, 424, 424, 424, 424, 424, 423, 423, 423, + 423, 423, 423, 423, 423, 423, 423, 423, 423, 423, + 423, 485, 506, 443, 443, 488, 490, 540, 457, 478, + 443, 443, 974, 443, 768, 312, 543, 706, 444, 300, + 303, 450, 473, 474, 476, 469, 481, 733, 468, 487, + 487, 999, 999, 999, 999, 999, 999, 999, 999, 999, + 999, 999, 999, 701, 689, 831, 435, 835, 776, 697, + 1068, 1068, 779, 435, 263, 749, 482, 3, 4, 247, + 316, 827, 809, 449, 769, 975, 465, 1068, 460, 673, + 770, 770, 770, 770, 872, 1061, 764, 771, 705, 970, + 697, 1071, 697, 976, 1030, 378, 678, 298, 728, 723, + 724, 737, 679, 725, 676, 726, 727, 10, 1053, 677, + 507, 731, 462, 935, 823, 328, 508, 332, 319, 319, + 268, 269, 285, 466, 271, 327, 286, 330, 493, 807, + 807, 1058, 1069, 1069, 282, 283, 812, 688, 688, 816, + 1042, 512, 698, 698, 698, 700, 525, 687, 499, 1069, + 314, 287, 693, 279, 309, 690, 832, 576, 966, 514, + 370, 978, 971, 484, 817, 817, 817, 817, 978, 817, + 836, 817, 865, 702, 1039, 817, 781, 686, 874, 386, + 0, 1039, 0, 0, 0, 978, 978, 978, 978, 1050, + 1050, 978, 978, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 744, 0, 0, 745, 1036, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 834, 0, + 0, 834, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1043, 1044 + ); + + protected $gotoCheck = array( + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 60, 53, 8, 10, 76, 7, 7, + 7, 106, 53, 7, 7, 93, 13, 69, 81, 69, + 69, 8, 8, 8, 15, 8, 81, 13, 13, 13, + 13, 13, 14, 13, 13, 13, 8, 36, 8, 5, + 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 131, 131, 131, 131, 131, 131, 131, + 131, 131, 131, 131, 131, 131, 131, 129, 129, 129, + 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, + 129, 43, 43, 8, 8, 64, 64, 64, 8, 8, + 8, 8, 88, 8, 72, 72, 72, 33, 8, 46, + 46, 46, 46, 46, 46, 2, 2, 52, 8, 82, + 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, + 82, 82, 82, 11, 11, 11, 71, 11, 37, 23, + 139, 139, 11, 71, 128, 11, 11, 34, 34, 128, + 62, 90, 11, 62, 11, 88, 130, 139, 62, 10, + 71, 71, 71, 71, 11, 138, 71, 71, 11, 11, + 23, 139, 23, 88, 88, 62, 10, 49, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 62, 136, 10, + 51, 10, 50, 112, 86, 53, 53, 53, 53, 53, + 53, 53, 53, 53, 53, 53, 53, 53, 53, 81, + 81, 81, 140, 140, 76, 76, 84, 23, 23, 87, + 133, 65, 23, 23, 23, 23, 65, 23, 21, 140, + 65, 17, 27, 9, 16, 25, 92, 78, 118, 20, + 67, 60, 121, 68, 60, 60, 60, 60, 60, 60, + 95, 60, 106, 29, 93, 60, 75, 12, 109, 116, + -1, 93, -1, -1, -1, 60, 60, 60, 60, 93, + 93, 60, 60, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 60, -1, -1, 60, 93, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 93, -1, + -1, 93, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 93, 93 + ); + + protected $gotoBase = array( + 0, 0, -336, 0, 0, 137, 0, 113, -141, 57, + -20, -120, -25, 124, 140, 132, 47, 75, 0, 0, + 4, 55, 0, -17, 0, 46, 0, 58, 0, -10, + -22, 0, 0, 198, -329, 0, -403, 220, 0, 0, + 0, 0, 0, 159, 0, 0, 172, 0, 0, 243, + 72, 73, 201, 79, 0, 0, 0, 0, 0, 0, + 107, 0, -98, 0, -43, -60, 0, -21, -27, -441, + 0, 2, -55, 0, 0, -15, -259, 0, 24, 0, + 0, 93, 3, 0, 74, 0, 50, 71, -95, 0, + 228, 0, 45, 120, 0, -14, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 109, 0, 0, -29, + 0, 0, 52, 0, 0, 0, -24, 0, -8, 0, + 0, 6, 0, 0, 0, 0, 0, 0, -13, -39, + 231, -53, 0, 70, 0, 0, 245, 0, 239, -6, + 66, 0, 0 + ); + + protected $gotoDefault = array( + -32768, 391, 579, 2, 580, 651, 659, 515, 411, 439, + 730, 877, 692, 712, 713, 714, 304, 342, 296, 302, + 500, 489, 382, 699, 354, 691, 379, 694, 353, 703, + 135, 516, 388, 707, 1, 709, 445, 740, 293, 717, + 294, 519, 719, 452, 721, 722, 299, 305, 306, 881, + 461, 486, 732, 205, 454, 734, 292, 735, 743, 333, + 297, 365, 522, 496, 477, 511, 412, 367, 483, 230, + 463, 985, 766, 374, 362, 780, 280, 788, 577, 796, + 799, 413, 414, 372, 811, 373, 821, 815, 993, 366, + 826, 355, 833, 1025, 357, 837, 840, 343, 502, 331, + 844, 845, 6, 849, 535, 536, 864, 243, 384, 873, + 352, 887, 346, 954, 956, 447, 381, 967, 361, 523, + 389, 972, 1029, 350, 415, 368, 270, 284, 246, 416, + 433, 251, 417, 369, 1032, 320, 1054, 434, 1062, 1070, + 277, 317, 480 + ); + + protected $ruleToNonTerminal = array( + 0, 1, 3, 3, 2, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, + 7, 7, 8, 8, 9, 10, 10, 11, 11, 12, + 12, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 17, 17, 18, 18, 18, 18, 20, 22, + 22, 16, 24, 24, 21, 26, 26, 23, 23, 25, + 25, 27, 27, 19, 28, 28, 29, 31, 32, 32, + 33, 34, 34, 36, 35, 35, 35, 35, 37, 37, + 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 13, 13, 56, 56, 59, 59, 58, 57, + 57, 50, 61, 61, 62, 62, 63, 63, 14, 15, + 15, 15, 66, 66, 66, 67, 67, 70, 70, 68, + 68, 72, 73, 73, 44, 44, 52, 52, 55, 55, + 55, 54, 74, 74, 75, 45, 45, 45, 45, 76, + 76, 77, 77, 78, 78, 42, 42, 38, 38, 79, + 40, 40, 80, 39, 39, 41, 41, 51, 51, 51, + 51, 64, 64, 83, 83, 84, 84, 86, 86, 87, + 87, 87, 85, 85, 65, 65, 88, 88, 89, 89, + 90, 90, 90, 47, 91, 91, 92, 48, 94, 94, + 95, 95, 69, 69, 96, 96, 96, 96, 101, 101, + 102, 102, 103, 103, 103, 103, 103, 104, 105, 105, + 100, 100, 97, 97, 99, 99, 107, 107, 106, 106, + 106, 106, 106, 106, 98, 108, 108, 109, 109, 49, + 110, 110, 43, 43, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 117, 111, 111, + 116, 116, 119, 120, 120, 121, 122, 122, 122, 71, + 71, 60, 60, 60, 112, 112, 112, 124, 124, 113, + 113, 115, 115, 115, 118, 118, 129, 129, 129, 82, + 131, 131, 131, 114, 114, 114, 114, 114, 114, 114, + 114, 114, 114, 114, 114, 114, 114, 114, 114, 46, + 46, 127, 127, 127, 123, 123, 123, 132, 132, 132, + 132, 132, 132, 53, 53, 53, 93, 93, 93, 93, + 134, 126, 126, 126, 126, 126, 126, 125, 125, 125, + 133, 133, 133, 133, 81, 135, 135, 136, 136, 136, + 136, 136, 130, 137, 137, 138, 138, 138, 138, 138, + 128, 128, 128, 128, 140, 141, 139, 139, 139, 139, + 139, 139, 139, 142, 142, 142, 142 + ); + + protected $ruleToLength = array( + 1, 1, 2, 0, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 3, 1, 1, 1, 0, 1, 0, + 1, 1, 1, 1, 1, 3, 5, 4, 3, 4, + 2, 3, 1, 1, 7, 8, 6, 7, 2, 3, + 1, 2, 3, 1, 2, 3, 1, 1, 3, 1, + 2, 1, 2, 2, 3, 1, 3, 2, 3, 1, + 3, 2, 0, 1, 1, 1, 1, 1, 3, 7, + 10, 5, 7, 9, 5, 3, 3, 3, 3, 3, + 3, 1, 2, 5, 7, 9, 5, 6, 3, 3, + 2, 1, 1, 1, 0, 2, 1, 3, 8, 0, + 4, 2, 1, 3, 0, 1, 0, 1, 10, 7, + 6, 5, 1, 2, 2, 0, 2, 0, 2, 0, + 2, 2, 1, 3, 1, 4, 1, 4, 1, 1, + 4, 2, 1, 3, 3, 3, 4, 4, 5, 0, + 2, 4, 3, 1, 1, 1, 4, 0, 2, 5, + 0, 2, 6, 0, 2, 0, 3, 1, 2, 1, + 1, 2, 0, 1, 3, 4, 6, 1, 2, 1, + 1, 1, 0, 1, 0, 2, 2, 4, 1, 3, + 1, 2, 2, 2, 3, 1, 1, 2, 3, 1, + 1, 3, 2, 0, 3, 4, 9, 3, 1, 3, + 0, 2, 4, 5, 4, 4, 4, 3, 1, 1, + 1, 3, 1, 1, 0, 1, 1, 2, 1, 1, + 1, 1, 1, 1, 2, 1, 3, 1, 3, 2, + 3, 1, 0, 1, 1, 3, 3, 3, 4, 1, + 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 2, 2, 2, 2, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 2, 2, 2, 2, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, + 4, 3, 4, 4, 2, 2, 4, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 1, 3, + 2, 1, 2, 4, 2, 10, 11, 7, 3, 2, + 0, 4, 2, 1, 3, 2, 2, 2, 4, 1, + 1, 1, 2, 3, 1, 1, 1, 1, 1, 0, + 3, 0, 1, 1, 0, 1, 1, 3, 3, 3, + 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 3, 2, 3, 3, 0, + 1, 1, 3, 1, 1, 3, 1, 1, 4, 4, + 4, 1, 4, 1, 1, 3, 1, 4, 2, 2, + 3, 1, 4, 4, 3, 3, 3, 1, 3, 1, + 1, 3, 1, 1, 4, 3, 1, 1, 1, 3, + 3, 0, 1, 3, 1, 3, 1, 4, 2, 0, + 2, 2, 1, 2, 1, 1, 1, 4, 3, 3, + 3, 6, 3, 1, 1, 2, 1 + ); + + protected function reduceRule0() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule1() { + $this->semValue = $this->handleNamespaces($this->semStack[$this->stackPos-(1-1)]); + } + + protected function reduceRule2() { + if (is_array($this->semStack[$this->stackPos-(2-2)])) { $this->semValue = array_merge($this->semStack[$this->stackPos-(2-1)], $this->semStack[$this->stackPos-(2-2)]); } else { $this->semStack[$this->stackPos-(2-1)][] = $this->semStack[$this->stackPos-(2-2)]; $this->semValue = $this->semStack[$this->stackPos-(2-1)]; }; + } + + protected function reduceRule3() { + $this->semValue = array(); + } + + protected function reduceRule4() { + $startAttributes = $this->lookaheadStartAttributes; if (isset($startAttributes['comments'])) { $nop = new Stmt\Nop(['comments' => $startAttributes['comments']]); } else { $nop = null; }; + if ($nop !== null) { $this->semStack[$this->stackPos-(1-1)][] = $nop; } $this->semValue = $this->semStack[$this->stackPos-(1-1)]; + } + + protected function reduceRule5() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule6() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule7() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule8() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule9() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule10() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule11() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule12() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule13() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule14() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule15() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule16() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule17() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule18() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule19() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule20() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule21() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule22() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule23() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule24() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule25() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule26() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule27() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule28() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule29() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule30() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule31() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule32() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule33() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule34() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule35() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule36() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule37() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule38() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule39() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule40() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule41() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule42() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule43() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule44() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule45() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule46() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule47() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule48() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule49() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule50() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule51() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule52() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule53() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule54() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule55() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule56() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule57() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule58() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule59() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule60() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule61() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule62() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule63() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule64() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule65() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule66() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule67() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule68() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule69() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule70() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule71() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule72() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule73() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule74() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule75() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule76() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule77() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule78() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule79() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule80() { + $this->semValue = $this->semStack[$this->stackPos-(1-1)]; + } + + protected function reduceRule81() { + $this->semValue = $this->semStack[$this->stackPos-(1-1)]; + } + + protected function reduceRule82() { + $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); + } + + protected function reduceRule83() { + $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; + } + + protected function reduceRule84() { + $this->semValue = new Name($this->semStack[$this->stackPos-(1-1)], $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); + } + + protected function reduceRule85() { + /* nothing */ + } + + protected function reduceRule86() { + /* nothing */ + } + + protected function reduceRule87() { + /* nothing */ + } + + protected function reduceRule88() { + $this->emitError(new Error('A trailing comma is not allowed here', $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes)); + } + + protected function reduceRule89() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule90() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule91() { + $this->semValue = $this->semStack[$this->stackPos-(1-1)]; + } + + protected function reduceRule92() { + $this->semValue = $this->semStack[$this->stackPos-(1-1)]; + } + + protected function reduceRule93() { + $this->semValue = $this->semStack[$this->stackPos-(1-1)]; + } + + protected function reduceRule94() { + $this->semValue = new Stmt\HaltCompiler($this->lexer->handleHaltCompiler(), $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); + } + + protected function reduceRule95() { + $this->semValue = new Stmt\Namespace_($this->semStack[$this->stackPos-(3-2)], null, $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + $this->semValue->setAttribute('kind', Stmt\Namespace_::KIND_SEMICOLON); + $this->checkNamespace($this->semValue); + } + + protected function reduceRule96() { + $this->semValue = new Stmt\Namespace_($this->semStack[$this->stackPos-(5-2)], $this->semStack[$this->stackPos-(5-4)], $this->startAttributeStack[$this->stackPos-(5-1)] + $this->endAttributes); + $this->semValue->setAttribute('kind', Stmt\Namespace_::KIND_BRACED); + $this->checkNamespace($this->semValue); + } + + protected function reduceRule97() { + $this->semValue = new Stmt\Namespace_(null, $this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); + $this->semValue->setAttribute('kind', Stmt\Namespace_::KIND_BRACED); + $this->checkNamespace($this->semValue); + } + + protected function reduceRule98() { + $this->semValue = new Stmt\Use_($this->semStack[$this->stackPos-(3-2)], Stmt\Use_::TYPE_NORMAL, $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule99() { + $this->semValue = new Stmt\Use_($this->semStack[$this->stackPos-(4-3)], $this->semStack[$this->stackPos-(4-2)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); + } + + protected function reduceRule100() { + $this->semValue = $this->semStack[$this->stackPos-(2-1)]; + } + + protected function reduceRule101() { + $this->semValue = new Stmt\Const_($this->semStack[$this->stackPos-(3-2)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule102() { + $this->semValue = Stmt\Use_::TYPE_FUNCTION; + } + + protected function reduceRule103() { + $this->semValue = Stmt\Use_::TYPE_CONSTANT; + } + + protected function reduceRule104() { + $this->semValue = new Stmt\GroupUse(new Name($this->semStack[$this->stackPos-(7-3)], $this->startAttributeStack[$this->stackPos-(7-3)] + $this->endAttributeStack[$this->stackPos-(7-3)]), $this->semStack[$this->stackPos-(7-6)], $this->semStack[$this->stackPos-(7-2)], $this->startAttributeStack[$this->stackPos-(7-1)] + $this->endAttributes); + } + + protected function reduceRule105() { + $this->semValue = new Stmt\GroupUse(new Name($this->semStack[$this->stackPos-(8-4)], $this->startAttributeStack[$this->stackPos-(8-4)] + $this->endAttributeStack[$this->stackPos-(8-4)]), $this->semStack[$this->stackPos-(8-7)], $this->semStack[$this->stackPos-(8-2)], $this->startAttributeStack[$this->stackPos-(8-1)] + $this->endAttributes); + } + + protected function reduceRule106() { + $this->semValue = new Stmt\GroupUse(new Name($this->semStack[$this->stackPos-(6-2)], $this->startAttributeStack[$this->stackPos-(6-2)] + $this->endAttributeStack[$this->stackPos-(6-2)]), $this->semStack[$this->stackPos-(6-5)], Stmt\Use_::TYPE_UNKNOWN, $this->startAttributeStack[$this->stackPos-(6-1)] + $this->endAttributes); + } + + protected function reduceRule107() { + $this->semValue = new Stmt\GroupUse(new Name($this->semStack[$this->stackPos-(7-3)], $this->startAttributeStack[$this->stackPos-(7-3)] + $this->endAttributeStack[$this->stackPos-(7-3)]), $this->semStack[$this->stackPos-(7-6)], Stmt\Use_::TYPE_UNKNOWN, $this->startAttributeStack[$this->stackPos-(7-1)] + $this->endAttributes); + } + + protected function reduceRule108() { + $this->semValue = $this->semStack[$this->stackPos-(2-1)]; + } + + protected function reduceRule109() { + $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; + } + + protected function reduceRule110() { + $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); + } + + protected function reduceRule111() { + $this->semValue = $this->semStack[$this->stackPos-(2-1)]; + } + + protected function reduceRule112() { + $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; + } + + protected function reduceRule113() { + $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); + } + + protected function reduceRule114() { + $this->semValue = $this->semStack[$this->stackPos-(2-1)]; + } + + protected function reduceRule115() { + $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; + } + + protected function reduceRule116() { + $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); + } + + protected function reduceRule117() { + $this->semValue = new Stmt\UseUse($this->semStack[$this->stackPos-(1-1)], null, Stmt\Use_::TYPE_UNKNOWN, $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); $this->checkUseUse($this->semValue, $this->stackPos-(1-1)); + } + + protected function reduceRule118() { + $this->semValue = new Stmt\UseUse($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], Stmt\Use_::TYPE_UNKNOWN, $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); $this->checkUseUse($this->semValue, $this->stackPos-(3-3)); + } + + protected function reduceRule119() { + $this->semValue = $this->semStack[$this->stackPos-(1-1)]; + } + + protected function reduceRule120() { + $this->semValue = $this->semStack[$this->stackPos-(2-2)]; + } + + protected function reduceRule121() { + $this->semValue = $this->semStack[$this->stackPos-(1-1)]; $this->semValue->type = Stmt\Use_::TYPE_NORMAL; + } + + protected function reduceRule122() { + $this->semValue = $this->semStack[$this->stackPos-(2-2)]; $this->semValue->type = $this->semStack[$this->stackPos-(2-1)]; + } + + protected function reduceRule123() { + $this->semValue = $this->semStack[$this->stackPos-(2-1)]; + } + + protected function reduceRule124() { + $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; + } + + protected function reduceRule125() { + $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); + } + + protected function reduceRule126() { + $this->semValue = new Node\Const_($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule127() { + $this->semValue = $this->semStack[$this->stackPos-(2-1)]; + } + + protected function reduceRule128() { + $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; + } + + protected function reduceRule129() { + $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); + } + + protected function reduceRule130() { + $this->semValue = new Node\Const_($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule131() { + if (is_array($this->semStack[$this->stackPos-(2-2)])) { $this->semValue = array_merge($this->semStack[$this->stackPos-(2-1)], $this->semStack[$this->stackPos-(2-2)]); } else { $this->semStack[$this->stackPos-(2-1)][] = $this->semStack[$this->stackPos-(2-2)]; $this->semValue = $this->semStack[$this->stackPos-(2-1)]; }; + } + + protected function reduceRule132() { + $this->semValue = array(); + } + + protected function reduceRule133() { + $startAttributes = $this->lookaheadStartAttributes; if (isset($startAttributes['comments'])) { $nop = new Stmt\Nop(['comments' => $startAttributes['comments']]); } else { $nop = null; }; + if ($nop !== null) { $this->semStack[$this->stackPos-(1-1)][] = $nop; } $this->semValue = $this->semStack[$this->stackPos-(1-1)]; + } + + protected function reduceRule134() { + $this->semValue = $this->semStack[$this->stackPos-(1-1)]; + } + + protected function reduceRule135() { + $this->semValue = $this->semStack[$this->stackPos-(1-1)]; + } + + protected function reduceRule136() { + $this->semValue = $this->semStack[$this->stackPos-(1-1)]; + } + + protected function reduceRule137() { + throw new Error('__HALT_COMPILER() can only be used from the outermost scope', $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); + } + + protected function reduceRule138() { + + if ($this->semStack[$this->stackPos-(3-2)]) { + $this->semValue = $this->semStack[$this->stackPos-(3-2)]; $attrs = $this->startAttributeStack[$this->stackPos-(3-1)]; $stmts = $this->semValue; if (!empty($attrs['comments'])) {$stmts[0]->setAttribute('comments', array_merge($attrs['comments'], $stmts[0]->getAttribute('comments', []))); }; + } else { + $startAttributes = $this->startAttributeStack[$this->stackPos-(3-1)]; if (isset($startAttributes['comments'])) { $this->semValue = new Stmt\Nop(['comments' => $startAttributes['comments']]); } else { $this->semValue = null; }; + if (null === $this->semValue) { $this->semValue = array(); } + } + + } + + protected function reduceRule139() { + $this->semValue = new Stmt\If_($this->semStack[$this->stackPos-(7-3)], ['stmts' => is_array($this->semStack[$this->stackPos-(7-5)]) ? $this->semStack[$this->stackPos-(7-5)] : array($this->semStack[$this->stackPos-(7-5)]), 'elseifs' => $this->semStack[$this->stackPos-(7-6)], 'else' => $this->semStack[$this->stackPos-(7-7)]], $this->startAttributeStack[$this->stackPos-(7-1)] + $this->endAttributes); + } + + protected function reduceRule140() { + $this->semValue = new Stmt\If_($this->semStack[$this->stackPos-(10-3)], ['stmts' => $this->semStack[$this->stackPos-(10-6)], 'elseifs' => $this->semStack[$this->stackPos-(10-7)], 'else' => $this->semStack[$this->stackPos-(10-8)]], $this->startAttributeStack[$this->stackPos-(10-1)] + $this->endAttributes); + } + + protected function reduceRule141() { + $this->semValue = new Stmt\While_($this->semStack[$this->stackPos-(5-3)], $this->semStack[$this->stackPos-(5-5)], $this->startAttributeStack[$this->stackPos-(5-1)] + $this->endAttributes); + } + + protected function reduceRule142() { + $this->semValue = new Stmt\Do_($this->semStack[$this->stackPos-(7-5)], is_array($this->semStack[$this->stackPos-(7-2)]) ? $this->semStack[$this->stackPos-(7-2)] : array($this->semStack[$this->stackPos-(7-2)]), $this->startAttributeStack[$this->stackPos-(7-1)] + $this->endAttributes); + } + + protected function reduceRule143() { + $this->semValue = new Stmt\For_(['init' => $this->semStack[$this->stackPos-(9-3)], 'cond' => $this->semStack[$this->stackPos-(9-5)], 'loop' => $this->semStack[$this->stackPos-(9-7)], 'stmts' => $this->semStack[$this->stackPos-(9-9)]], $this->startAttributeStack[$this->stackPos-(9-1)] + $this->endAttributes); + } + + protected function reduceRule144() { + $this->semValue = new Stmt\Switch_($this->semStack[$this->stackPos-(5-3)], $this->semStack[$this->stackPos-(5-5)], $this->startAttributeStack[$this->stackPos-(5-1)] + $this->endAttributes); + } + + protected function reduceRule145() { + $this->semValue = new Stmt\Break_($this->semStack[$this->stackPos-(3-2)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule146() { + $this->semValue = new Stmt\Continue_($this->semStack[$this->stackPos-(3-2)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule147() { + $this->semValue = new Stmt\Return_($this->semStack[$this->stackPos-(3-2)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule148() { + $this->semValue = new Stmt\Global_($this->semStack[$this->stackPos-(3-2)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule149() { + $this->semValue = new Stmt\Static_($this->semStack[$this->stackPos-(3-2)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule150() { + $this->semValue = new Stmt\Echo_($this->semStack[$this->stackPos-(3-2)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule151() { + $this->semValue = new Stmt\InlineHTML($this->semStack[$this->stackPos-(1-1)], $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); + } + + protected function reduceRule152() { + $this->semValue = $this->semStack[$this->stackPos-(2-1)]; + } + + protected function reduceRule153() { + $this->semValue = new Stmt\Unset_($this->semStack[$this->stackPos-(5-3)], $this->startAttributeStack[$this->stackPos-(5-1)] + $this->endAttributes); + } + + protected function reduceRule154() { + $this->semValue = new Stmt\Foreach_($this->semStack[$this->stackPos-(7-3)], $this->semStack[$this->stackPos-(7-5)][0], ['keyVar' => null, 'byRef' => $this->semStack[$this->stackPos-(7-5)][1], 'stmts' => $this->semStack[$this->stackPos-(7-7)]], $this->startAttributeStack[$this->stackPos-(7-1)] + $this->endAttributes); + } + + protected function reduceRule155() { + $this->semValue = new Stmt\Foreach_($this->semStack[$this->stackPos-(9-3)], $this->semStack[$this->stackPos-(9-7)][0], ['keyVar' => $this->semStack[$this->stackPos-(9-5)], 'byRef' => $this->semStack[$this->stackPos-(9-7)][1], 'stmts' => $this->semStack[$this->stackPos-(9-9)]], $this->startAttributeStack[$this->stackPos-(9-1)] + $this->endAttributes); + } + + protected function reduceRule156() { + $this->semValue = new Stmt\Declare_($this->semStack[$this->stackPos-(5-3)], $this->semStack[$this->stackPos-(5-5)], $this->startAttributeStack[$this->stackPos-(5-1)] + $this->endAttributes); + } + + protected function reduceRule157() { + $this->semValue = new Stmt\TryCatch($this->semStack[$this->stackPos-(6-3)], $this->semStack[$this->stackPos-(6-5)], $this->semStack[$this->stackPos-(6-6)], $this->startAttributeStack[$this->stackPos-(6-1)] + $this->endAttributes); $this->checkTryCatch($this->semValue); + } + + protected function reduceRule158() { + $this->semValue = new Stmt\Throw_($this->semStack[$this->stackPos-(3-2)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule159() { + $this->semValue = new Stmt\Goto_($this->semStack[$this->stackPos-(3-2)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule160() { + $this->semValue = new Stmt\Label($this->semStack[$this->stackPos-(2-1)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); + } + + protected function reduceRule161() { + $this->semValue = array(); /* means: no statement */ + } + + protected function reduceRule162() { + $this->semValue = $this->semStack[$this->stackPos-(1-1)]; + } + + protected function reduceRule163() { + $startAttributes = $this->startAttributeStack[$this->stackPos-(1-1)]; if (isset($startAttributes['comments'])) { $this->semValue = new Stmt\Nop(['comments' => $startAttributes['comments']]); } else { $this->semValue = null; }; + if ($this->semValue === null) $this->semValue = array(); /* means: no statement */ + } + + protected function reduceRule164() { + $this->semValue = array(); + } + + protected function reduceRule165() { + $this->semStack[$this->stackPos-(2-1)][] = $this->semStack[$this->stackPos-(2-2)]; $this->semValue = $this->semStack[$this->stackPos-(2-1)]; + } + + protected function reduceRule166() { + $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); + } + + protected function reduceRule167() { + $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; + } + + protected function reduceRule168() { + $this->semValue = new Stmt\Catch_($this->semStack[$this->stackPos-(8-3)], substr($this->semStack[$this->stackPos-(8-4)], 1), $this->semStack[$this->stackPos-(8-7)], $this->startAttributeStack[$this->stackPos-(8-1)] + $this->endAttributes); + } + + protected function reduceRule169() { + $this->semValue = null; + } + + protected function reduceRule170() { + $this->semValue = new Stmt\Finally_($this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); + } + + protected function reduceRule171() { + $this->semValue = $this->semStack[$this->stackPos-(2-1)]; + } + + protected function reduceRule172() { + $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); + } + + protected function reduceRule173() { + $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; + } + + protected function reduceRule174() { + $this->semValue = false; + } + + protected function reduceRule175() { + $this->semValue = true; + } + + protected function reduceRule176() { + $this->semValue = false; + } + + protected function reduceRule177() { + $this->semValue = true; + } + + protected function reduceRule178() { + $this->semValue = new Stmt\Function_($this->semStack[$this->stackPos-(10-3)], ['byRef' => $this->semStack[$this->stackPos-(10-2)], 'params' => $this->semStack[$this->stackPos-(10-5)], 'returnType' => $this->semStack[$this->stackPos-(10-7)], 'stmts' => $this->semStack[$this->stackPos-(10-9)]], $this->startAttributeStack[$this->stackPos-(10-1)] + $this->endAttributes); + } + + protected function reduceRule179() { + $this->semValue = new Stmt\Class_($this->semStack[$this->stackPos-(7-2)], ['type' => $this->semStack[$this->stackPos-(7-1)], 'extends' => $this->semStack[$this->stackPos-(7-3)], 'implements' => $this->semStack[$this->stackPos-(7-4)], 'stmts' => $this->semStack[$this->stackPos-(7-6)]], $this->startAttributeStack[$this->stackPos-(7-1)] + $this->endAttributes); + $this->checkClass($this->semValue, $this->stackPos-(7-2)); + } + + protected function reduceRule180() { + $this->semValue = new Stmt\Interface_($this->semStack[$this->stackPos-(6-2)], ['extends' => $this->semStack[$this->stackPos-(6-3)], 'stmts' => $this->semStack[$this->stackPos-(6-5)]], $this->startAttributeStack[$this->stackPos-(6-1)] + $this->endAttributes); + $this->checkInterface($this->semValue, $this->stackPos-(6-2)); + } + + protected function reduceRule181() { + $this->semValue = new Stmt\Trait_($this->semStack[$this->stackPos-(5-2)], ['stmts' => $this->semStack[$this->stackPos-(5-4)]], $this->startAttributeStack[$this->stackPos-(5-1)] + $this->endAttributes); + } + + protected function reduceRule182() { + $this->semValue = 0; + } + + protected function reduceRule183() { + $this->semValue = Stmt\Class_::MODIFIER_ABSTRACT; + } + + protected function reduceRule184() { + $this->semValue = Stmt\Class_::MODIFIER_FINAL; + } + + protected function reduceRule185() { + $this->semValue = null; + } + + protected function reduceRule186() { + $this->semValue = $this->semStack[$this->stackPos-(2-2)]; + } + + protected function reduceRule187() { + $this->semValue = array(); + } + + protected function reduceRule188() { + $this->semValue = $this->semStack[$this->stackPos-(2-2)]; + } + + protected function reduceRule189() { + $this->semValue = array(); + } + + protected function reduceRule190() { + $this->semValue = $this->semStack[$this->stackPos-(2-2)]; + } + + protected function reduceRule191() { + $this->semValue = $this->semStack[$this->stackPos-(2-1)]; + } + + protected function reduceRule192() { + $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); + } + + protected function reduceRule193() { + $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; + } + + protected function reduceRule194() { + $this->semValue = is_array($this->semStack[$this->stackPos-(1-1)]) ? $this->semStack[$this->stackPos-(1-1)] : array($this->semStack[$this->stackPos-(1-1)]); + } + + protected function reduceRule195() { + $this->semValue = $this->semStack[$this->stackPos-(4-2)]; + } + + protected function reduceRule196() { + $this->semValue = is_array($this->semStack[$this->stackPos-(1-1)]) ? $this->semStack[$this->stackPos-(1-1)] : array($this->semStack[$this->stackPos-(1-1)]); + } + + protected function reduceRule197() { + $this->semValue = $this->semStack[$this->stackPos-(4-2)]; + } + + protected function reduceRule198() { + $this->semValue = is_array($this->semStack[$this->stackPos-(1-1)]) ? $this->semStack[$this->stackPos-(1-1)] : array($this->semStack[$this->stackPos-(1-1)]); + } + + protected function reduceRule199() { + $this->semValue = null; + } + + protected function reduceRule200() { + $this->semValue = $this->semStack[$this->stackPos-(4-2)]; + } + + protected function reduceRule201() { + $this->semValue = $this->semStack[$this->stackPos-(2-1)]; + } + + protected function reduceRule202() { + $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); + } + + protected function reduceRule203() { + $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; + } + + protected function reduceRule204() { + $this->semValue = new Stmt\DeclareDeclare($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule205() { + $this->semValue = $this->semStack[$this->stackPos-(3-2)]; + } + + protected function reduceRule206() { + $this->semValue = $this->semStack[$this->stackPos-(4-3)]; + } + + protected function reduceRule207() { + $this->semValue = $this->semStack[$this->stackPos-(4-2)]; + } + + protected function reduceRule208() { + $this->semValue = $this->semStack[$this->stackPos-(5-3)]; + } + + protected function reduceRule209() { + $this->semValue = array(); + } + + protected function reduceRule210() { + $this->semStack[$this->stackPos-(2-1)][] = $this->semStack[$this->stackPos-(2-2)]; $this->semValue = $this->semStack[$this->stackPos-(2-1)]; + } + + protected function reduceRule211() { + $this->semValue = new Stmt\Case_($this->semStack[$this->stackPos-(4-2)], $this->semStack[$this->stackPos-(4-4)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); + } + + protected function reduceRule212() { + $this->semValue = new Stmt\Case_(null, $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule213() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule214() { + $this->semValue = $this->semStack[$this->stackPos]; + } + + protected function reduceRule215() { + $this->semValue = is_array($this->semStack[$this->stackPos-(1-1)]) ? $this->semStack[$this->stackPos-(1-1)] : array($this->semStack[$this->stackPos-(1-1)]); + } + + protected function reduceRule216() { + $this->semValue = $this->semStack[$this->stackPos-(4-2)]; + } + + protected function reduceRule217() { + $this->semValue = array(); + } + + protected function reduceRule218() { + $this->semStack[$this->stackPos-(2-1)][] = $this->semStack[$this->stackPos-(2-2)]; $this->semValue = $this->semStack[$this->stackPos-(2-1)]; + } + + protected function reduceRule219() { + $this->semValue = new Stmt\ElseIf_($this->semStack[$this->stackPos-(5-3)], is_array($this->semStack[$this->stackPos-(5-5)]) ? $this->semStack[$this->stackPos-(5-5)] : array($this->semStack[$this->stackPos-(5-5)]), $this->startAttributeStack[$this->stackPos-(5-1)] + $this->endAttributes); + } + + protected function reduceRule220() { + $this->semValue = array(); + } + + protected function reduceRule221() { + $this->semStack[$this->stackPos-(2-1)][] = $this->semStack[$this->stackPos-(2-2)]; $this->semValue = $this->semStack[$this->stackPos-(2-1)]; + } + + protected function reduceRule222() { + $this->semValue = new Stmt\ElseIf_($this->semStack[$this->stackPos-(6-3)], $this->semStack[$this->stackPos-(6-6)], $this->startAttributeStack[$this->stackPos-(6-1)] + $this->endAttributes); + } + + protected function reduceRule223() { + $this->semValue = null; + } + + protected function reduceRule224() { + $this->semValue = new Stmt\Else_(is_array($this->semStack[$this->stackPos-(2-2)]) ? $this->semStack[$this->stackPos-(2-2)] : array($this->semStack[$this->stackPos-(2-2)]), $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); + } + + protected function reduceRule225() { + $this->semValue = null; + } + + protected function reduceRule226() { + $this->semValue = new Stmt\Else_($this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule227() { + $this->semValue = array($this->semStack[$this->stackPos-(1-1)], false); + } + + protected function reduceRule228() { + $this->semValue = array($this->semStack[$this->stackPos-(2-2)], true); + } + + protected function reduceRule229() { + $this->semValue = array($this->semStack[$this->stackPos-(1-1)], false); + } + + protected function reduceRule230() { + $this->semValue = array($this->semStack[$this->stackPos-(1-1)], false); + } + + protected function reduceRule231() { + $this->semValue = $this->semStack[$this->stackPos-(2-1)]; + } + + protected function reduceRule232() { + $this->semValue = array(); + } + + protected function reduceRule233() { + $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); + } + + protected function reduceRule234() { + $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; + } + + protected function reduceRule235() { + $this->semValue = new Node\Param(substr($this->semStack[$this->stackPos-(4-4)], 1), null, $this->semStack[$this->stackPos-(4-1)], $this->semStack[$this->stackPos-(4-2)], $this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); $this->checkParam($this->semValue); + } + + protected function reduceRule236() { + $this->semValue = new Node\Param(substr($this->semStack[$this->stackPos-(6-4)], 1), $this->semStack[$this->stackPos-(6-6)], $this->semStack[$this->stackPos-(6-1)], $this->semStack[$this->stackPos-(6-2)], $this->semStack[$this->stackPos-(6-3)], $this->startAttributeStack[$this->stackPos-(6-1)] + $this->endAttributes); $this->checkParam($this->semValue); + } + + protected function reduceRule237() { + $this->semValue = $this->semStack[$this->stackPos-(1-1)]; + } + + protected function reduceRule238() { + $this->semValue = new Node\NullableType($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); + } + + protected function reduceRule239() { + $this->semValue = $this->handleBuiltinTypes($this->semStack[$this->stackPos-(1-1)]); + } + + protected function reduceRule240() { + $this->semValue = 'array'; + } + + protected function reduceRule241() { + $this->semValue = 'callable'; + } + + protected function reduceRule242() { + $this->semValue = null; + } + + protected function reduceRule243() { + $this->semValue = $this->semStack[$this->stackPos-(1-1)]; + } + + protected function reduceRule244() { + $this->semValue = null; + } + + protected function reduceRule245() { + $this->semValue = $this->semStack[$this->stackPos-(2-2)]; + } + + protected function reduceRule246() { + $this->semValue = array(); + } + + protected function reduceRule247() { + $this->semValue = $this->semStack[$this->stackPos-(4-2)]; + } + + protected function reduceRule248() { + $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); + } + + protected function reduceRule249() { + $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; + } + + protected function reduceRule250() { + $this->semValue = new Node\Arg($this->semStack[$this->stackPos-(1-1)], false, false, $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); + } + + protected function reduceRule251() { + $this->semValue = new Node\Arg($this->semStack[$this->stackPos-(2-2)], true, false, $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); + } + + protected function reduceRule252() { + $this->semValue = new Node\Arg($this->semStack[$this->stackPos-(2-2)], false, true, $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); + } + + protected function reduceRule253() { + $this->semValue = $this->semStack[$this->stackPos-(2-1)]; + } + + protected function reduceRule254() { + $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; + } + + protected function reduceRule255() { + $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); + } + + protected function reduceRule256() { + $this->semValue = new Expr\Variable($this->semStack[$this->stackPos-(1-1)], $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); + } + + protected function reduceRule257() { + $this->semValue = $this->semStack[$this->stackPos-(2-1)]; + } + + protected function reduceRule258() { + $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; + } + + protected function reduceRule259() { + $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); + } + + protected function reduceRule260() { + $this->semValue = new Stmt\StaticVar(substr($this->semStack[$this->stackPos-(1-1)], 1), null, $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); + } + + protected function reduceRule261() { + $this->semValue = new Stmt\StaticVar(substr($this->semStack[$this->stackPos-(3-1)], 1), $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule262() { + $this->semStack[$this->stackPos-(2-1)][] = $this->semStack[$this->stackPos-(2-2)]; $this->semValue = $this->semStack[$this->stackPos-(2-1)]; + } + + protected function reduceRule263() { + $this->semValue = array(); + } + + protected function reduceRule264() { + $this->semValue = new Stmt\Property($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-2)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); $this->checkProperty($this->semValue, $this->stackPos-(3-1)); + } + + protected function reduceRule265() { + $this->semValue = new Stmt\ClassConst($this->semStack[$this->stackPos-(4-3)], $this->semStack[$this->stackPos-(4-1)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); $this->checkClassConst($this->semValue, $this->stackPos-(4-1)); + } + + protected function reduceRule266() { + $this->semValue = new Stmt\ClassMethod($this->semStack[$this->stackPos-(9-4)], ['type' => $this->semStack[$this->stackPos-(9-1)], 'byRef' => $this->semStack[$this->stackPos-(9-3)], 'params' => $this->semStack[$this->stackPos-(9-6)], 'returnType' => $this->semStack[$this->stackPos-(9-8)], 'stmts' => $this->semStack[$this->stackPos-(9-9)]], $this->startAttributeStack[$this->stackPos-(9-1)] + $this->endAttributes); + $this->checkClassMethod($this->semValue, $this->stackPos-(9-1)); + } + + protected function reduceRule267() { + $this->semValue = new Stmt\TraitUse($this->semStack[$this->stackPos-(3-2)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule268() { + $this->semValue = array(); + } + + protected function reduceRule269() { + $this->semValue = $this->semStack[$this->stackPos-(3-2)]; + } + + protected function reduceRule270() { + $this->semValue = array(); + } + + protected function reduceRule271() { + $this->semStack[$this->stackPos-(2-1)][] = $this->semStack[$this->stackPos-(2-2)]; $this->semValue = $this->semStack[$this->stackPos-(2-1)]; + } + + protected function reduceRule272() { + $this->semValue = new Stmt\TraitUseAdaptation\Precedence($this->semStack[$this->stackPos-(4-1)][0], $this->semStack[$this->stackPos-(4-1)][1], $this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); + } + + protected function reduceRule273() { + $this->semValue = new Stmt\TraitUseAdaptation\Alias($this->semStack[$this->stackPos-(5-1)][0], $this->semStack[$this->stackPos-(5-1)][1], $this->semStack[$this->stackPos-(5-3)], $this->semStack[$this->stackPos-(5-4)], $this->startAttributeStack[$this->stackPos-(5-1)] + $this->endAttributes); + } + + protected function reduceRule274() { + $this->semValue = new Stmt\TraitUseAdaptation\Alias($this->semStack[$this->stackPos-(4-1)][0], $this->semStack[$this->stackPos-(4-1)][1], $this->semStack[$this->stackPos-(4-3)], null, $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); + } + + protected function reduceRule275() { + $this->semValue = new Stmt\TraitUseAdaptation\Alias($this->semStack[$this->stackPos-(4-1)][0], $this->semStack[$this->stackPos-(4-1)][1], null, $this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); + } + + protected function reduceRule276() { + $this->semValue = new Stmt\TraitUseAdaptation\Alias($this->semStack[$this->stackPos-(4-1)][0], $this->semStack[$this->stackPos-(4-1)][1], null, $this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); + } + + protected function reduceRule277() { + $this->semValue = array($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)]); + } + + protected function reduceRule278() { + $this->semValue = $this->semStack[$this->stackPos-(1-1)]; + } + + protected function reduceRule279() { + $this->semValue = array(null, $this->semStack[$this->stackPos-(1-1)]); + } + + protected function reduceRule280() { + $this->semValue = null; + } + + protected function reduceRule281() { + $this->semValue = $this->semStack[$this->stackPos-(3-2)]; + } + + protected function reduceRule282() { + $this->semValue = $this->semStack[$this->stackPos-(1-1)]; + } + + protected function reduceRule283() { + $this->semValue = 0; + } + + protected function reduceRule284() { + $this->semValue = 0; + } + + protected function reduceRule285() { + $this->semValue = $this->semStack[$this->stackPos-(1-1)]; + } + + protected function reduceRule286() { + $this->semValue = $this->semStack[$this->stackPos-(1-1)]; + } + + protected function reduceRule287() { + $this->checkModifier($this->semStack[$this->stackPos-(2-1)], $this->semStack[$this->stackPos-(2-2)], $this->stackPos-(2-2)); $this->semValue = $this->semStack[$this->stackPos-(2-1)] | $this->semStack[$this->stackPos-(2-2)]; + } + + protected function reduceRule288() { + $this->semValue = Stmt\Class_::MODIFIER_PUBLIC; + } + + protected function reduceRule289() { + $this->semValue = Stmt\Class_::MODIFIER_PROTECTED; + } + + protected function reduceRule290() { + $this->semValue = Stmt\Class_::MODIFIER_PRIVATE; + } + + protected function reduceRule291() { + $this->semValue = Stmt\Class_::MODIFIER_STATIC; + } + + protected function reduceRule292() { + $this->semValue = Stmt\Class_::MODIFIER_ABSTRACT; + } + + protected function reduceRule293() { + $this->semValue = Stmt\Class_::MODIFIER_FINAL; + } + + protected function reduceRule294() { + $this->semValue = $this->semStack[$this->stackPos-(2-1)]; + } + + protected function reduceRule295() { + $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); + } + + protected function reduceRule296() { + $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; + } + + protected function reduceRule297() { + $this->semValue = new Stmt\PropertyProperty(substr($this->semStack[$this->stackPos-(1-1)], 1), null, $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); + } + + protected function reduceRule298() { + $this->semValue = new Stmt\PropertyProperty(substr($this->semStack[$this->stackPos-(3-1)], 1), $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule299() { + $this->semValue = $this->semStack[$this->stackPos-(2-1)]; + } + + protected function reduceRule300() { + $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; + } + + protected function reduceRule301() { + $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); + } + + protected function reduceRule302() { + $this->semValue = array(); + } + + protected function reduceRule303() { + $this->semValue = $this->semStack[$this->stackPos-(1-1)]; + } + + protected function reduceRule304() { + $this->semValue = $this->semStack[$this->stackPos-(1-1)]; + } + + protected function reduceRule305() { + $this->semValue = new Expr\Assign($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule306() { + $this->semValue = new Expr\Assign($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule307() { + $this->semValue = new Expr\Assign($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule308() { + $this->semValue = new Expr\AssignRef($this->semStack[$this->stackPos-(4-1)], $this->semStack[$this->stackPos-(4-4)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); + } + + protected function reduceRule309() { + $this->semValue = $this->semStack[$this->stackPos-(1-1)]; + } + + protected function reduceRule310() { + $this->semValue = new Expr\Clone_($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); + } + + protected function reduceRule311() { + $this->semValue = new Expr\AssignOp\Plus($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule312() { + $this->semValue = new Expr\AssignOp\Minus($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule313() { + $this->semValue = new Expr\AssignOp\Mul($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule314() { + $this->semValue = new Expr\AssignOp\Div($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule315() { + $this->semValue = new Expr\AssignOp\Concat($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule316() { + $this->semValue = new Expr\AssignOp\Mod($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule317() { + $this->semValue = new Expr\AssignOp\BitwiseAnd($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule318() { + $this->semValue = new Expr\AssignOp\BitwiseOr($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule319() { + $this->semValue = new Expr\AssignOp\BitwiseXor($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule320() { + $this->semValue = new Expr\AssignOp\ShiftLeft($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule321() { + $this->semValue = new Expr\AssignOp\ShiftRight($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule322() { + $this->semValue = new Expr\AssignOp\Pow($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule323() { + $this->semValue = new Expr\PostInc($this->semStack[$this->stackPos-(2-1)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); + } + + protected function reduceRule324() { + $this->semValue = new Expr\PreInc($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); + } + + protected function reduceRule325() { + $this->semValue = new Expr\PostDec($this->semStack[$this->stackPos-(2-1)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); + } + + protected function reduceRule326() { + $this->semValue = new Expr\PreDec($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); + } + + protected function reduceRule327() { + $this->semValue = new Expr\BinaryOp\BooleanOr($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule328() { + $this->semValue = new Expr\BinaryOp\BooleanAnd($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule329() { + $this->semValue = new Expr\BinaryOp\LogicalOr($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule330() { + $this->semValue = new Expr\BinaryOp\LogicalAnd($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule331() { + $this->semValue = new Expr\BinaryOp\LogicalXor($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule332() { + $this->semValue = new Expr\BinaryOp\BitwiseOr($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule333() { + $this->semValue = new Expr\BinaryOp\BitwiseAnd($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule334() { + $this->semValue = new Expr\BinaryOp\BitwiseXor($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule335() { + $this->semValue = new Expr\BinaryOp\Concat($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule336() { + $this->semValue = new Expr\BinaryOp\Plus($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule337() { + $this->semValue = new Expr\BinaryOp\Minus($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule338() { + $this->semValue = new Expr\BinaryOp\Mul($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule339() { + $this->semValue = new Expr\BinaryOp\Div($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule340() { + $this->semValue = new Expr\BinaryOp\Mod($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule341() { + $this->semValue = new Expr\BinaryOp\ShiftLeft($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule342() { + $this->semValue = new Expr\BinaryOp\ShiftRight($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule343() { + $this->semValue = new Expr\BinaryOp\Pow($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule344() { + $this->semValue = new Expr\UnaryPlus($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); + } + + protected function reduceRule345() { + $this->semValue = new Expr\UnaryMinus($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); + } + + protected function reduceRule346() { + $this->semValue = new Expr\BooleanNot($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); + } + + protected function reduceRule347() { + $this->semValue = new Expr\BitwiseNot($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); + } + + protected function reduceRule348() { + $this->semValue = new Expr\BinaryOp\Identical($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule349() { + $this->semValue = new Expr\BinaryOp\NotIdentical($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule350() { + $this->semValue = new Expr\BinaryOp\Equal($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule351() { + $this->semValue = new Expr\BinaryOp\NotEqual($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule352() { + $this->semValue = new Expr\BinaryOp\Spaceship($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule353() { + $this->semValue = new Expr\BinaryOp\Smaller($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule354() { + $this->semValue = new Expr\BinaryOp\SmallerOrEqual($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule355() { + $this->semValue = new Expr\BinaryOp\Greater($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule356() { + $this->semValue = new Expr\BinaryOp\GreaterOrEqual($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule357() { + $this->semValue = new Expr\Instanceof_($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule358() { + $this->semValue = $this->semStack[$this->stackPos-(3-2)]; + } + + protected function reduceRule359() { + $this->semValue = new Expr\Ternary($this->semStack[$this->stackPos-(5-1)], $this->semStack[$this->stackPos-(5-3)], $this->semStack[$this->stackPos-(5-5)], $this->startAttributeStack[$this->stackPos-(5-1)] + $this->endAttributes); + } + + protected function reduceRule360() { + $this->semValue = new Expr\Ternary($this->semStack[$this->stackPos-(4-1)], null, $this->semStack[$this->stackPos-(4-4)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); + } + + protected function reduceRule361() { + $this->semValue = new Expr\BinaryOp\Coalesce($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule362() { + $this->semValue = new Expr\Isset_($this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); + } + + protected function reduceRule363() { + $this->semValue = new Expr\Empty_($this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); + } + + protected function reduceRule364() { + $this->semValue = new Expr\Include_($this->semStack[$this->stackPos-(2-2)], Expr\Include_::TYPE_INCLUDE, $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); + } + + protected function reduceRule365() { + $this->semValue = new Expr\Include_($this->semStack[$this->stackPos-(2-2)], Expr\Include_::TYPE_INCLUDE_ONCE, $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); + } + + protected function reduceRule366() { + $this->semValue = new Expr\Eval_($this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); + } + + protected function reduceRule367() { + $this->semValue = new Expr\Include_($this->semStack[$this->stackPos-(2-2)], Expr\Include_::TYPE_REQUIRE, $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); + } + + protected function reduceRule368() { + $this->semValue = new Expr\Include_($this->semStack[$this->stackPos-(2-2)], Expr\Include_::TYPE_REQUIRE_ONCE, $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); + } + + protected function reduceRule369() { + $this->semValue = new Expr\Cast\Int_($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); + } + + protected function reduceRule370() { + $this->semValue = new Expr\Cast\Double($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); + } + + protected function reduceRule371() { + $this->semValue = new Expr\Cast\String_($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); + } + + protected function reduceRule372() { + $this->semValue = new Expr\Cast\Array_($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); + } + + protected function reduceRule373() { + $this->semValue = new Expr\Cast\Object_($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); + } + + protected function reduceRule374() { + $this->semValue = new Expr\Cast\Bool_($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); + } + + protected function reduceRule375() { + $this->semValue = new Expr\Cast\Unset_($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); + } + + protected function reduceRule376() { + $attrs = $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes; + $attrs['kind'] = strtolower($this->semStack[$this->stackPos-(2-1)]) === 'exit' ? Expr\Exit_::KIND_EXIT : Expr\Exit_::KIND_DIE; + $this->semValue = new Expr\Exit_($this->semStack[$this->stackPos-(2-2)], $attrs); + } + + protected function reduceRule377() { + $this->semValue = new Expr\ErrorSuppress($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); + } + + protected function reduceRule378() { + $this->semValue = $this->semStack[$this->stackPos-(1-1)]; + } + + protected function reduceRule379() { + $this->semValue = new Expr\ShellExec($this->semStack[$this->stackPos-(3-2)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule380() { + $this->semValue = new Expr\Print_($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); + } + + protected function reduceRule381() { + $this->semValue = new Expr\Yield_(null, null, $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); + } + + protected function reduceRule382() { + $this->semValue = new Expr\Yield_($this->semStack[$this->stackPos-(2-2)], null, $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); + } + + protected function reduceRule383() { + $this->semValue = new Expr\Yield_($this->semStack[$this->stackPos-(4-4)], $this->semStack[$this->stackPos-(4-2)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); + } + + protected function reduceRule384() { + $this->semValue = new Expr\YieldFrom($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); + } + + protected function reduceRule385() { + $this->semValue = new Expr\Closure(['static' => false, 'byRef' => $this->semStack[$this->stackPos-(10-2)], 'params' => $this->semStack[$this->stackPos-(10-4)], 'uses' => $this->semStack[$this->stackPos-(10-6)], 'returnType' => $this->semStack[$this->stackPos-(10-7)], 'stmts' => $this->semStack[$this->stackPos-(10-9)]], $this->startAttributeStack[$this->stackPos-(10-1)] + $this->endAttributes); + } + + protected function reduceRule386() { + $this->semValue = new Expr\Closure(['static' => true, 'byRef' => $this->semStack[$this->stackPos-(11-3)], 'params' => $this->semStack[$this->stackPos-(11-5)], 'uses' => $this->semStack[$this->stackPos-(11-7)], 'returnType' => $this->semStack[$this->stackPos-(11-8)], 'stmts' => $this->semStack[$this->stackPos-(11-10)]], $this->startAttributeStack[$this->stackPos-(11-1)] + $this->endAttributes); + } + + protected function reduceRule387() { + $this->semValue = array(new Stmt\Class_(null, ['type' => 0, 'extends' => $this->semStack[$this->stackPos-(7-3)], 'implements' => $this->semStack[$this->stackPos-(7-4)], 'stmts' => $this->semStack[$this->stackPos-(7-6)]], $this->startAttributeStack[$this->stackPos-(7-1)] + $this->endAttributes), $this->semStack[$this->stackPos-(7-2)]); + $this->checkClass($this->semValue[0], -1); + } + + protected function reduceRule388() { + $this->semValue = new Expr\New_($this->semStack[$this->stackPos-(3-2)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule389() { + list($class, $ctorArgs) = $this->semStack[$this->stackPos-(2-2)]; $this->semValue = new Expr\New_($class, $ctorArgs, $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); + } + + protected function reduceRule390() { + $this->semValue = array(); + } + + protected function reduceRule391() { + $this->semValue = $this->semStack[$this->stackPos-(4-3)]; + } + + protected function reduceRule392() { + $this->semValue = $this->semStack[$this->stackPos-(2-1)]; + } + + protected function reduceRule393() { + $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); + } + + protected function reduceRule394() { + $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; + } + + protected function reduceRule395() { + $this->semValue = new Expr\ClosureUse(substr($this->semStack[$this->stackPos-(2-2)], 1), $this->semStack[$this->stackPos-(2-1)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); + } + + protected function reduceRule396() { + $this->semValue = new Expr\FuncCall($this->semStack[$this->stackPos-(2-1)], $this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); + } + + protected function reduceRule397() { + $this->semValue = new Expr\FuncCall($this->semStack[$this->stackPos-(2-1)], $this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); + } + + protected function reduceRule398() { + $this->semValue = new Expr\StaticCall($this->semStack[$this->stackPos-(4-1)], $this->semStack[$this->stackPos-(4-3)], $this->semStack[$this->stackPos-(4-4)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); + } + + protected function reduceRule399() { + $this->semValue = new Name($this->semStack[$this->stackPos-(1-1)], $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); + } + + protected function reduceRule400() { + $this->semValue = $this->semStack[$this->stackPos-(1-1)]; + } + + protected function reduceRule401() { + $this->semValue = new Name($this->semStack[$this->stackPos-(1-1)], $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); + } + + protected function reduceRule402() { + $this->semValue = new Name\FullyQualified($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); + } + + protected function reduceRule403() { + $this->semValue = new Name\Relative($this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule404() { + $this->semValue = $this->semStack[$this->stackPos-(1-1)]; + } + + protected function reduceRule405() { + $this->semValue = $this->semStack[$this->stackPos-(1-1)]; + } + + protected function reduceRule406() { + $this->semValue = new Expr\Error($this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); $this->errorState = 2; + } + + protected function reduceRule407() { + $this->semValue = $this->semStack[$this->stackPos-(1-1)]; + } + + protected function reduceRule408() { + $this->semValue = $this->semStack[$this->stackPos-(1-1)]; + } + + protected function reduceRule409() { + $this->semValue = null; + } + + protected function reduceRule410() { + $this->semValue = $this->semStack[$this->stackPos-(3-2)]; + } + + protected function reduceRule411() { + $this->semValue = array(); + } + + protected function reduceRule412() { + $this->semValue = array(new Scalar\EncapsedStringPart(Scalar\String_::parseEscapeSequences($this->semStack[$this->stackPos-(1-1)], '`'), $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes)); + } + + protected function reduceRule413() { + foreach ($this->semStack[$this->stackPos-(1-1)] as $s) { if ($s instanceof Node\Scalar\EncapsedStringPart) { $s->value = Node\Scalar\String_::parseEscapeSequences($s->value, '`', true); } }; $this->semValue = $this->semStack[$this->stackPos-(1-1)]; + } + + protected function reduceRule414() { + $this->semValue = array(); + } + + protected function reduceRule415() { + $this->semValue = $this->semStack[$this->stackPos-(1-1)]; + } + + protected function reduceRule416() { + $this->semValue = new Expr\ConstFetch($this->semStack[$this->stackPos-(1-1)], $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); + } + + protected function reduceRule417() { + $this->semValue = new Expr\ClassConstFetch($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule418() { + $this->semValue = new Expr\ClassConstFetch($this->semStack[$this->stackPos-(3-1)], new Expr\Error($this->startAttributeStack[$this->stackPos-(3-3)] + $this->endAttributeStack[$this->stackPos-(3-3)]), $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); $this->errorState = 2; + } + + protected function reduceRule419() { + $attrs = $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes; $attrs['kind'] = Expr\Array_::KIND_SHORT; + $this->semValue = new Expr\Array_($this->semStack[$this->stackPos-(3-2)], $attrs); + } + + protected function reduceRule420() { + $attrs = $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes; $attrs['kind'] = Expr\Array_::KIND_LONG; + $this->semValue = new Expr\Array_($this->semStack[$this->stackPos-(4-3)], $attrs); + } + + protected function reduceRule421() { + $this->semValue = $this->semStack[$this->stackPos-(1-1)]; + } + + protected function reduceRule422() { + $attrs = $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes; $attrs['kind'] = ($this->semStack[$this->stackPos-(1-1)][0] === "'" || ($this->semStack[$this->stackPos-(1-1)][1] === "'" && ($this->semStack[$this->stackPos-(1-1)][0] === 'b' || $this->semStack[$this->stackPos-(1-1)][0] === 'B')) ? Scalar\String_::KIND_SINGLE_QUOTED : Scalar\String_::KIND_DOUBLE_QUOTED); + $this->semValue = new Scalar\String_(Scalar\String_::parse($this->semStack[$this->stackPos-(1-1)]), $attrs); + } + + protected function reduceRule423() { + $this->semValue = $this->parseLNumber($this->semStack[$this->stackPos-(1-1)], $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); + } + + protected function reduceRule424() { + $this->semValue = new Scalar\DNumber(Scalar\DNumber::parse($this->semStack[$this->stackPos-(1-1)]), $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); + } + + protected function reduceRule425() { + $this->semValue = new Scalar\MagicConst\Line($this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); + } + + protected function reduceRule426() { + $this->semValue = new Scalar\MagicConst\File($this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); + } + + protected function reduceRule427() { + $this->semValue = new Scalar\MagicConst\Dir($this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); + } + + protected function reduceRule428() { + $this->semValue = new Scalar\MagicConst\Class_($this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); + } + + protected function reduceRule429() { + $this->semValue = new Scalar\MagicConst\Trait_($this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); + } + + protected function reduceRule430() { + $this->semValue = new Scalar\MagicConst\Method($this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); + } + + protected function reduceRule431() { + $this->semValue = new Scalar\MagicConst\Function_($this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); + } + + protected function reduceRule432() { + $this->semValue = new Scalar\MagicConst\Namespace_($this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); + } + + protected function reduceRule433() { + $this->semValue = $this->semStack[$this->stackPos-(1-1)]; + } + + protected function reduceRule434() { + $this->semValue = $this->semStack[$this->stackPos-(1-1)]; + } + + protected function reduceRule435() { + $attrs = $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes; $attrs['kind'] = strpos($this->semStack[$this->stackPos-(3-1)], "'") === false ? Scalar\String_::KIND_HEREDOC : Scalar\String_::KIND_NOWDOC; preg_match('/\A[bB]?<<<[ \t]*[\'"]?([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)[\'"]?(?:\r\n|\n|\r)\z/', $this->semStack[$this->stackPos-(3-1)], $matches); $attrs['docLabel'] = $matches[1];; + $this->semValue = new Scalar\String_(Scalar\String_::parseDocString($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-2)]), $attrs); + } + + protected function reduceRule436() { + $attrs = $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes; $attrs['kind'] = strpos($this->semStack[$this->stackPos-(2-1)], "'") === false ? Scalar\String_::KIND_HEREDOC : Scalar\String_::KIND_NOWDOC; preg_match('/\A[bB]?<<<[ \t]*[\'"]?([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)[\'"]?(?:\r\n|\n|\r)\z/', $this->semStack[$this->stackPos-(2-1)], $matches); $attrs['docLabel'] = $matches[1];; + $this->semValue = new Scalar\String_('', $attrs); + } + + protected function reduceRule437() { + $attrs = $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes; $attrs['kind'] = Scalar\String_::KIND_DOUBLE_QUOTED; + foreach ($this->semStack[$this->stackPos-(3-2)] as $s) { if ($s instanceof Node\Scalar\EncapsedStringPart) { $s->value = Node\Scalar\String_::parseEscapeSequences($s->value, '"', true); } }; $this->semValue = new Scalar\Encapsed($this->semStack[$this->stackPos-(3-2)], $attrs); + } + + protected function reduceRule438() { + $attrs = $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes; $attrs['kind'] = strpos($this->semStack[$this->stackPos-(3-1)], "'") === false ? Scalar\String_::KIND_HEREDOC : Scalar\String_::KIND_NOWDOC; preg_match('/\A[bB]?<<<[ \t]*[\'"]?([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)[\'"]?(?:\r\n|\n|\r)\z/', $this->semStack[$this->stackPos-(3-1)], $matches); $attrs['docLabel'] = $matches[1];; + foreach ($this->semStack[$this->stackPos-(3-2)] as $s) { if ($s instanceof Node\Scalar\EncapsedStringPart) { $s->value = Node\Scalar\String_::parseEscapeSequences($s->value, null, true); } } $s->value = preg_replace('~(\r\n|\n|\r)\z~', '', $s->value); if ('' === $s->value) array_pop($this->semStack[$this->stackPos-(3-2)]);; $this->semValue = new Scalar\Encapsed($this->semStack[$this->stackPos-(3-2)], $attrs); + } + + protected function reduceRule439() { + $this->semValue = null; + } + + protected function reduceRule440() { + $this->semValue = $this->semStack[$this->stackPos-(1-1)]; + } + + protected function reduceRule441() { + $this->semValue = $this->semStack[$this->stackPos-(1-1)]; + } + + protected function reduceRule442() { + $this->semValue = $this->semStack[$this->stackPos-(3-2)]; + } + + protected function reduceRule443() { + $this->semValue = $this->semStack[$this->stackPos-(1-1)]; + } + + protected function reduceRule444() { + $this->semValue = $this->semStack[$this->stackPos-(1-1)]; + } + + protected function reduceRule445() { + $this->semValue = $this->semStack[$this->stackPos-(3-2)]; + } + + protected function reduceRule446() { + $this->semValue = $this->semStack[$this->stackPos-(1-1)]; + } + + protected function reduceRule447() { + $this->semValue = new Expr\Variable($this->semStack[$this->stackPos-(1-1)], $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); + } + + protected function reduceRule448() { + $this->semValue = new Expr\ArrayDimFetch($this->semStack[$this->stackPos-(4-1)], $this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); + } + + protected function reduceRule449() { + $this->semValue = new Expr\ArrayDimFetch($this->semStack[$this->stackPos-(4-1)], $this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); + } + + protected function reduceRule450() { + $this->semValue = new Expr\ArrayDimFetch($this->semStack[$this->stackPos-(4-1)], $this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); + } + + protected function reduceRule451() { + $this->semValue = $this->semStack[$this->stackPos-(1-1)]; + } + + protected function reduceRule452() { + $this->semValue = new Expr\MethodCall($this->semStack[$this->stackPos-(4-1)], $this->semStack[$this->stackPos-(4-3)], $this->semStack[$this->stackPos-(4-4)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); + } + + protected function reduceRule453() { + $this->semValue = $this->semStack[$this->stackPos-(1-1)]; + } + + protected function reduceRule454() { + $this->semValue = $this->semStack[$this->stackPos-(1-1)]; + } + + protected function reduceRule455() { + $this->semValue = new Expr\PropertyFetch($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule456() { + $this->semValue = substr($this->semStack[$this->stackPos-(1-1)], 1); + } + + protected function reduceRule457() { + $this->semValue = $this->semStack[$this->stackPos-(4-3)]; + } + + protected function reduceRule458() { + $this->semValue = new Expr\Variable($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); + } + + protected function reduceRule459() { + $this->semValue = new Expr\Error($this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); $this->errorState = 2; + } + + protected function reduceRule460() { + $this->semValue = new Expr\StaticPropertyFetch($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule461() { + $this->semValue = new Expr\Variable($this->semStack[$this->stackPos-(1-1)], $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); + } + + protected function reduceRule462() { + $this->semValue = new Expr\ArrayDimFetch($this->semStack[$this->stackPos-(4-1)], $this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); + } + + protected function reduceRule463() { + $this->semValue = new Expr\ArrayDimFetch($this->semStack[$this->stackPos-(4-1)], $this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); + } + + protected function reduceRule464() { + $this->semValue = new Expr\PropertyFetch($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule465() { + $this->semValue = new Expr\StaticPropertyFetch($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule466() { + $this->semValue = new Expr\StaticPropertyFetch($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule467() { + $this->semValue = $this->semStack[$this->stackPos-(1-1)]; + } + + protected function reduceRule468() { + $this->semValue = $this->semStack[$this->stackPos-(3-2)]; + } + + protected function reduceRule469() { + $this->semValue = new Expr\Variable($this->semStack[$this->stackPos-(1-1)], $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); + } + + protected function reduceRule470() { + $this->semValue = $this->semStack[$this->stackPos-(1-1)]; + } + + protected function reduceRule471() { + $this->semValue = $this->semStack[$this->stackPos-(3-2)]; + } + + protected function reduceRule472() { + $this->semValue = new Expr\Variable($this->semStack[$this->stackPos-(1-1)], $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); + } + + protected function reduceRule473() { + $this->semValue = new Expr\Error($this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); $this->errorState = 2; + } + + protected function reduceRule474() { + $this->semValue = new Expr\List_($this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); + } + + protected function reduceRule475() { + $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; + } + + protected function reduceRule476() { + $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); + } + + protected function reduceRule477() { + $this->semValue = new Expr\ArrayItem($this->semStack[$this->stackPos-(1-1)], null, false, $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); + } + + protected function reduceRule478() { + $this->semValue = new Expr\ArrayItem($this->semStack[$this->stackPos-(1-1)], null, false, $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); + } + + protected function reduceRule479() { + $this->semValue = new Expr\ArrayItem($this->semStack[$this->stackPos-(3-3)], $this->semStack[$this->stackPos-(3-1)], false, $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule480() { + $this->semValue = new Expr\ArrayItem($this->semStack[$this->stackPos-(3-3)], $this->semStack[$this->stackPos-(3-1)], false, $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule481() { + $this->semValue = null; + } + + protected function reduceRule482() { + $this->semValue = $this->semStack[$this->stackPos-(1-1)]; $end = count($this->semValue)-1; if ($this->semValue[$end] === null) unset($this->semValue[$end]); + } + + protected function reduceRule483() { + $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; + } + + protected function reduceRule484() { + $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); + } + + protected function reduceRule485() { + $this->semValue = new Expr\ArrayItem($this->semStack[$this->stackPos-(3-3)], $this->semStack[$this->stackPos-(3-1)], false, $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule486() { + $this->semValue = new Expr\ArrayItem($this->semStack[$this->stackPos-(1-1)], null, false, $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); + } + + protected function reduceRule487() { + $this->semValue = new Expr\ArrayItem($this->semStack[$this->stackPos-(4-4)], $this->semStack[$this->stackPos-(4-1)], true, $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); + } + + protected function reduceRule488() { + $this->semValue = new Expr\ArrayItem($this->semStack[$this->stackPos-(2-2)], null, true, $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); + } + + protected function reduceRule489() { + $this->semValue = null; + } + + protected function reduceRule490() { + $this->semStack[$this->stackPos-(2-1)][] = $this->semStack[$this->stackPos-(2-2)]; $this->semValue = $this->semStack[$this->stackPos-(2-1)]; + } + + protected function reduceRule491() { + $this->semStack[$this->stackPos-(2-1)][] = $this->semStack[$this->stackPos-(2-2)]; $this->semValue = $this->semStack[$this->stackPos-(2-1)]; + } + + protected function reduceRule492() { + $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); + } + + protected function reduceRule493() { + $this->semValue = array($this->semStack[$this->stackPos-(2-1)], $this->semStack[$this->stackPos-(2-2)]); + } + + protected function reduceRule494() { + $this->semValue = new Scalar\EncapsedStringPart($this->semStack[$this->stackPos-(1-1)], $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); + } + + protected function reduceRule495() { + $this->semValue = new Expr\Variable(substr($this->semStack[$this->stackPos-(1-1)], 1), $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); + } + + protected function reduceRule496() { + $this->semValue = $this->semStack[$this->stackPos-(1-1)]; + } + + protected function reduceRule497() { + $this->semValue = new Expr\ArrayDimFetch($this->semStack[$this->stackPos-(4-1)], $this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); + } + + protected function reduceRule498() { + $this->semValue = new Expr\PropertyFetch($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule499() { + $this->semValue = new Expr\Variable($this->semStack[$this->stackPos-(3-2)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule500() { + $this->semValue = new Expr\Variable($this->semStack[$this->stackPos-(3-2)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + } + + protected function reduceRule501() { + $this->semValue = new Expr\ArrayDimFetch(new Expr\Variable($this->semStack[$this->stackPos-(6-2)], $this->startAttributeStack[$this->stackPos-(6-1)] + $this->endAttributes), $this->semStack[$this->stackPos-(6-4)], $this->startAttributeStack[$this->stackPos-(6-1)] + $this->endAttributes); + } + + protected function reduceRule502() { + $this->semValue = $this->semStack[$this->stackPos-(3-2)]; + } + + protected function reduceRule503() { + $this->semValue = new Scalar\String_($this->semStack[$this->stackPos-(1-1)], $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); + } + + protected function reduceRule504() { + $this->semValue = $this->parseNumString($this->semStack[$this->stackPos-(1-1)], $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); + } + + protected function reduceRule505() { + $this->semValue = $this->parseNumString('-' . $this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); + } + + protected function reduceRule506() { + $this->semValue = new Expr\Variable(substr($this->semStack[$this->stackPos-(1-1)], 1), $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/Parser/Tokens.php b/lib/nikic/php-parser/lib/PhpParser/Parser/Tokens.php new file mode 100644 index 000000000..861663fae --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Parser/Tokens.php @@ -0,0 +1,144 @@ +lexer = $lexer; + $this->errors = array(); + + if (isset($options['throwOnError'])) { + throw new \LogicException( + '"throwOnError" is no longer supported, use "errorHandler" instead'); + } + } + + /** + * Parses PHP code into a node tree. + * + * If a non-throwing error handler is used, the parser will continue parsing after an error + * occurred and attempt to build a partial AST. + * + * @param string $code The source code to parse + * @param ErrorHandler|null $errorHandler Error handler to use for lexer/parser errors, defaults + * to ErrorHandler\Throwing. + * + * @return Node[]|null Array of statements (or null if the 'throwOnError' option is disabled and the parser was + * unable to recover from an error). + */ + public function parse($code, ErrorHandler $errorHandler = null) { + $this->errorHandler = $errorHandler ?: new ErrorHandler\Throwing; + + // Initialize the lexer + $this->lexer->startLexing($code, $this->errorHandler); + + // We start off with no lookahead-token + $symbol = self::SYMBOL_NONE; + + // The attributes for a node are taken from the first and last token of the node. + // From the first token only the startAttributes are taken and from the last only + // the endAttributes. Both are merged using the array union operator (+). + $startAttributes = '*POISON'; + $endAttributes = '*POISON'; + $this->endAttributes = $endAttributes; + + // Keep stack of start and end attributes + $this->startAttributeStack = array(); + $this->endAttributeStack = array($endAttributes); + + // Start off in the initial state and keep a stack of previous states + $state = 0; + $stateStack = array($state); + + // Semantic value stack (contains values of tokens and semantic action results) + $this->semStack = array(); + + // Current position in the stack(s) + $this->stackPos = 0; + + $this->errorState = 0; + + for (;;) { + //$this->traceNewState($state, $symbol); + + if ($this->actionBase[$state] == 0) { + $rule = $this->actionDefault[$state]; + } else { + if ($symbol === self::SYMBOL_NONE) { + // Fetch the next token id from the lexer and fetch additional info by-ref. + // The end attributes are fetched into a temporary variable and only set once the token is really + // shifted (not during read). Otherwise you would sometimes get off-by-one errors, when a rule is + // reduced after a token was read but not yet shifted. + $tokenId = $this->lexer->getNextToken($tokenValue, $startAttributes, $endAttributes); + + // map the lexer token id to the internally used symbols + $symbol = $tokenId >= 0 && $tokenId < $this->tokenToSymbolMapSize + ? $this->tokenToSymbol[$tokenId] + : $this->invalidSymbol; + + if ($symbol === $this->invalidSymbol) { + throw new \RangeException(sprintf( + 'The lexer returned an invalid token (id=%d, value=%s)', + $tokenId, $tokenValue + )); + } + + // This is necessary to assign some meaningful attributes to /* empty */ productions. They'll get + // the attributes of the next token, even though they don't contain it themselves. + $this->startAttributeStack[$this->stackPos+1] = $startAttributes; + $this->endAttributeStack[$this->stackPos+1] = $endAttributes; + $this->lookaheadStartAttributes = $startAttributes; + + //$this->traceRead($symbol); + } + + $idx = $this->actionBase[$state] + $symbol; + if ((($idx >= 0 && $idx < $this->actionTableSize && $this->actionCheck[$idx] == $symbol) + || ($state < $this->YY2TBLSTATE + && ($idx = $this->actionBase[$state + $this->YYNLSTATES] + $symbol) >= 0 + && $idx < $this->actionTableSize && $this->actionCheck[$idx] == $symbol)) + && ($action = $this->action[$idx]) != $this->defaultAction) { + /* + * >= YYNLSTATES: shift and reduce + * > 0: shift + * = 0: accept + * < 0: reduce + * = -YYUNEXPECTED: error + */ + if ($action > 0) { + /* shift */ + //$this->traceShift($symbol); + + ++$this->stackPos; + $stateStack[$this->stackPos] = $state = $action; + $this->semStack[$this->stackPos] = $tokenValue; + $this->startAttributeStack[$this->stackPos] = $startAttributes; + $this->endAttributeStack[$this->stackPos] = $endAttributes; + $this->endAttributes = $endAttributes; + $symbol = self::SYMBOL_NONE; + + if ($this->errorState) { + --$this->errorState; + } + + if ($action < $this->YYNLSTATES) { + continue; + } + + /* $yyn >= YYNLSTATES means shift-and-reduce */ + $rule = $action - $this->YYNLSTATES; + } else { + $rule = -$action; + } + } else { + $rule = $this->actionDefault[$state]; + } + } + + for (;;) { + if ($rule === 0) { + /* accept */ + //$this->traceAccept(); + return $this->semValue; + } elseif ($rule !== $this->unexpectedTokenRule) { + /* reduce */ + //$this->traceReduce($rule); + + try { + $this->{'reduceRule' . $rule}(); + } catch (Error $e) { + if (-1 === $e->getStartLine() && isset($startAttributes['startLine'])) { + $e->setStartLine($startAttributes['startLine']); + } + + $this->emitError($e); + // Can't recover from this type of error + return null; + } + + /* Goto - shift nonterminal */ + $lastEndAttributes = $this->endAttributeStack[$this->stackPos]; + $this->stackPos -= $this->ruleToLength[$rule]; + $nonTerminal = $this->ruleToNonTerminal[$rule]; + $idx = $this->gotoBase[$nonTerminal] + $stateStack[$this->stackPos]; + if ($idx >= 0 && $idx < $this->gotoTableSize && $this->gotoCheck[$idx] == $nonTerminal) { + $state = $this->goto[$idx]; + } else { + $state = $this->gotoDefault[$nonTerminal]; + } + + ++$this->stackPos; + $stateStack[$this->stackPos] = $state; + $this->semStack[$this->stackPos] = $this->semValue; + $this->endAttributeStack[$this->stackPos] = $lastEndAttributes; + } else { + /* error */ + switch ($this->errorState) { + case 0: + $msg = $this->getErrorMessage($symbol, $state); + $this->emitError(new Error($msg, $startAttributes + $endAttributes)); + // Break missing intentionally + case 1: + case 2: + $this->errorState = 3; + + // Pop until error-expecting state uncovered + while (!( + (($idx = $this->actionBase[$state] + $this->errorSymbol) >= 0 + && $idx < $this->actionTableSize && $this->actionCheck[$idx] == $this->errorSymbol) + || ($state < $this->YY2TBLSTATE + && ($idx = $this->actionBase[$state + $this->YYNLSTATES] + $this->errorSymbol) >= 0 + && $idx < $this->actionTableSize && $this->actionCheck[$idx] == $this->errorSymbol) + ) || ($action = $this->action[$idx]) == $this->defaultAction) { // Not totally sure about this + if ($this->stackPos <= 0) { + // Could not recover from error + return null; + } + $state = $stateStack[--$this->stackPos]; + //$this->tracePop($state); + } + + //$this->traceShift($this->errorSymbol); + ++$this->stackPos; + $stateStack[$this->stackPos] = $state = $action; + + // We treat the error symbol as being empty, so we reset the end attributes + // to the end attributes of the last non-error symbol + $this->endAttributeStack[$this->stackPos] = $this->endAttributeStack[$this->stackPos - 1]; + $this->endAttributes = $this->endAttributeStack[$this->stackPos - 1]; + break; + + case 3: + if ($symbol === 0) { + // Reached EOF without recovering from error + return null; + } + + //$this->traceDiscard($symbol); + $symbol = self::SYMBOL_NONE; + break 2; + } + } + + if ($state < $this->YYNLSTATES) { + break; + } + + /* >= YYNLSTATES means shift-and-reduce */ + $rule = $state - $this->YYNLSTATES; + } + } + + throw new \RuntimeException('Reached end of parser loop'); + } + + protected function emitError(Error $error) { + $this->errorHandler->handleError($error); + } + + protected function getErrorMessage($symbol, $state) { + $expectedString = ''; + if ($expected = $this->getExpectedTokens($state)) { + $expectedString = ', expecting ' . implode(' or ', $expected); + } + + return 'Syntax error, unexpected ' . $this->symbolToName[$symbol] . $expectedString; + } + + protected function getExpectedTokens($state) { + $expected = array(); + + $base = $this->actionBase[$state]; + foreach ($this->symbolToName as $symbol => $name) { + $idx = $base + $symbol; + if ($idx >= 0 && $idx < $this->actionTableSize && $this->actionCheck[$idx] === $symbol + || $state < $this->YY2TBLSTATE + && ($idx = $this->actionBase[$state + $this->YYNLSTATES] + $symbol) >= 0 + && $idx < $this->actionTableSize && $this->actionCheck[$idx] === $symbol + ) { + if ($this->action[$idx] != $this->unexpectedTokenRule + && $this->action[$idx] != $this->defaultAction + && $symbol != $this->errorSymbol + ) { + if (count($expected) == 4) { + /* Too many expected tokens */ + return array(); + } + + $expected[] = $name; + } + } + } + + return $expected; + } + + /* + * Tracing functions used for debugging the parser. + */ + + /* + protected function traceNewState($state, $symbol) { + echo '% State ' . $state + . ', Lookahead ' . ($symbol == self::SYMBOL_NONE ? '--none--' : $this->symbolToName[$symbol]) . "\n"; + } + + protected function traceRead($symbol) { + echo '% Reading ' . $this->symbolToName[$symbol] . "\n"; + } + + protected function traceShift($symbol) { + echo '% Shift ' . $this->symbolToName[$symbol] . "\n"; + } + + protected function traceAccept() { + echo "% Accepted.\n"; + } + + protected function traceReduce($n) { + echo '% Reduce by (' . $n . ') ' . $this->productions[$n] . "\n"; + } + + protected function tracePop($state) { + echo '% Recovering, uncovered state ' . $state . "\n"; + } + + protected function traceDiscard($symbol) { + echo '% Discard ' . $this->symbolToName[$symbol] . "\n"; + } + */ + + /* + * Helper functions invoked by semantic actions + */ + + /** + * Moves statements of semicolon-style namespaces into $ns->stmts and checks various error conditions. + * + * @param Node[] $stmts + * @return Node[] + */ + protected function handleNamespaces(array $stmts) { + $hasErrored = false; + $style = $this->getNamespacingStyle($stmts); + if (null === $style) { + // not namespaced, nothing to do + return $stmts; + } elseif ('brace' === $style) { + // For braced namespaces we only have to check that there are no invalid statements between the namespaces + $afterFirstNamespace = false; + foreach ($stmts as $stmt) { + if ($stmt instanceof Node\Stmt\Namespace_) { + $afterFirstNamespace = true; + } elseif (!$stmt instanceof Node\Stmt\HaltCompiler + && !$stmt instanceof Node\Stmt\Nop + && $afterFirstNamespace && !$hasErrored) { + $this->emitError(new Error( + 'No code may exist outside of namespace {}', $stmt->getAttributes())); + $hasErrored = true; // Avoid one error for every statement + } + } + return $stmts; + } else { + // For semicolon namespaces we have to move the statements after a namespace declaration into ->stmts + $resultStmts = array(); + $targetStmts =& $resultStmts; + foreach ($stmts as $stmt) { + if ($stmt instanceof Node\Stmt\Namespace_) { + if ($stmt->stmts === null) { + $stmt->stmts = array(); + $targetStmts =& $stmt->stmts; + $resultStmts[] = $stmt; + } else { + // This handles the invalid case of mixed style namespaces + $resultStmts[] = $stmt; + $targetStmts =& $resultStmts; + } + } elseif ($stmt instanceof Node\Stmt\HaltCompiler) { + // __halt_compiler() is not moved into the namespace + $resultStmts[] = $stmt; + } else { + $targetStmts[] = $stmt; + } + } + return $resultStmts; + } + } + + private function getNamespacingStyle(array $stmts) { + $style = null; + $hasNotAllowedStmts = false; + foreach ($stmts as $i => $stmt) { + if ($stmt instanceof Node\Stmt\Namespace_) { + $currentStyle = null === $stmt->stmts ? 'semicolon' : 'brace'; + if (null === $style) { + $style = $currentStyle; + if ($hasNotAllowedStmts) { + $this->emitError(new Error( + 'Namespace declaration statement has to be the very first statement in the script', + $stmt->getLine() // Avoid marking the entire namespace as an error + )); + } + } elseif ($style !== $currentStyle) { + $this->emitError(new Error( + 'Cannot mix bracketed namespace declarations with unbracketed namespace declarations', + $stmt->getLine() // Avoid marking the entire namespace as an error + )); + // Treat like semicolon style for namespace normalization + return 'semicolon'; + } + continue; + } + + /* declare(), __halt_compiler() and nops can be used before a namespace declaration */ + if ($stmt instanceof Node\Stmt\Declare_ + || $stmt instanceof Node\Stmt\HaltCompiler + || $stmt instanceof Node\Stmt\Nop) { + continue; + } + + /* There may be a hashbang line at the very start of the file */ + if ($i == 0 && $stmt instanceof Node\Stmt\InlineHTML && preg_match('/\A#!.*\r?\n\z/', $stmt->value)) { + continue; + } + + /* Everything else if forbidden before namespace declarations */ + $hasNotAllowedStmts = true; + } + return $style; + } + + protected function handleBuiltinTypes(Name $name) { + $scalarTypes = [ + 'bool' => true, + 'int' => true, + 'float' => true, + 'string' => true, + 'iterable' => true, + 'void' => true, + 'object' => true, + ]; + + if (!$name->isUnqualified()) { + return $name; + } + + $lowerName = strtolower($name->toString()); + return isset($scalarTypes[$lowerName]) ? $lowerName : $name; + } + + protected static $specialNames = array( + 'self' => true, + 'parent' => true, + 'static' => true, + ); + + protected function getAttributesAt($pos) { + return $this->startAttributeStack[$pos] + $this->endAttributeStack[$pos]; + } + + protected function parseLNumber($str, $attributes, $allowInvalidOctal = false) { + try { + return LNumber::fromString($str, $attributes, $allowInvalidOctal); + } catch (Error $error) { + $this->emitError($error); + // Use dummy value + return new LNumber(0, $attributes); + } + } + + protected function parseNumString($str, $attributes) { + if (!preg_match('/^(?:0|-?[1-9][0-9]*)$/', $str)) { + return new String_($str, $attributes); + } + + $num = +$str; + if (!is_int($num)) { + return new String_($str, $attributes); + } + + return new LNumber($num, $attributes); + } + + protected function checkModifier($a, $b, $modifierPos) { + // Jumping through some hoops here because verifyModifier() is also used elsewhere + try { + Class_::verifyModifier($a, $b); + } catch (Error $error) { + $error->setAttributes($this->getAttributesAt($modifierPos)); + $this->emitError($error); + } + } + + protected function checkParam(Param $node) { + if ($node->variadic && null !== $node->default) { + $this->emitError(new Error( + 'Variadic parameter cannot have a default value', + $node->default->getAttributes() + )); + } + } + + protected function checkTryCatch(TryCatch $node) { + if (empty($node->catches) && null === $node->finally) { + $this->emitError(new Error( + 'Cannot use try without catch or finally', $node->getAttributes() + )); + } + } + + protected function checkNamespace(Namespace_ $node) { + if (isset(self::$specialNames[strtolower($node->name)])) { + $this->emitError(new Error( + sprintf('Cannot use \'%s\' as namespace name', $node->name), + $node->name->getAttributes() + )); + } + + if (null !== $node->stmts) { + foreach ($node->stmts as $stmt) { + if ($stmt instanceof Namespace_) { + $this->emitError(new Error( + 'Namespace declarations cannot be nested', $stmt->getAttributes() + )); + } + } + } + } + + protected function checkClass(Class_ $node, $namePos) { + if (null !== $node->name && isset(self::$specialNames[strtolower($node->name)])) { + $this->emitError(new Error( + sprintf('Cannot use \'%s\' as class name as it is reserved', $node->name), + $this->getAttributesAt($namePos) + )); + } + + if (isset(self::$specialNames[strtolower($node->extends)])) { + $this->emitError(new Error( + sprintf('Cannot use \'%s\' as class name as it is reserved', $node->extends), + $node->extends->getAttributes() + )); + } + + foreach ($node->implements as $interface) { + if (isset(self::$specialNames[strtolower($interface)])) { + $this->emitError(new Error( + sprintf('Cannot use \'%s\' as interface name as it is reserved', $interface), + $interface->getAttributes() + )); + } + } + } + + protected function checkInterface(Interface_ $node, $namePos) { + if (null !== $node->name && isset(self::$specialNames[strtolower($node->name)])) { + $this->emitError(new Error( + sprintf('Cannot use \'%s\' as class name as it is reserved', $node->name), + $this->getAttributesAt($namePos) + )); + } + + foreach ($node->extends as $interface) { + if (isset(self::$specialNames[strtolower($interface)])) { + $this->emitError(new Error( + sprintf('Cannot use \'%s\' as interface name as it is reserved', $interface), + $interface->getAttributes() + )); + } + } + } + + protected function checkClassMethod(ClassMethod $node, $modifierPos) { + if ($node->flags & Class_::MODIFIER_STATIC) { + switch (strtolower($node->name)) { + case '__construct': + $this->emitError(new Error( + sprintf('Constructor %s() cannot be static', $node->name), + $this->getAttributesAt($modifierPos))); + break; + case '__destruct': + $this->emitError(new Error( + sprintf('Destructor %s() cannot be static', $node->name), + $this->getAttributesAt($modifierPos))); + break; + case '__clone': + $this->emitError(new Error( + sprintf('Clone method %s() cannot be static', $node->name), + $this->getAttributesAt($modifierPos))); + break; + } + } + } + + protected function checkClassConst(ClassConst $node, $modifierPos) { + if ($node->flags & Class_::MODIFIER_STATIC) { + $this->emitError(new Error( + "Cannot use 'static' as constant modifier", + $this->getAttributesAt($modifierPos))); + } + if ($node->flags & Class_::MODIFIER_ABSTRACT) { + $this->emitError(new Error( + "Cannot use 'abstract' as constant modifier", + $this->getAttributesAt($modifierPos))); + } + if ($node->flags & Class_::MODIFIER_FINAL) { + $this->emitError(new Error( + "Cannot use 'final' as constant modifier", + $this->getAttributesAt($modifierPos))); + } + } + + protected function checkProperty(Property $node, $modifierPos) { + if ($node->flags & Class_::MODIFIER_ABSTRACT) { + $this->emitError(new Error('Properties cannot be declared abstract', + $this->getAttributesAt($modifierPos))); + } + + if ($node->flags & Class_::MODIFIER_FINAL) { + $this->emitError(new Error('Properties cannot be declared final', + $this->getAttributesAt($modifierPos))); + } + } + + protected function checkUseUse(UseUse $node, $namePos) { + if ('self' == strtolower($node->alias) || 'parent' == strtolower($node->alias)) { + $this->emitError(new Error( + sprintf( + 'Cannot use %s as %s because \'%2$s\' is a special class name', + $node->name, $node->alias + ), + $this->getAttributesAt($namePos) + )); + } + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/ParserFactory.php b/lib/nikic/php-parser/lib/PhpParser/ParserFactory.php new file mode 100644 index 000000000..28b9070d4 --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/ParserFactory.php @@ -0,0 +1,43 @@ +type ? $this->pType($node->type) . ' ' : '') + . ($node->byRef ? '&' : '') + . ($node->variadic ? '...' : '') + . '$' . $node->name + . ($node->default ? ' = ' . $this->p($node->default) : ''); + } + + protected function pArg(Node\Arg $node) { + return ($node->byRef ? '&' : '') . ($node->unpack ? '...' : '') . $this->p($node->value); + } + + protected function pConst(Node\Const_ $node) { + return $node->name . ' = ' . $this->p($node->value); + } + + protected function pNullableType(Node\NullableType $node) { + return '?' . $this->pType($node->type); + } + + // Names + + protected function pName(Name $node) { + return implode('\\', $node->parts); + } + + protected function pName_FullyQualified(Name\FullyQualified $node) { + return '\\' . implode('\\', $node->parts); + } + + protected function pName_Relative(Name\Relative $node) { + return 'namespace\\' . implode('\\', $node->parts); + } + + // Magic Constants + + protected function pScalar_MagicConst_Class(MagicConst\Class_ $node) { + return '__CLASS__'; + } + + protected function pScalar_MagicConst_Dir(MagicConst\Dir $node) { + return '__DIR__'; + } + + protected function pScalar_MagicConst_File(MagicConst\File $node) { + return '__FILE__'; + } + + protected function pScalar_MagicConst_Function(MagicConst\Function_ $node) { + return '__FUNCTION__'; + } + + protected function pScalar_MagicConst_Line(MagicConst\Line $node) { + return '__LINE__'; + } + + protected function pScalar_MagicConst_Method(MagicConst\Method $node) { + return '__METHOD__'; + } + + protected function pScalar_MagicConst_Namespace(MagicConst\Namespace_ $node) { + return '__NAMESPACE__'; + } + + protected function pScalar_MagicConst_Trait(MagicConst\Trait_ $node) { + return '__TRAIT__'; + } + + // Scalars + + protected function pScalar_String(Scalar\String_ $node) { + $kind = $node->getAttribute('kind', Scalar\String_::KIND_SINGLE_QUOTED); + switch ($kind) { + case Scalar\String_::KIND_NOWDOC: + $label = $node->getAttribute('docLabel'); + if ($label && !$this->containsEndLabel($node->value, $label)) { + if ($node->value === '') { + return $this->pNoIndent("<<<'$label'\n$label") . $this->docStringEndToken; + } + + return $this->pNoIndent("<<<'$label'\n$node->value\n$label") + . $this->docStringEndToken; + } + /* break missing intentionally */ + case Scalar\String_::KIND_SINGLE_QUOTED: + return '\'' . $this->pNoIndent(addcslashes($node->value, '\'\\')) . '\''; + case Scalar\String_::KIND_HEREDOC: + $label = $node->getAttribute('docLabel'); + if ($label && !$this->containsEndLabel($node->value, $label)) { + if ($node->value === '') { + return $this->pNoIndent("<<<$label\n$label") . $this->docStringEndToken; + } + + $escaped = $this->escapeString($node->value, null); + return $this->pNoIndent("<<<$label\n" . $escaped ."\n$label") + . $this->docStringEndToken; + } + /* break missing intentionally */ + case Scalar\String_::KIND_DOUBLE_QUOTED: + return '"' . $this->escapeString($node->value, '"') . '"'; + } + throw new \Exception('Invalid string kind'); + } + + protected function pScalar_Encapsed(Scalar\Encapsed $node) { + if ($node->getAttribute('kind') === Scalar\String_::KIND_HEREDOC) { + $label = $node->getAttribute('docLabel'); + if ($label && !$this->encapsedContainsEndLabel($node->parts, $label)) { + if (count($node->parts) === 1 + && $node->parts[0] instanceof Scalar\EncapsedStringPart + && $node->parts[0]->value === '' + ) { + return $this->pNoIndent("<<<$label\n$label") . $this->docStringEndToken; + } + + return $this->pNoIndent( + "<<<$label\n" . $this->pEncapsList($node->parts, null) . "\n$label" + ) . $this->docStringEndToken; + } + } + return '"' . $this->pEncapsList($node->parts, '"') . '"'; + } + + protected function pScalar_LNumber(Scalar\LNumber $node) { + if ($node->value === -\PHP_INT_MAX-1) { + // PHP_INT_MIN cannot be represented as a literal, + // because the sign is not part of the literal + return '(-' . \PHP_INT_MAX . '-1)'; + } + + $kind = $node->getAttribute('kind', Scalar\LNumber::KIND_DEC); + if (Scalar\LNumber::KIND_DEC === $kind) { + return (string) $node->value; + } + + $sign = $node->value < 0 ? '-' : ''; + $str = (string) $node->value; + switch ($kind) { + case Scalar\LNumber::KIND_BIN: + return $sign . '0b' . base_convert($str, 10, 2); + case Scalar\LNumber::KIND_OCT: + return $sign . '0' . base_convert($str, 10, 8); + case Scalar\LNumber::KIND_HEX: + return $sign . '0x' . base_convert($str, 10, 16); + } + throw new \Exception('Invalid number kind'); + } + + protected function pScalar_DNumber(Scalar\DNumber $node) { + if (!is_finite($node->value)) { + if ($node->value === \INF) { + return '\INF'; + } elseif ($node->value === -\INF) { + return '-\INF'; + } else { + return '\NAN'; + } + } + + // Try to find a short full-precision representation + $stringValue = sprintf('%.16G', $node->value); + if ($node->value !== (double) $stringValue) { + $stringValue = sprintf('%.17G', $node->value); + } + + // %G is locale dependent and there exists no locale-independent alternative. We don't want + // mess with switching locales here, so let's assume that a comma is the only non-standard + // decimal separator we may encounter... + $stringValue = str_replace(',', '.', $stringValue); + + // ensure that number is really printed as float + return preg_match('/^-?[0-9]+$/', $stringValue) ? $stringValue . '.0' : $stringValue; + } + + // Assignments + + protected function pExpr_Assign(Expr\Assign $node) { + return $this->pInfixOp('Expr_Assign', $node->var, ' = ', $node->expr); + } + + protected function pExpr_AssignRef(Expr\AssignRef $node) { + return $this->pInfixOp('Expr_AssignRef', $node->var, ' =& ', $node->expr); + } + + protected function pExpr_AssignOp_Plus(AssignOp\Plus $node) { + return $this->pInfixOp('Expr_AssignOp_Plus', $node->var, ' += ', $node->expr); + } + + protected function pExpr_AssignOp_Minus(AssignOp\Minus $node) { + return $this->pInfixOp('Expr_AssignOp_Minus', $node->var, ' -= ', $node->expr); + } + + protected function pExpr_AssignOp_Mul(AssignOp\Mul $node) { + return $this->pInfixOp('Expr_AssignOp_Mul', $node->var, ' *= ', $node->expr); + } + + protected function pExpr_AssignOp_Div(AssignOp\Div $node) { + return $this->pInfixOp('Expr_AssignOp_Div', $node->var, ' /= ', $node->expr); + } + + protected function pExpr_AssignOp_Concat(AssignOp\Concat $node) { + return $this->pInfixOp('Expr_AssignOp_Concat', $node->var, ' .= ', $node->expr); + } + + protected function pExpr_AssignOp_Mod(AssignOp\Mod $node) { + return $this->pInfixOp('Expr_AssignOp_Mod', $node->var, ' %= ', $node->expr); + } + + protected function pExpr_AssignOp_BitwiseAnd(AssignOp\BitwiseAnd $node) { + return $this->pInfixOp('Expr_AssignOp_BitwiseAnd', $node->var, ' &= ', $node->expr); + } + + protected function pExpr_AssignOp_BitwiseOr(AssignOp\BitwiseOr $node) { + return $this->pInfixOp('Expr_AssignOp_BitwiseOr', $node->var, ' |= ', $node->expr); + } + + protected function pExpr_AssignOp_BitwiseXor(AssignOp\BitwiseXor $node) { + return $this->pInfixOp('Expr_AssignOp_BitwiseXor', $node->var, ' ^= ', $node->expr); + } + + protected function pExpr_AssignOp_ShiftLeft(AssignOp\ShiftLeft $node) { + return $this->pInfixOp('Expr_AssignOp_ShiftLeft', $node->var, ' <<= ', $node->expr); + } + + protected function pExpr_AssignOp_ShiftRight(AssignOp\ShiftRight $node) { + return $this->pInfixOp('Expr_AssignOp_ShiftRight', $node->var, ' >>= ', $node->expr); + } + + protected function pExpr_AssignOp_Pow(AssignOp\Pow $node) { + return $this->pInfixOp('Expr_AssignOp_Pow', $node->var, ' **= ', $node->expr); + } + + // Binary expressions + + protected function pExpr_BinaryOp_Plus(BinaryOp\Plus $node) { + return $this->pInfixOp('Expr_BinaryOp_Plus', $node->left, ' + ', $node->right); + } + + protected function pExpr_BinaryOp_Minus(BinaryOp\Minus $node) { + return $this->pInfixOp('Expr_BinaryOp_Minus', $node->left, ' - ', $node->right); + } + + protected function pExpr_BinaryOp_Mul(BinaryOp\Mul $node) { + return $this->pInfixOp('Expr_BinaryOp_Mul', $node->left, ' * ', $node->right); + } + + protected function pExpr_BinaryOp_Div(BinaryOp\Div $node) { + return $this->pInfixOp('Expr_BinaryOp_Div', $node->left, ' / ', $node->right); + } + + protected function pExpr_BinaryOp_Concat(BinaryOp\Concat $node) { + return $this->pInfixOp('Expr_BinaryOp_Concat', $node->left, ' . ', $node->right); + } + + protected function pExpr_BinaryOp_Mod(BinaryOp\Mod $node) { + return $this->pInfixOp('Expr_BinaryOp_Mod', $node->left, ' % ', $node->right); + } + + protected function pExpr_BinaryOp_BooleanAnd(BinaryOp\BooleanAnd $node) { + return $this->pInfixOp('Expr_BinaryOp_BooleanAnd', $node->left, ' && ', $node->right); + } + + protected function pExpr_BinaryOp_BooleanOr(BinaryOp\BooleanOr $node) { + return $this->pInfixOp('Expr_BinaryOp_BooleanOr', $node->left, ' || ', $node->right); + } + + protected function pExpr_BinaryOp_BitwiseAnd(BinaryOp\BitwiseAnd $node) { + return $this->pInfixOp('Expr_BinaryOp_BitwiseAnd', $node->left, ' & ', $node->right); + } + + protected function pExpr_BinaryOp_BitwiseOr(BinaryOp\BitwiseOr $node) { + return $this->pInfixOp('Expr_BinaryOp_BitwiseOr', $node->left, ' | ', $node->right); + } + + protected function pExpr_BinaryOp_BitwiseXor(BinaryOp\BitwiseXor $node) { + return $this->pInfixOp('Expr_BinaryOp_BitwiseXor', $node->left, ' ^ ', $node->right); + } + + protected function pExpr_BinaryOp_ShiftLeft(BinaryOp\ShiftLeft $node) { + return $this->pInfixOp('Expr_BinaryOp_ShiftLeft', $node->left, ' << ', $node->right); + } + + protected function pExpr_BinaryOp_ShiftRight(BinaryOp\ShiftRight $node) { + return $this->pInfixOp('Expr_BinaryOp_ShiftRight', $node->left, ' >> ', $node->right); + } + + protected function pExpr_BinaryOp_Pow(BinaryOp\Pow $node) { + return $this->pInfixOp('Expr_BinaryOp_Pow', $node->left, ' ** ', $node->right); + } + + protected function pExpr_BinaryOp_LogicalAnd(BinaryOp\LogicalAnd $node) { + return $this->pInfixOp('Expr_BinaryOp_LogicalAnd', $node->left, ' and ', $node->right); + } + + protected function pExpr_BinaryOp_LogicalOr(BinaryOp\LogicalOr $node) { + return $this->pInfixOp('Expr_BinaryOp_LogicalOr', $node->left, ' or ', $node->right); + } + + protected function pExpr_BinaryOp_LogicalXor(BinaryOp\LogicalXor $node) { + return $this->pInfixOp('Expr_BinaryOp_LogicalXor', $node->left, ' xor ', $node->right); + } + + protected function pExpr_BinaryOp_Equal(BinaryOp\Equal $node) { + return $this->pInfixOp('Expr_BinaryOp_Equal', $node->left, ' == ', $node->right); + } + + protected function pExpr_BinaryOp_NotEqual(BinaryOp\NotEqual $node) { + return $this->pInfixOp('Expr_BinaryOp_NotEqual', $node->left, ' != ', $node->right); + } + + protected function pExpr_BinaryOp_Identical(BinaryOp\Identical $node) { + return $this->pInfixOp('Expr_BinaryOp_Identical', $node->left, ' === ', $node->right); + } + + protected function pExpr_BinaryOp_NotIdentical(BinaryOp\NotIdentical $node) { + return $this->pInfixOp('Expr_BinaryOp_NotIdentical', $node->left, ' !== ', $node->right); + } + + protected function pExpr_BinaryOp_Spaceship(BinaryOp\Spaceship $node) { + return $this->pInfixOp('Expr_BinaryOp_Spaceship', $node->left, ' <=> ', $node->right); + } + + protected function pExpr_BinaryOp_Greater(BinaryOp\Greater $node) { + return $this->pInfixOp('Expr_BinaryOp_Greater', $node->left, ' > ', $node->right); + } + + protected function pExpr_BinaryOp_GreaterOrEqual(BinaryOp\GreaterOrEqual $node) { + return $this->pInfixOp('Expr_BinaryOp_GreaterOrEqual', $node->left, ' >= ', $node->right); + } + + protected function pExpr_BinaryOp_Smaller(BinaryOp\Smaller $node) { + return $this->pInfixOp('Expr_BinaryOp_Smaller', $node->left, ' < ', $node->right); + } + + protected function pExpr_BinaryOp_SmallerOrEqual(BinaryOp\SmallerOrEqual $node) { + return $this->pInfixOp('Expr_BinaryOp_SmallerOrEqual', $node->left, ' <= ', $node->right); + } + + protected function pExpr_BinaryOp_Coalesce(BinaryOp\Coalesce $node) { + return $this->pInfixOp('Expr_BinaryOp_Coalesce', $node->left, ' ?? ', $node->right); + } + + protected function pExpr_Instanceof(Expr\Instanceof_ $node) { + return $this->pInfixOp('Expr_Instanceof', $node->expr, ' instanceof ', $node->class); + } + + // Unary expressions + + protected function pExpr_BooleanNot(Expr\BooleanNot $node) { + return $this->pPrefixOp('Expr_BooleanNot', '!', $node->expr); + } + + protected function pExpr_BitwiseNot(Expr\BitwiseNot $node) { + return $this->pPrefixOp('Expr_BitwiseNot', '~', $node->expr); + } + + protected function pExpr_UnaryMinus(Expr\UnaryMinus $node) { + if ($node->expr instanceof Expr\UnaryMinus || $node->expr instanceof Expr\PreDec) { + // Enforce -(-$expr) instead of --$expr + return '-(' . $this->p($node->expr) . ')'; + } + return $this->pPrefixOp('Expr_UnaryMinus', '-', $node->expr); + } + + protected function pExpr_UnaryPlus(Expr\UnaryPlus $node) { + if ($node->expr instanceof Expr\UnaryPlus || $node->expr instanceof Expr\PreInc) { + // Enforce +(+$expr) instead of ++$expr + return '+(' . $this->p($node->expr) . ')'; + } + return $this->pPrefixOp('Expr_UnaryPlus', '+', $node->expr); + } + + protected function pExpr_PreInc(Expr\PreInc $node) { + return $this->pPrefixOp('Expr_PreInc', '++', $node->var); + } + + protected function pExpr_PreDec(Expr\PreDec $node) { + return $this->pPrefixOp('Expr_PreDec', '--', $node->var); + } + + protected function pExpr_PostInc(Expr\PostInc $node) { + return $this->pPostfixOp('Expr_PostInc', $node->var, '++'); + } + + protected function pExpr_PostDec(Expr\PostDec $node) { + return $this->pPostfixOp('Expr_PostDec', $node->var, '--'); + } + + protected function pExpr_ErrorSuppress(Expr\ErrorSuppress $node) { + return $this->pPrefixOp('Expr_ErrorSuppress', '@', $node->expr); + } + + protected function pExpr_YieldFrom(Expr\YieldFrom $node) { + return $this->pPrefixOp('Expr_YieldFrom', 'yield from ', $node->expr); + } + + protected function pExpr_Print(Expr\Print_ $node) { + return $this->pPrefixOp('Expr_Print', 'print ', $node->expr); + } + + // Casts + + protected function pExpr_Cast_Int(Cast\Int_ $node) { + return $this->pPrefixOp('Expr_Cast_Int', '(int) ', $node->expr); + } + + protected function pExpr_Cast_Double(Cast\Double $node) { + return $this->pPrefixOp('Expr_Cast_Double', '(double) ', $node->expr); + } + + protected function pExpr_Cast_String(Cast\String_ $node) { + return $this->pPrefixOp('Expr_Cast_String', '(string) ', $node->expr); + } + + protected function pExpr_Cast_Array(Cast\Array_ $node) { + return $this->pPrefixOp('Expr_Cast_Array', '(array) ', $node->expr); + } + + protected function pExpr_Cast_Object(Cast\Object_ $node) { + return $this->pPrefixOp('Expr_Cast_Object', '(object) ', $node->expr); + } + + protected function pExpr_Cast_Bool(Cast\Bool_ $node) { + return $this->pPrefixOp('Expr_Cast_Bool', '(bool) ', $node->expr); + } + + protected function pExpr_Cast_Unset(Cast\Unset_ $node) { + return $this->pPrefixOp('Expr_Cast_Unset', '(unset) ', $node->expr); + } + + // Function calls and similar constructs + + protected function pExpr_FuncCall(Expr\FuncCall $node) { + return $this->pCallLhs($node->name) + . '(' . $this->pMaybeMultiline($node->args) . ')'; + } + + protected function pExpr_MethodCall(Expr\MethodCall $node) { + return $this->pDereferenceLhs($node->var) . '->' . $this->pObjectProperty($node->name) + . '(' . $this->pMaybeMultiline($node->args) . ')'; + } + + protected function pExpr_StaticCall(Expr\StaticCall $node) { + return $this->pDereferenceLhs($node->class) . '::' + . ($node->name instanceof Expr + ? ($node->name instanceof Expr\Variable + ? $this->p($node->name) + : '{' . $this->p($node->name) . '}') + : $node->name) + . '(' . $this->pMaybeMultiline($node->args) . ')'; + } + + protected function pExpr_Empty(Expr\Empty_ $node) { + return 'empty(' . $this->p($node->expr) . ')'; + } + + protected function pExpr_Isset(Expr\Isset_ $node) { + return 'isset(' . $this->pCommaSeparated($node->vars) . ')'; + } + + protected function pExpr_Eval(Expr\Eval_ $node) { + return 'eval(' . $this->p($node->expr) . ')'; + } + + protected function pExpr_Include(Expr\Include_ $node) { + static $map = array( + Expr\Include_::TYPE_INCLUDE => 'include', + Expr\Include_::TYPE_INCLUDE_ONCE => 'include_once', + Expr\Include_::TYPE_REQUIRE => 'require', + Expr\Include_::TYPE_REQUIRE_ONCE => 'require_once', + ); + + return $map[$node->type] . ' ' . $this->p($node->expr); + } + + protected function pExpr_List(Expr\List_ $node) { + return 'list(' . $this->pCommaSeparated($node->items) . ')'; + } + + // Other + + protected function pExpr_Error(Expr\Error $node) { + throw new \LogicException('Cannot pretty-print AST with Error nodes'); + } + + protected function pExpr_Variable(Expr\Variable $node) { + if ($node->name instanceof Expr) { + return '${' . $this->p($node->name) . '}'; + } else { + return '$' . $node->name; + } + } + + protected function pExpr_Array(Expr\Array_ $node) { + $syntax = $node->getAttribute('kind', + $this->options['shortArraySyntax'] ? Expr\Array_::KIND_SHORT : Expr\Array_::KIND_LONG); + if ($syntax === Expr\Array_::KIND_SHORT) { + return '[' . $this->pMaybeMultiline($node->items, true) . ']'; + } else { + return 'array(' . $this->pMaybeMultiline($node->items, true) . ')'; + } + } + + protected function pExpr_ArrayItem(Expr\ArrayItem $node) { + return (null !== $node->key ? $this->p($node->key) . ' => ' : '') + . ($node->byRef ? '&' : '') . $this->p($node->value); + } + + protected function pExpr_ArrayDimFetch(Expr\ArrayDimFetch $node) { + return $this->pDereferenceLhs($node->var) + . '[' . (null !== $node->dim ? $this->p($node->dim) : '') . ']'; + } + + protected function pExpr_ConstFetch(Expr\ConstFetch $node) { + return $this->p($node->name); + } + + protected function pExpr_ClassConstFetch(Expr\ClassConstFetch $node) { + return $this->p($node->class) . '::' + . (is_string($node->name) ? $node->name : $this->p($node->name)); + } + + protected function pExpr_PropertyFetch(Expr\PropertyFetch $node) { + return $this->pDereferenceLhs($node->var) . '->' . $this->pObjectProperty($node->name); + } + + protected function pExpr_StaticPropertyFetch(Expr\StaticPropertyFetch $node) { + return $this->pDereferenceLhs($node->class) . '::$' . $this->pObjectProperty($node->name); + } + + protected function pExpr_ShellExec(Expr\ShellExec $node) { + return '`' . $this->pEncapsList($node->parts, '`') . '`'; + } + + protected function pExpr_Closure(Expr\Closure $node) { + return ($node->static ? 'static ' : '') + . 'function ' . ($node->byRef ? '&' : '') + . '(' . $this->pCommaSeparated($node->params) . ')' + . (!empty($node->uses) ? ' use(' . $this->pCommaSeparated($node->uses) . ')': '') + . (null !== $node->returnType ? ' : ' . $this->pType($node->returnType) : '') + . ' {' . $this->pStmts($node->stmts) . "\n" . '}'; + } + + protected function pExpr_ClosureUse(Expr\ClosureUse $node) { + return ($node->byRef ? '&' : '') . '$' . $node->var; + } + + protected function pExpr_New(Expr\New_ $node) { + if ($node->class instanceof Stmt\Class_) { + $args = $node->args ? '(' . $this->pMaybeMultiline($node->args) . ')' : ''; + return 'new ' . $this->pClassCommon($node->class, $args); + } + return 'new ' . $this->p($node->class) . '(' . $this->pMaybeMultiline($node->args) . ')'; + } + + protected function pExpr_Clone(Expr\Clone_ $node) { + return 'clone ' . $this->p($node->expr); + } + + protected function pExpr_Ternary(Expr\Ternary $node) { + // a bit of cheating: we treat the ternary as a binary op where the ?...: part is the operator. + // this is okay because the part between ? and : never needs parentheses. + return $this->pInfixOp('Expr_Ternary', + $node->cond, ' ?' . (null !== $node->if ? ' ' . $this->p($node->if) . ' ' : '') . ': ', $node->else + ); + } + + protected function pExpr_Exit(Expr\Exit_ $node) { + $kind = $node->getAttribute('kind', Expr\Exit_::KIND_DIE); + return ($kind === Expr\Exit_::KIND_EXIT ? 'exit' : 'die') + . (null !== $node->expr ? '(' . $this->p($node->expr) . ')' : ''); + } + + protected function pExpr_Yield(Expr\Yield_ $node) { + if ($node->value === null) { + return 'yield'; + } else { + // this is a bit ugly, but currently there is no way to detect whether the parentheses are necessary + return '(yield ' + . ($node->key !== null ? $this->p($node->key) . ' => ' : '') + . $this->p($node->value) + . ')'; + } + } + + // Declarations + + protected function pStmt_Namespace(Stmt\Namespace_ $node) { + if ($this->canUseSemicolonNamespaces) { + return 'namespace ' . $this->p($node->name) . ';' . "\n" . $this->pStmts($node->stmts, false); + } else { + return 'namespace' . (null !== $node->name ? ' ' . $this->p($node->name) : '') + . ' {' . $this->pStmts($node->stmts) . "\n" . '}'; + } + } + + protected function pStmt_Use(Stmt\Use_ $node) { + return 'use ' . $this->pUseType($node->type) + . $this->pCommaSeparated($node->uses) . ';'; + } + + protected function pStmt_GroupUse(Stmt\GroupUse $node) { + return 'use ' . $this->pUseType($node->type) . $this->pName($node->prefix) + . '\{' . $this->pCommaSeparated($node->uses) . '};'; + } + + protected function pStmt_UseUse(Stmt\UseUse $node) { + return $this->pUseType($node->type) . $this->p($node->name) + . ($node->name->getLast() !== $node->alias ? ' as ' . $node->alias : ''); + } + + protected function pUseType($type) { + return $type === Stmt\Use_::TYPE_FUNCTION ? 'function ' + : ($type === Stmt\Use_::TYPE_CONSTANT ? 'const ' : ''); + } + + protected function pStmt_Interface(Stmt\Interface_ $node) { + return 'interface ' . $node->name + . (!empty($node->extends) ? ' extends ' . $this->pCommaSeparated($node->extends) : '') + . "\n" . '{' . $this->pStmts($node->stmts) . "\n" . '}'; + } + + protected function pStmt_Class(Stmt\Class_ $node) { + return $this->pClassCommon($node, ' ' . $node->name); + } + + protected function pStmt_Trait(Stmt\Trait_ $node) { + return 'trait ' . $node->name + . "\n" . '{' . $this->pStmts($node->stmts) . "\n" . '}'; + } + + protected function pStmt_TraitUse(Stmt\TraitUse $node) { + return 'use ' . $this->pCommaSeparated($node->traits) + . (empty($node->adaptations) + ? ';' + : ' {' . $this->pStmts($node->adaptations) . "\n" . '}'); + } + + protected function pStmt_TraitUseAdaptation_Precedence(Stmt\TraitUseAdaptation\Precedence $node) { + return $this->p($node->trait) . '::' . $node->method + . ' insteadof ' . $this->pCommaSeparated($node->insteadof) . ';'; + } + + protected function pStmt_TraitUseAdaptation_Alias(Stmt\TraitUseAdaptation\Alias $node) { + return (null !== $node->trait ? $this->p($node->trait) . '::' : '') + . $node->method . ' as' + . (null !== $node->newModifier ? ' ' . rtrim($this->pModifiers($node->newModifier), ' ') : '') + . (null !== $node->newName ? ' ' . $node->newName : '') + . ';'; + } + + protected function pStmt_Property(Stmt\Property $node) { + return (0 === $node->flags ? 'var ' : $this->pModifiers($node->flags)) . $this->pCommaSeparated($node->props) . ';'; + } + + protected function pStmt_PropertyProperty(Stmt\PropertyProperty $node) { + return '$' . $node->name + . (null !== $node->default ? ' = ' . $this->p($node->default) : ''); + } + + protected function pStmt_ClassMethod(Stmt\ClassMethod $node) { + return $this->pModifiers($node->flags) + . 'function ' . ($node->byRef ? '&' : '') . $node->name + . '(' . $this->pCommaSeparated($node->params) . ')' + . (null !== $node->returnType ? ' : ' . $this->pType($node->returnType) : '') + . (null !== $node->stmts + ? "\n" . '{' . $this->pStmts($node->stmts) . "\n" . '}' + : ';'); + } + + protected function pStmt_ClassConst(Stmt\ClassConst $node) { + return $this->pModifiers($node->flags) + . 'const ' . $this->pCommaSeparated($node->consts) . ';'; + } + + protected function pStmt_Function(Stmt\Function_ $node) { + return 'function ' . ($node->byRef ? '&' : '') . $node->name + . '(' . $this->pCommaSeparated($node->params) . ')' + . (null !== $node->returnType ? ' : ' . $this->pType($node->returnType) : '') + . "\n" . '{' . $this->pStmts($node->stmts) . "\n" . '}'; + } + + protected function pStmt_Const(Stmt\Const_ $node) { + return 'const ' . $this->pCommaSeparated($node->consts) . ';'; + } + + protected function pStmt_Declare(Stmt\Declare_ $node) { + return 'declare (' . $this->pCommaSeparated($node->declares) . ')' + . (null !== $node->stmts ? ' {' . $this->pStmts($node->stmts) . "\n" . '}' : ';'); + } + + protected function pStmt_DeclareDeclare(Stmt\DeclareDeclare $node) { + return $node->key . '=' . $this->p($node->value); + } + + // Control flow + + protected function pStmt_If(Stmt\If_ $node) { + return 'if (' . $this->p($node->cond) . ') {' + . $this->pStmts($node->stmts) . "\n" . '}' + . $this->pImplode($node->elseifs) + . (null !== $node->else ? $this->p($node->else) : ''); + } + + protected function pStmt_ElseIf(Stmt\ElseIf_ $node) { + return ' elseif (' . $this->p($node->cond) . ') {' + . $this->pStmts($node->stmts) . "\n" . '}'; + } + + protected function pStmt_Else(Stmt\Else_ $node) { + return ' else {' . $this->pStmts($node->stmts) . "\n" . '}'; + } + + protected function pStmt_For(Stmt\For_ $node) { + return 'for (' + . $this->pCommaSeparated($node->init) . ';' . (!empty($node->cond) ? ' ' : '') + . $this->pCommaSeparated($node->cond) . ';' . (!empty($node->loop) ? ' ' : '') + . $this->pCommaSeparated($node->loop) + . ') {' . $this->pStmts($node->stmts) . "\n" . '}'; + } + + protected function pStmt_Foreach(Stmt\Foreach_ $node) { + return 'foreach (' . $this->p($node->expr) . ' as ' + . (null !== $node->keyVar ? $this->p($node->keyVar) . ' => ' : '') + . ($node->byRef ? '&' : '') . $this->p($node->valueVar) . ') {' + . $this->pStmts($node->stmts) . "\n" . '}'; + } + + protected function pStmt_While(Stmt\While_ $node) { + return 'while (' . $this->p($node->cond) . ') {' + . $this->pStmts($node->stmts) . "\n" . '}'; + } + + protected function pStmt_Do(Stmt\Do_ $node) { + return 'do {' . $this->pStmts($node->stmts) . "\n" + . '} while (' . $this->p($node->cond) . ');'; + } + + protected function pStmt_Switch(Stmt\Switch_ $node) { + return 'switch (' . $this->p($node->cond) . ') {' + . $this->pStmts($node->cases) . "\n" . '}'; + } + + protected function pStmt_Case(Stmt\Case_ $node) { + return (null !== $node->cond ? 'case ' . $this->p($node->cond) : 'default') . ':' + . $this->pStmts($node->stmts); + } + + protected function pStmt_TryCatch(Stmt\TryCatch $node) { + return 'try {' . $this->pStmts($node->stmts) . "\n" . '}' + . $this->pImplode($node->catches) + . ($node->finally !== null ? $this->p($node->finally) : ''); + } + + protected function pStmt_Catch(Stmt\Catch_ $node) { + return ' catch (' . $this->pImplode($node->types, '|') . ' $' . $node->var . ') {' + . $this->pStmts($node->stmts) . "\n" . '}'; + } + + protected function pStmt_Finally(Stmt\Finally_ $node) { + return ' finally {' . $this->pStmts($node->stmts) . "\n" . '}'; + } + + protected function pStmt_Break(Stmt\Break_ $node) { + return 'break' . ($node->num !== null ? ' ' . $this->p($node->num) : '') . ';'; + } + + protected function pStmt_Continue(Stmt\Continue_ $node) { + return 'continue' . ($node->num !== null ? ' ' . $this->p($node->num) : '') . ';'; + } + + protected function pStmt_Return(Stmt\Return_ $node) { + return 'return' . (null !== $node->expr ? ' ' . $this->p($node->expr) : '') . ';'; + } + + protected function pStmt_Throw(Stmt\Throw_ $node) { + return 'throw ' . $this->p($node->expr) . ';'; + } + + protected function pStmt_Label(Stmt\Label $node) { + return $node->name . ':'; + } + + protected function pStmt_Goto(Stmt\Goto_ $node) { + return 'goto ' . $node->name . ';'; + } + + // Other + + protected function pStmt_Echo(Stmt\Echo_ $node) { + return 'echo ' . $this->pCommaSeparated($node->exprs) . ';'; + } + + protected function pStmt_Static(Stmt\Static_ $node) { + return 'static ' . $this->pCommaSeparated($node->vars) . ';'; + } + + protected function pStmt_Global(Stmt\Global_ $node) { + return 'global ' . $this->pCommaSeparated($node->vars) . ';'; + } + + protected function pStmt_StaticVar(Stmt\StaticVar $node) { + return '$' . $node->name + . (null !== $node->default ? ' = ' . $this->p($node->default) : ''); + } + + protected function pStmt_Unset(Stmt\Unset_ $node) { + return 'unset(' . $this->pCommaSeparated($node->vars) . ');'; + } + + protected function pStmt_InlineHTML(Stmt\InlineHTML $node) { + $newline = $node->getAttribute('hasLeadingNewline', true) ? "\n" : ''; + return '?>' . $this->pNoIndent($newline . $node->value) . 'remaining; + } + + protected function pStmt_Nop(Stmt\Nop $node) { + return ''; + } + + // Helpers + + protected function pType($node) { + return is_string($node) ? $node : $this->p($node); + } + + protected function pClassCommon(Stmt\Class_ $node, $afterClassToken) { + return $this->pModifiers($node->flags) + . 'class' . $afterClassToken + . (null !== $node->extends ? ' extends ' . $this->p($node->extends) : '') + . (!empty($node->implements) ? ' implements ' . $this->pCommaSeparated($node->implements) : '') + . "\n" . '{' . $this->pStmts($node->stmts) . "\n" . '}'; + } + + protected function pObjectProperty($node) { + if ($node instanceof Expr) { + return '{' . $this->p($node) . '}'; + } else { + return $node; + } + } + + protected function pModifiers($modifiers) { + return ($modifiers & Stmt\Class_::MODIFIER_PUBLIC ? 'public ' : '') + . ($modifiers & Stmt\Class_::MODIFIER_PROTECTED ? 'protected ' : '') + . ($modifiers & Stmt\Class_::MODIFIER_PRIVATE ? 'private ' : '') + . ($modifiers & Stmt\Class_::MODIFIER_STATIC ? 'static ' : '') + . ($modifiers & Stmt\Class_::MODIFIER_ABSTRACT ? 'abstract ' : '') + . ($modifiers & Stmt\Class_::MODIFIER_FINAL ? 'final ' : ''); + } + + protected function pEncapsList(array $encapsList, $quote) { + $return = ''; + foreach ($encapsList as $element) { + if ($element instanceof Scalar\EncapsedStringPart) { + $return .= $this->escapeString($element->value, $quote); + } else { + $return .= '{' . $this->p($element) . '}'; + } + } + + return $return; + } + + protected function escapeString($string, $quote) { + if (null === $quote) { + // For doc strings, don't escape newlines + $escaped = addcslashes($string, "\t\f\v$\\"); + } else { + $escaped = addcslashes($string, "\n\r\t\f\v$" . $quote . "\\"); + } + + // Escape other control characters + return preg_replace_callback('/([\0-\10\16-\37])(?=([0-7]?))/', function ($matches) { + $oct = decoct(ord($matches[1])); + if ($matches[2] !== '') { + // If there is a trailing digit, use the full three character form + return '\\' . str_pad($oct, 3, '0', STR_PAD_LEFT); + } + return '\\' . $oct; + }, $escaped); + } + + protected function containsEndLabel($string, $label, $atStart = true, $atEnd = true) { + $start = $atStart ? '(?:^|[\r\n])' : '[\r\n]'; + $end = $atEnd ? '(?:$|[;\r\n])' : '[;\r\n]'; + return false !== strpos($string, $label) + && preg_match('/' . $start . $label . $end . '/', $string); + } + + protected function encapsedContainsEndLabel(array $parts, $label) { + foreach ($parts as $i => $part) { + $atStart = $i === 0; + $atEnd = $i === count($parts) - 1; + if ($part instanceof Scalar\EncapsedStringPart + && $this->containsEndLabel($part->value, $label, $atStart, $atEnd) + ) { + return true; + } + } + return false; + } + + protected function pDereferenceLhs(Node $node) { + if ($node instanceof Expr\Variable + || $node instanceof Name + || $node instanceof Expr\ArrayDimFetch + || $node instanceof Expr\PropertyFetch + || $node instanceof Expr\StaticPropertyFetch + || $node instanceof Expr\FuncCall + || $node instanceof Expr\MethodCall + || $node instanceof Expr\StaticCall + || $node instanceof Expr\Array_ + || $node instanceof Scalar\String_ + || $node instanceof Expr\ConstFetch + || $node instanceof Expr\ClassConstFetch + ) { + return $this->p($node); + } else { + return '(' . $this->p($node) . ')'; + } + } + + protected function pCallLhs(Node $node) { + if ($node instanceof Name + || $node instanceof Expr\Variable + || $node instanceof Expr\ArrayDimFetch + || $node instanceof Expr\FuncCall + || $node instanceof Expr\MethodCall + || $node instanceof Expr\StaticCall + || $node instanceof Expr\Array_ + ) { + return $this->p($node); + } else { + return '(' . $this->p($node) . ')'; + } + } + + private function hasNodeWithComments(array $nodes) { + foreach ($nodes as $node) { + if ($node && $node->getAttribute('comments')) { + return true; + } + } + return false; + } + + private function pMaybeMultiline(array $nodes, $trailingComma = false) { + if (!$this->hasNodeWithComments($nodes)) { + return $this->pCommaSeparated($nodes); + } else { + return $this->pCommaSeparatedMultiline($nodes, $trailingComma) . "\n"; + } + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/PrettyPrinterAbstract.php b/lib/nikic/php-parser/lib/PhpParser/PrettyPrinterAbstract.php new file mode 100644 index 000000000..24bae5936 --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/PrettyPrinterAbstract.php @@ -0,0 +1,348 @@ + array( 0, 1), + 'Expr_BitwiseNot' => array( 10, 1), + 'Expr_PreInc' => array( 10, 1), + 'Expr_PreDec' => array( 10, 1), + 'Expr_PostInc' => array( 10, -1), + 'Expr_PostDec' => array( 10, -1), + 'Expr_UnaryPlus' => array( 10, 1), + 'Expr_UnaryMinus' => array( 10, 1), + 'Expr_Cast_Int' => array( 10, 1), + 'Expr_Cast_Double' => array( 10, 1), + 'Expr_Cast_String' => array( 10, 1), + 'Expr_Cast_Array' => array( 10, 1), + 'Expr_Cast_Object' => array( 10, 1), + 'Expr_Cast_Bool' => array( 10, 1), + 'Expr_Cast_Unset' => array( 10, 1), + 'Expr_ErrorSuppress' => array( 10, 1), + 'Expr_Instanceof' => array( 20, 0), + 'Expr_BooleanNot' => array( 30, 1), + 'Expr_BinaryOp_Mul' => array( 40, -1), + 'Expr_BinaryOp_Div' => array( 40, -1), + 'Expr_BinaryOp_Mod' => array( 40, -1), + 'Expr_BinaryOp_Plus' => array( 50, -1), + 'Expr_BinaryOp_Minus' => array( 50, -1), + 'Expr_BinaryOp_Concat' => array( 50, -1), + 'Expr_BinaryOp_ShiftLeft' => array( 60, -1), + 'Expr_BinaryOp_ShiftRight' => array( 60, -1), + 'Expr_BinaryOp_Smaller' => array( 70, 0), + 'Expr_BinaryOp_SmallerOrEqual' => array( 70, 0), + 'Expr_BinaryOp_Greater' => array( 70, 0), + 'Expr_BinaryOp_GreaterOrEqual' => array( 70, 0), + 'Expr_BinaryOp_Equal' => array( 80, 0), + 'Expr_BinaryOp_NotEqual' => array( 80, 0), + 'Expr_BinaryOp_Identical' => array( 80, 0), + 'Expr_BinaryOp_NotIdentical' => array( 80, 0), + 'Expr_BinaryOp_Spaceship' => array( 80, 0), + 'Expr_BinaryOp_BitwiseAnd' => array( 90, -1), + 'Expr_BinaryOp_BitwiseXor' => array(100, -1), + 'Expr_BinaryOp_BitwiseOr' => array(110, -1), + 'Expr_BinaryOp_BooleanAnd' => array(120, -1), + 'Expr_BinaryOp_BooleanOr' => array(130, -1), + 'Expr_BinaryOp_Coalesce' => array(140, 1), + 'Expr_Ternary' => array(150, -1), + // parser uses %left for assignments, but they really behave as %right + 'Expr_Assign' => array(160, 1), + 'Expr_AssignRef' => array(160, 1), + 'Expr_AssignOp_Plus' => array(160, 1), + 'Expr_AssignOp_Minus' => array(160, 1), + 'Expr_AssignOp_Mul' => array(160, 1), + 'Expr_AssignOp_Div' => array(160, 1), + 'Expr_AssignOp_Concat' => array(160, 1), + 'Expr_AssignOp_Mod' => array(160, 1), + 'Expr_AssignOp_BitwiseAnd' => array(160, 1), + 'Expr_AssignOp_BitwiseOr' => array(160, 1), + 'Expr_AssignOp_BitwiseXor' => array(160, 1), + 'Expr_AssignOp_ShiftLeft' => array(160, 1), + 'Expr_AssignOp_ShiftRight' => array(160, 1), + 'Expr_AssignOp_Pow' => array(160, 1), + 'Expr_YieldFrom' => array(165, 1), + 'Expr_Print' => array(168, 1), + 'Expr_BinaryOp_LogicalAnd' => array(170, -1), + 'Expr_BinaryOp_LogicalXor' => array(180, -1), + 'Expr_BinaryOp_LogicalOr' => array(190, -1), + 'Expr_Include' => array(200, -1), + ); + + protected $noIndentToken; + protected $docStringEndToken; + protected $canUseSemicolonNamespaces; + protected $options; + + /** + * Creates a pretty printer instance using the given options. + * + * Supported options: + * * bool $shortArraySyntax = false: Whether to use [] instead of array() as the default array + * syntax, if the node does not specify a format. + * + * @param array $options Dictionary of formatting options + */ + public function __construct(array $options = []) { + $this->noIndentToken = '_NO_INDENT_' . mt_rand(); + $this->docStringEndToken = '_DOC_STRING_END_' . mt_rand(); + + $defaultOptions = ['shortArraySyntax' => false]; + $this->options = $options + $defaultOptions; + } + + /** + * Pretty prints an array of statements. + * + * @param Node[] $stmts Array of statements + * + * @return string Pretty printed statements + */ + public function prettyPrint(array $stmts) { + $this->preprocessNodes($stmts); + + return ltrim($this->handleMagicTokens($this->pStmts($stmts, false))); + } + + /** + * Pretty prints an expression. + * + * @param Expr $node Expression node + * + * @return string Pretty printed node + */ + public function prettyPrintExpr(Expr $node) { + return $this->handleMagicTokens($this->p($node)); + } + + /** + * Pretty prints a file of statements (includes the opening prettyPrint($stmts); + + if ($stmts[0] instanceof Stmt\InlineHTML) { + $p = preg_replace('/^<\?php\s+\?>\n?/', '', $p); + } + if ($stmts[count($stmts) - 1] instanceof Stmt\InlineHTML) { + $p = preg_replace('/<\?php$/', '', rtrim($p)); + } + + return $p; + } + + /** + * Preprocesses the top-level nodes to initialize pretty printer state. + * + * @param Node[] $nodes Array of nodes + */ + protected function preprocessNodes(array $nodes) { + /* We can use semicolon-namespaces unless there is a global namespace declaration */ + $this->canUseSemicolonNamespaces = true; + foreach ($nodes as $node) { + if ($node instanceof Stmt\Namespace_ && null === $node->name) { + $this->canUseSemicolonNamespaces = false; + } + } + } + + protected function handleMagicTokens($str) { + // Drop no-indent tokens + $str = str_replace($this->noIndentToken, '', $str); + + // Replace doc-string-end tokens with nothing or a newline + $str = str_replace($this->docStringEndToken . ";\n", ";\n", $str); + $str = str_replace($this->docStringEndToken, "\n", $str); + + return $str; + } + + /** + * Pretty prints an array of nodes (statements) and indents them optionally. + * + * @param Node[] $nodes Array of nodes + * @param bool $indent Whether to indent the printed nodes + * + * @return string Pretty printed statements + */ + protected function pStmts(array $nodes, $indent = true) { + $result = ''; + foreach ($nodes as $node) { + $comments = $node->getAttribute('comments', array()); + if ($comments) { + $result .= "\n" . $this->pComments($comments); + if ($node instanceof Stmt\Nop) { + continue; + } + } + + $result .= "\n" . $this->p($node) . ($node instanceof Expr ? ';' : ''); + } + + if ($indent) { + return preg_replace('~\n(?!$|' . $this->noIndentToken . ')~', "\n ", $result); + } else { + return $result; + } + } + + /** + * Pretty prints a node. + * + * @param Node $node Node to be pretty printed + * + * @return string Pretty printed node + */ + protected function p(Node $node) { + return $this->{'p' . $node->getType()}($node); + } + + protected function pInfixOp($type, Node $leftNode, $operatorString, Node $rightNode) { + list($precedence, $associativity) = $this->precedenceMap[$type]; + + return $this->pPrec($leftNode, $precedence, $associativity, -1) + . $operatorString + . $this->pPrec($rightNode, $precedence, $associativity, 1); + } + + protected function pPrefixOp($type, $operatorString, Node $node) { + list($precedence, $associativity) = $this->precedenceMap[$type]; + return $operatorString . $this->pPrec($node, $precedence, $associativity, 1); + } + + protected function pPostfixOp($type, Node $node, $operatorString) { + list($precedence, $associativity) = $this->precedenceMap[$type]; + return $this->pPrec($node, $precedence, $associativity, -1) . $operatorString; + } + + /** + * Prints an expression node with the least amount of parentheses necessary to preserve the meaning. + * + * @param Node $node Node to pretty print + * @param int $parentPrecedence Precedence of the parent operator + * @param int $parentAssociativity Associativity of parent operator + * (-1 is left, 0 is nonassoc, 1 is right) + * @param int $childPosition Position of the node relative to the operator + * (-1 is left, 1 is right) + * + * @return string The pretty printed node + */ + protected function pPrec(Node $node, $parentPrecedence, $parentAssociativity, $childPosition) { + $type = $node->getType(); + if (isset($this->precedenceMap[$type])) { + $childPrecedence = $this->precedenceMap[$type][0]; + if ($childPrecedence > $parentPrecedence + || ($parentPrecedence == $childPrecedence && $parentAssociativity != $childPosition) + ) { + return '(' . $this->p($node) . ')'; + } + } + + return $this->p($node); + } + + /** + * Pretty prints an array of nodes and implodes the printed values. + * + * @param Node[] $nodes Array of Nodes to be printed + * @param string $glue Character to implode with + * + * @return string Imploded pretty printed nodes + */ + protected function pImplode(array $nodes, $glue = '') { + $pNodes = array(); + foreach ($nodes as $node) { + if (null === $node) { + $pNodes[] = ''; + } else { + $pNodes[] = $this->p($node); + } + } + + return implode($glue, $pNodes); + } + + /** + * Pretty prints an array of nodes and implodes the printed values with commas. + * + * @param Node[] $nodes Array of Nodes to be printed + * + * @return string Comma separated pretty printed nodes + */ + protected function pCommaSeparated(array $nodes) { + return $this->pImplode($nodes, ', '); + } + + /** + * Pretty prints a comma-separated list of nodes in multiline style, including comments. + * + * The result includes a leading newline and one level of indentation (same as pStmts). + * + * @param Node[] $nodes Array of Nodes to be printed + * @param bool $trailingComma Whether to use a trailing comma + * + * @return string Comma separated pretty printed nodes in multiline style + */ + protected function pCommaSeparatedMultiline(array $nodes, $trailingComma) { + $result = ''; + $lastIdx = count($nodes) - 1; + foreach ($nodes as $idx => $node) { + if ($node !== null) { + $comments = $node->getAttribute('comments', array()); + if ($comments) { + $result .= "\n" . $this->pComments($comments); + } + + $result .= "\n" . $this->p($node); + } else { + $result .= "\n"; + } + if ($trailingComma || $idx !== $lastIdx) { + $result .= ','; + } + } + + return preg_replace('~\n(?!$|' . $this->noIndentToken . ')~', "\n ", $result); + } + + /** + * Signals the pretty printer that a string shall not be indented. + * + * @param string $string Not to be indented string + * + * @return string String marked with $this->noIndentToken's. + */ + protected function pNoIndent($string) { + return str_replace("\n", "\n" . $this->noIndentToken, $string); + } + + /** + * Prints reformatted text of the passed comments. + * + * @param Comment[] $comments List of comments + * + * @return string Reformatted text of comments + */ + protected function pComments(array $comments) { + $formattedComments = []; + + foreach ($comments as $comment) { + $formattedComments[] = $comment->getReformattedText(); + } + + return implode("\n", $formattedComments); + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/Serializer.php b/lib/nikic/php-parser/lib/PhpParser/Serializer.php new file mode 100644 index 000000000..1dd790666 --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Serializer.php @@ -0,0 +1,18 @@ +writer = new XMLWriter; + $this->writer->openMemory(); + $this->writer->setIndent(true); + } + + public function serialize(array $nodes) { + $this->writer->flush(); + $this->writer->startDocument('1.0', 'UTF-8'); + + $this->writer->startElement('AST'); + $this->writer->writeAttribute('xmlns:node', 'http://nikic.github.com/PHPParser/XML/node'); + $this->writer->writeAttribute('xmlns:subNode', 'http://nikic.github.com/PHPParser/XML/subNode'); + $this->writer->writeAttribute('xmlns:attribute', 'http://nikic.github.com/PHPParser/XML/attribute'); + $this->writer->writeAttribute('xmlns:scalar', 'http://nikic.github.com/PHPParser/XML/scalar'); + + $this->_serialize($nodes); + + $this->writer->endElement(); + + return $this->writer->outputMemory(); + } + + protected function _serialize($node) { + if ($node instanceof Node) { + $this->writer->startElement('node:' . $node->getType()); + + foreach ($node->getAttributes() as $name => $value) { + $this->writer->startElement('attribute:' . $name); + $this->_serialize($value); + $this->writer->endElement(); + } + + foreach ($node as $name => $subNode) { + $this->writer->startElement('subNode:' . $name); + $this->_serialize($subNode); + $this->writer->endElement(); + } + + $this->writer->endElement(); + } elseif ($node instanceof Comment) { + $this->writer->startElement('comment'); + $this->writer->writeAttribute('isDocComment', $node instanceof Comment\Doc ? 'true' : 'false'); + $this->writer->writeAttribute('line', (string) $node->getLine()); + $this->writer->text($node->getText()); + $this->writer->endElement(); + } elseif (is_array($node)) { + $this->writer->startElement('scalar:array'); + foreach ($node as $subNode) { + $this->_serialize($subNode); + } + $this->writer->endElement(); + } elseif (is_string($node)) { + $this->writer->writeElement('scalar:string', $node); + } elseif (is_int($node)) { + $this->writer->writeElement('scalar:int', (string) $node); + } elseif (is_float($node)) { + // TODO Higher precision conversion? + $this->writer->writeElement('scalar:float', (string) $node); + } elseif (true === $node) { + $this->writer->writeElement('scalar:true'); + } elseif (false === $node) { + $this->writer->writeElement('scalar:false'); + } elseif (null === $node) { + $this->writer->writeElement('scalar:null'); + } else { + throw new \InvalidArgumentException('Unexpected node type'); + } + } +} diff --git a/lib/nikic/php-parser/lib/PhpParser/Unserializer.php b/lib/nikic/php-parser/lib/PhpParser/Unserializer.php new file mode 100644 index 000000000..9c221a141 --- /dev/null +++ b/lib/nikic/php-parser/lib/PhpParser/Unserializer.php @@ -0,0 +1,18 @@ +reader = new XMLReader; + } + + public function unserialize($string) { + $this->reader->XML($string); + + $this->reader->read(); + if ('AST' !== $this->reader->name) { + throw new DomainException('AST root element not found'); + } + + return $this->read($this->reader->depth); + } + + protected function read($depthLimit, $throw = true, &$nodeFound = null) { + $nodeFound = true; + while ($this->reader->read() && $depthLimit < $this->reader->depth) { + if (XMLReader::ELEMENT !== $this->reader->nodeType) { + continue; + } + + if ('node' === $this->reader->prefix) { + return $this->readNode(); + } elseif ('scalar' === $this->reader->prefix) { + return $this->readScalar(); + } elseif ('comment' === $this->reader->name) { + return $this->readComment(); + } else { + throw new DomainException(sprintf('Unexpected node of type "%s"', $this->reader->name)); + } + } + + $nodeFound = false; + if ($throw) { + throw new DomainException('Expected node or scalar'); + } + } + + protected function readNode() { + $className = $this->getClassNameFromType($this->reader->localName); + + // create the node without calling it's constructor + $node = unserialize( + sprintf( + "O:%d:\"%s\":1:{s:13:\"\0*\0attributes\";a:0:{}}", + strlen($className), $className + ) + ); + + $depthLimit = $this->reader->depth; + while ($this->reader->read() && $depthLimit < $this->reader->depth) { + if (XMLReader::ELEMENT !== $this->reader->nodeType) { + continue; + } + + $type = $this->reader->prefix; + if ('subNode' !== $type && 'attribute' !== $type) { + throw new DomainException( + sprintf('Expected sub node or attribute, got node of type "%s"', $this->reader->name) + ); + } + + $name = $this->reader->localName; + $value = $this->read($this->reader->depth); + + if ('subNode' === $type) { + $node->$name = $value; + } else { + $node->setAttribute($name, $value); + } + } + + return $node; + } + + protected function readScalar() { + switch ($name = $this->reader->localName) { + case 'array': + $depth = $this->reader->depth; + $array = array(); + while (true) { + $node = $this->read($depth, false, $nodeFound); + if (!$nodeFound) { + break; + } + $array[] = $node; + } + return $array; + case 'string': + return $this->reader->readString(); + case 'int': + return $this->parseInt($this->reader->readString()); + case 'float': + $text = $this->reader->readString(); + if (false === $float = filter_var($text, FILTER_VALIDATE_FLOAT)) { + throw new DomainException(sprintf('"%s" is not a valid float', $text)); + } + return $float; + case 'true': + case 'false': + case 'null': + if (!$this->reader->isEmptyElement) { + throw new DomainException(sprintf('"%s" scalar must be empty', $name)); + } + return constant($name); + default: + throw new DomainException(sprintf('Unknown scalar type "%s"', $name)); + } + } + + private function parseInt($text) { + if (false === $int = filter_var($text, FILTER_VALIDATE_INT)) { + throw new DomainException(sprintf('"%s" is not a valid integer', $text)); + } + return $int; + } + + protected function readComment() { + $className = $this->reader->getAttribute('isDocComment') === 'true' + ? 'PhpParser\Comment\Doc' + : 'PhpParser\Comment' + ; + return new $className( + $this->reader->readString(), + $this->parseInt($this->reader->getAttribute('line')) + ); + } + + protected function getClassNameFromType($type) { + $className = 'PhpParser\\Node\\' . strtr($type, '_', '\\'); + if (!class_exists($className)) { + $className .= '_'; + } + if (!class_exists($className)) { + throw new DomainException(sprintf('Unknown node type "%s"', $type)); + } + return $className; + } +} diff --git a/lib/nikic/php-parser/lib/bootstrap.php b/lib/nikic/php-parser/lib/bootstrap.php new file mode 100644 index 000000000..b0f517822 --- /dev/null +++ b/lib/nikic/php-parser/lib/bootstrap.php @@ -0,0 +1,6 @@ + + + + + + ./test/ + + + + + + ./lib/PhpParser/ + + + diff --git a/lib/nikic/php-parser/test_old/run-php-src.sh b/lib/nikic/php-parser/test_old/run-php-src.sh new file mode 100755 index 000000000..0d37f851d --- /dev/null +++ b/lib/nikic/php-parser/test_old/run-php-src.sh @@ -0,0 +1,4 @@ +wget -q https://github.com/php/php-src/archive/php-7.1.0.tar.gz +mkdir -p ./data/php-src +tar -xzf ./php-7.1.0.tar.gz -C ./data/php-src --strip-components=1 +php -n test_old/run.php --verbose --no-progress PHP7 ./data/php-src diff --git a/lib/nikic/php-parser/test_old/run.php b/lib/nikic/php-parser/test_old/run.php new file mode 100644 index 000000000..bc14d893a --- /dev/null +++ b/lib/nikic/php-parser/test_old/run.php @@ -0,0 +1,220 @@ +parse($code); + $parseTime += microtime(true) - $startTime; + + $startTime = microtime(true); + $code = 'prettyPrint($stmts); + $ppTime += microtime(true) - $startTime; + + try { + $startTime = microtime(true); + $ppStmts = $parser->parse($code); + $reparseTime += microtime(true) - $startTime; + + $startTime = microtime(true); + $same = $nodeDumper->dump($stmts) == $nodeDumper->dump($ppStmts); + $compareTime += microtime(true) - $startTime; + + if (!$same) { + echo $file, ":\n Result of initial parse and parse after pretty print differ\n"; + if ($verbose) { + echo "Pretty printer output:\n=====\n$code\n=====\n\n"; + } + + ++$compareFail; + } + } catch (PhpParser\Error $e) { + echo $file, ":\n Parse of pretty print failed with message: {$e->getMessage()}\n"; + if ($verbose) { + echo "Pretty printer output:\n=====\n$code\n=====\n\n"; + } + + ++$ppFail; + } + } catch (PhpParser\Error $e) { + echo $file, ":\n Parse failed with message: {$e->getMessage()}\n"; + + ++$parseFail; + } +} + +if (0 === $parseFail && 0 === $ppFail && 0 === $compareFail) { + $exit = 0; + echo "\n\n", 'All tests passed.', "\n"; +} else { + $exit = 1; + echo "\n\n", '==========', "\n\n", 'There were: ', "\n"; + if (0 !== $parseFail) { + echo ' ', $parseFail, ' parse failures.', "\n"; + } + if (0 !== $ppFail) { + echo ' ', $ppFail, ' pretty print failures.', "\n"; + } + if (0 !== $compareFail) { + echo ' ', $compareFail, ' compare failures.', "\n"; + } +} + +echo "\n", + 'Tested files: ', $count, "\n", + "\n", + 'Reading files took: ', $readTime, "\n", + 'Parsing took: ', $parseTime, "\n", + 'Pretty printing took: ', $ppTime, "\n", + 'Reparsing took: ', $reparseTime, "\n", + 'Comparing took: ', $compareTime, "\n", + "\n", + 'Total time: ', microtime(true) - $totalStartTime, "\n", + 'Maximum memory usage: ', memory_get_peak_usage(true), "\n"; + +exit($exit); diff --git a/test/core/iTopConfigParserTest.php b/test/core/iTopConfigParserTest.php new file mode 100644 index 000000000..ea13d6167 --- /dev/null +++ b/test/core/iTopConfigParserTest.php @@ -0,0 +1,179 @@ +assertEquals($aExpectedVarsMap, $oITopConfigParser->GetVarsMap()); + + } + + public function ParserProvider() + { + + return array( + "test MySettings" => array( + 'sInitialConfig' => ' $a + );', + 'aExpectedVarsMap' => array( + 'MySettings' => array('b' => '$a'), + 'MyModuleSettings' => array(), + 'MyModules' => array(), + ) + ), + + "test MyModuleSettings" => array( + 'sInitialConfig' => ' $a + );', + 'aExpectedVarsMap' => array( + 'MySettings' => array(), + 'MyModuleSettings' => array('b' => '$a'), + 'MyModules' => array(), + ) + ), + + + "test MyModules" => array( + 'sInitialConfig' => ' $a + );', + 'aExpectedVarsMap' => array( + 'MySettings' =>array(), + 'MyModuleSettings' => array(), + 'MyModules' => array('b' => '$a'), + ) + ), + + "test MyModules + MyModuleSettings " => array( + 'sInitialConfig' => ' $a + ); + $MyModuleSettings = array( + "e" => $d + );', + 'aExpectedVarsMap' => array( + 'MySettings' =>array(), + 'MyModuleSettings' => array('e' => '$d'), + 'MyModules' => array('b' => '$a'), + ) + ), + + "test preserve gloabl + concatenation" => array( + 'sInitialConfig' => ' $_SERVER["REQUEST_URI"] . "/toto" + );', + 'aExpectedVarsMap' => array( + 'MySettings' =>array(), + 'MyModuleSettings' => array(), + 'MyModules' => array('b' => '$_SERVER["REQUEST_URI"] . "/toto"'), + ) + ), + "test MyModules array of arrays" => array( + 'sInitialConfig' => ' array ( + "default" => + array ( + "date" => "Y-m-d", + "time" => "H:i:s", + "date_time" => "$date $time", + ), + ), + );', + 'aExpectedVarsMap' => array( + 'MySettings' =>array(), + 'MyModuleSettings' => array(), + 'MyModules' => array( + 'date_and_time_format' => 'array("default" => array("date" => "Y-m-d", "time" => "H:i:s", "date_time" => "{$date} {$time}"))' + ), + ) + ), + ); + } + + /** + * @doesNotPerformAssertions + * + * @throws \ConfigException + * @throws \CoreException + */ + public function testConfigWriteToFile() + { + exec("rm -f /tmp/config-itop*"); + $tmpConfigFileBeforePath = tempnam( '/tmp/', 'config-itop'); + $tmpConfigFileAfterPath = tempnam( '/tmp/', 'config-itop'); + + //create new config file + $sConfigFile = utils::GetConfig()->GetLoadedFile(); + utils::GetConfig()->WriteToFile($tmpConfigFileBeforePath); + + //add few dynamic configurations in MySettings section + $tmpConfigContentBefore = file_get_contents($tmpConfigFileBeforePath); + $expected_line = <<< CONF + 'app_root_url' => 'http://\$_SERVER[\\'SERVER_NAME\\']/iTop/', +CONF; + //add few dynamic configurations in MyModuleSettings section + $tmpConfigNewContentBefore = preg_replace('/.*\'app_root_url.*,/', $expected_line, $tmpConfigContentBefore); + $expected_line = <<< CONF + \$MyModuleSettings = array( + 'shadok_module' => array ('gabu' => '\$_SERVER[\\'ZOMEU\\']'), +CONF; + $tmpConfigNewContentBefore = preg_replace('/\$MyModuleSettings = array\(/', $expected_line, $tmpConfigNewContentBefore); + + //add few dynamic configurations in MyModules section + $expected_line = <<< CONF + 'addons' => array( + 'user rights' => 'addons/userrights/userrightsprofile.class.inc.php', + 'user rights2' => '\$_SERVER[\\'TEST\\']' + ), +CONF; + $tmpConfigNewContentBefore = preg_replace('/.*\'addons.*/', $expected_line, $tmpConfigNewContentBefore); + + unlink($tmpConfigFileBeforePath); + fwrite(fopen($tmpConfigFileBeforePath, 'w'), $tmpConfigNewContentBefore); + + //write same content again + $config = new Config($tmpConfigFileBeforePath, true); + $config->WriteToFile($tmpConfigFileAfterPath); + + //compare + $tmpConfigContentBefore = file_get_contents($tmpConfigFileAfterPath); + $tmpConfigContentAfter = file_get_contents($tmpConfigFileAfterPath); + unlink($tmpConfigFileAfterPath); + unlink($tmpConfigFileBeforePath); + $this->assertEquals($tmpConfigContentBefore, $tmpConfigContentAfter); + } +}