/* +----------------------------------------------------------------------+ | HipHop for PHP | +----------------------------------------------------------------------+ | Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | | available through the world-wide-web at the following url: | | http://www.php.net/license/3_01.txt | | If you did not receive a copy of the PHP license and are unable to | | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ */ #include "hphp/test/ext/test_parser_expr.h" #include "hphp/compiler/option.h" #include "hphp/util/parser/scanner.h" /////////////////////////////////////////////////////////////////////////////// bool TestParserExpr::RunTests(const std::string &which) { bool ret = true; RUN_TEST(TestExpressionList); RUN_TEST(TestAssignmentExpression); RUN_TEST(TestSimpleVariable); RUN_TEST(TestDynamicVariable); RUN_TEST(TestStaticMemberExpression); RUN_TEST(TestArrayElementExpression); RUN_TEST(TestStringOffsetExpression); RUN_TEST(TestDynamicFunctionCall); RUN_TEST(TestSimpleFunctionCall); RUN_TEST(TestScalarExpression); RUN_TEST(TestObjectPropertyExpression); RUN_TEST(TestObjectMethodExpression); RUN_TEST(TestListAssignment); RUN_TEST(TestNewObjectExpression); RUN_TEST(TestUnaryOpExpression); RUN_TEST(TestBinaryOpExpression); RUN_TEST(TestQOpExpression); RUN_TEST(TestArrayPairExpression); RUN_TEST(TestClassConstantExpression); RUN_TEST(TestParameterExpression); RUN_TEST(TestModifierExpression); RUN_TEST(TestConstant); RUN_TEST(TestEncapsListExpression); RUN_TEST(TestClosure); RUN_TEST(TestXHP); return ret; } /////////////////////////////////////////////////////////////////////////////// bool TestParserExpr::TestExpressionList() { // TestUnsetStatement // TestEchoStatement // TestForStatement // TestObjectPropertyExpression // TestListAssignment // TestUnaryOpExpression - internal_functions - isset_variables return true; } bool TestParserExpr::TestAssignmentExpression() { V("c();", "$a = &new $b->c();\n"); V("c->d();", "$a = &new $b->c->d();\n"); return true; } bool TestParserExpr::TestSimpleVariable() { V("c;", "print $b->c;\n"); V("c;", "print ${b}->c;\n"); V("c;", "print ${$b}->c;\n"); V("c;", "print $b[]->c;\n"); V("c;", "print $b[$a]->c;\n"); V("c;", "print $b[$a]->c;\n"); V("c;", "print $b[$a][]->c;\n"); V("c;", "print $b[$a][$c]->c;\n"); V("c;", "print $b[$a][$c][$d]->c;\n"); V("c[];", "print $b[$a][$c][$d]->c[];\n"); V("c[$e];", "print $b[$a][$c][$d]->c[$e];\n"); V("c{$e};", "print $b[$a][$c][$d]->c[$e];\n"); V("c{$e}->f;", "print $b[$a][$c][$d]->c[$e]->f;\n"); V("c{$e}->f[];", "print $b[$a][$c][$d]->c[$e]->f[];\n"); return true; } bool TestParserExpr::TestObjectMethodExpression() { V("c();", "echo $b->c();\n"); V("c();", "echo ${b}->c();\n"); V("c();", "echo ${$b}->c();\n"); V("c();", "echo $b[]->c();\n"); V("c();", "echo $b[$a]->c();\n"); V("c();", "echo $b[$a]->c();\n"); V("c();", "echo $b[$a][]->c();\n"); V("c();", "echo $b[$a][$c]->c();\n"); V("c();", "echo $b[$a][$c][$d]->c();\n"); V("c[]();", "echo $b[$a][$c][$d]->c[]();\n"); V("c[$e]();", "echo $b[$a][$c][$d]->c[$e]();\n"); V("c{$e}();", "echo $b[$a][$c][$d]->c[$e]();\n"); V("c{$e}->f();", "echo $b[$a][$c][$d]->c[$e]->f();\n"); V("c{$e}->f[]();", "echo $b[$a][$c][$d]->c[$e]->f[]();\n"); V("c{$e}($p3,$p4)->f[]($p5,$p6);", "$b[$a][$c][$d]($p1, $p2)->c[$e]($p3, $p4)->f[]($p5, $p6);\n"); return true; } bool TestParserExpr::TestListAssignment() { V(">= A;", "$a >>= A;\n"); V("> A;", "$a >> A;\n"); V(" A;", "$a > A;\n"); V("= A;", "$a >= A;\n"); V(" $b);", "array($a => $b);\n"); V(" $b, $c => $d);", "array($a => $b, $c => $d);\n"); V(" $b, $c => $d,);", "array($a => $b, $c => $d);\n"); V(" &$b);", "array($a => &$b);\n"); V(" &$b, $c => &$d);", "array($a => &$b, $c => &$d);\n"); V(" b);}", "function a() {\nstatic $a = array(a => b);\n}\n"); V(" b, c => d);}", "function a() {\nstatic $a = array(a => b, c => d);\n}\n"); V(" b, c => d,);}", "function a() {\nstatic $a = array(a => b, c => d);\n}\n"); return true; } bool TestParserExpr::TestClassConstantExpression() { V("\\b$/\";", "'->'.\"\\\\\".'b$/';\n"); V(";", "$x = new xhp_thing(array(), array());\n"); // white spaces V(" a{ 'b' }c ;", "$x = new xhp_x(array(), array(' a', 'b', 'c '));\n"); V(" a { 'b' } c ;", "$x = new xhp_x(array(), array(' a ', 'b', ' c '));\n"); V("\n foo\n ;", "$x = new xhp_x(array(), array(' foo '));\n"); V("\n foo\n bar\n ;", "$x = new xhp_x(array(), array(' foo bar '));\n"); // attributes V(";", "$x = new xhp_x__y(array('attr' => xhp_tag::CONSTANT), array());\n"); V("c;", "$x = new xhp_a(array('b' => '\xC2\xA0'), array('c'));\n"); V(";", "$x = new xhp_a(array('b' => ''), array());\n"); // children V(" {'a'} ;", "$x = new xhp_x(array(), array(new xhp_x(array(), array()), 'a'));\n"); V(" {'a'};", "$x = new xhp_x(array(), array('a', new xhp_x(array(), array())));"); V("\n\n.\n;", "$x = new xhp_x(array(), array(new xhp_x(array(), array()), '. '));\n"); V("=;", "new xhp_div(array(), array(new xhp_a(array(), array()), '=', " "new xhp_a(array(), array())));\n"); // closing tag V("hi;", "$x = new xhp_a(array(), array(new xhp_a(array(), " "array(new xhp_a(array(), array('hi'))))));\n"); // class name with PHP keyword V(" array(5, 'Thing', null, 0), " "'b' => array(5, 'Thing', null, 0)));\n" "}\n" "return $_;\n" "}\n" "}\n"); // enum attributes V(" array(7, array(123, 456), null, 0)));\n" "}\n" "return $_;\n" "}\n" "}\n"); // base attributes V(" array(1, null, null, 0)));\n" "}\n" "return $_;\n" "}\n" "}\n" "class xhp_bar {\n" "protected static function &__xhpAttributeDeclaration() {\n" "static $_ = -1;\n" "if ($_ === -1) {\n" "$_ = array_merge(parent::__xhpAttributeDeclaration(), " "xhp_foo::__xhpAttributeDeclaration(), " "xhp_foo::__xhpAttributeDeclaration(), " "array('bar' => array(1, null, null, 0)));\n" "}\n" "return $_;\n" "}\n" "}\n"); // attribute default and required V(" array(3, null, 123, 1), 'b' => array(6, null, null, 0)));\n" "}\n" "return $_;\n" "}\n" "}\n"); // categories V(" 1, 'b' => 1);\n" "return $_;\n" "}\n" "}\n"); // children V(" 1, 'b' => 1);\n" "return $_;\n" "}\n" "protected function &__xhpChildrenDeclaration() {\n" "static $_ = 1;\n" "return $_;\n" "}\n" "}\n"); // multiple interleaved V(" 1);\n" "return $_;\n" "}\n" "protected function &__xhpChildrenDeclaration() {\n" "static $_ = 1;\n" "return $_;\n" "}\n" "public function foo() {\n" "}\n" "public function bar() {\n" "}\n" "protected static function &__xhpAttributeDeclaration() {\n" "static $_ = -1;\n" "if ($_ === -1) {\n" "$_ = array_merge(parent::__xhpAttributeDeclaration(), " "array('a' => array(5, 'Thing', null, 0), " "'b' => array(5, 'Thing', null, 0)));\n" "}\n" "return $_;\n" "}\n" "}\n"); return true; }