move trait alias modifier validation to parser ...
[hiphop-php.git] / hphp / test / ext / test_code_error.cpp
blobd6a6cb7601f4b59f14c39a29f8da850be20b112e
1 /*
2 +----------------------------------------------------------------------+
3 | HipHop for PHP |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 3.01 of the PHP license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.php.net/license/3_01.txt |
11 | If you did not receive a copy of the PHP license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@php.net so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
17 #include "hphp/test/ext/test_code_error.h"
18 #include "hphp/compiler/parser/parser.h"
19 #include "hphp/compiler/builtin_symbols.h"
20 #include "hphp/compiler/analysis/analysis_result.h"
21 #include "hphp/compiler/code_generator.h"
22 #include "hphp/compiler/option.h"
24 ///////////////////////////////////////////////////////////////////////////////
26 TestCodeError::TestCodeError() {
27 Option::IncludeRoots["$_SERVER['PHP_ROOT']"] = "";
30 bool TestCodeError::RunTests(const std::string &which) {
31 bool ret = true;
32 #define CODE_ERROR_ENTRY(x) RUN_TEST(Test ## x);
33 #include "hphp/compiler/analysis/core_code_error.inc"
34 #undef CODE_ERROR_ENTRY
35 return ret;
38 bool TestCodeError::Verify(Compiler::ErrorType type, const char *src,
39 const char *file, int line, bool exists) {
40 WithOpt w0(Option::RecordErrors);
41 WithOpt w1(Option::WholeProgram);
42 WithOpt w2(Option::ParseTimeOpts);
44 Compiler::ClearErrors();
46 Type::ResetTypeHintTypes();
47 Type::InitTypeHintMap();
48 BuiltinSymbols::LoadSuperGlobals();
50 AnalysisResultPtr ar(new AnalysisResult());
51 // for TestPHPIncludeFileNotInLib
52 Compiler::Parser::ParseString("<?php ", ar, "f2");
53 Compiler::Parser::ParseString(src, ar, "f1");
54 BuiltinSymbols::Load(ar);
55 ar->analyzeProgram();
56 ar->inferTypes();
57 ar->analyzeProgramFinal();
58 if (Compiler::HasError(type) != exists) {
59 std::ostringstream error;
60 JSON::CodeError::OutputStream out(error, ar);
61 Compiler::SaveErrors(out);
62 printf("%s:%d: parsing %s\ncode error missing\n%s\n", file, line, src,
63 error.str().c_str());
64 return false;
66 return true;
69 ///////////////////////////////////////////////////////////////////////////////
71 bool TestCodeError::TestBadPHPIncludeFile() {
72 VE(BadPHPIncludeFile, "<?php include 'f1';");
73 return true;
76 bool TestCodeError::TestPHPIncludeFileNotFound() {
77 VE(PHPIncludeFileNotFound, "<?php include $_SERVER['PHP_ROOT'].'a.php';");
78 VEN(PHPIncludeFileNotFound, "<?php include_once $template_path;");
79 return true;
82 bool TestCodeError::TestUseEvaluation() {
83 VE(UseEvaluation, "<?php eval('a');");
84 return true;
87 bool TestCodeError::TestUseUndeclaredVariable() {
88 VE(UseUndeclaredVariable, "<?php $a = 1; function t() { print $a;}");
90 Removing for now. We dont warn about non-static properties.
92 VE(UseUndeclaredVariable,
93 "<?php class T {} function t() { $a = new T(); print $a->a; }");
95 VE(UseUndeclaredVariable,
96 "<?php class A { public $a = 123; } print A::$a;");
98 return true;
101 bool TestCodeError::TestUseUndeclaredGlobalVariable() {
102 VE(UseUndeclaredGlobalVariable, "<?php print $a;");
103 VE(UseUndeclaredGlobalVariable, "<?php print $GLOBALS['a'];");
104 return true;
107 bool TestCodeError::TestUseUndeclaredConstant() {
108 VE(UseUndeclaredConstant, "<?php print a;");
109 VE(UseUndeclaredConstant, "<?php class T {} print T::a;");
110 return true;
113 bool TestCodeError::TestUnknownClass() {
114 VE(UnknownClass, "<?php $a = new T();");
116 VEN(UnknownClass, "<?php class A { function foo(self $a) {}}");
117 VEN(UnknownClass,
118 "<?php "
119 "trait A {"
120 " function foo($f) {"
121 " echo self::FOO+parent::FOO;"
122 " echo self::$f()+parent::$f();"
123 " var_dump(new self, new parent);"
124 " echo self::bar()+parent::bar();"
125 " echo self::$foo+parent::$foo;"
126 " try {} catch (self $p) {}"
127 " try {} catch (parent $p) {}"
128 " }"
129 "}");
130 return true;
133 bool TestCodeError::TestUnknownBaseClass() {
134 VE(UnknownBaseClass, "<?php class T extends R {}");
135 return true;
138 bool TestCodeError::TestUnknownObjectMethod() {
139 VE(UnknownObjectMethod,
140 "<?php class T {} "
141 "function test() { $a = new T(); print $a->a(); }");
143 // negatve cases
144 VEN(UnknownObjectMethod,
145 "<?php class T { function __call($name, $args) {} } "
146 "function t() { $a = new T(); print $a->a(); }");
147 VEN(UnknownObjectMethod,
148 "<?php class T { function __call($name, $args) {}} class R extends T {} "
149 "function test(R $a) { print $a->a();}");
150 return true;
153 bool TestCodeError::TestInvalidMagicMethod() {
154 VE(InvalidMagicMethod, "<?php class T { function __tostring($a) {}}");
155 return true;
158 bool TestCodeError::TestUnknownFunction() {
159 VE(UnknownFunction, "<?php test();");
160 return true;
163 bool TestCodeError::TestBadConstructorCall() {
164 VE(BadConstructorCall, "<?php class T {} $a = new T(1);");
166 // negative cases
167 VEN(BadConstructorCall,
168 "<?php class B { function __construct($a) {}} "
169 "class A extends B {} $a = new A(1);");
171 return true;
174 bool TestCodeError::TestDeclaredVariableTwice() {
175 VE(DeclaredVariableTwice, "<?php class T { var $a; var $a;}");
176 VE(DeclaredVariableTwice, "<?php class T { var $a = 1; var $a;}");
177 VE(DeclaredVariableTwice, "<?php class T { var $a; var $a = 1;}");
178 VE(DeclaredVariableTwice, "<?php class T { var $a = 1; var $a = 2;}");
179 VE(DeclaredVariableTwice, "<?php class T { static $a; static $a;}");
180 VE(DeclaredVariableTwice, "<?php class T { static $a = 1; static $a;}");
181 VE(DeclaredVariableTwice, "<?php class T { static $a; static $a = 1;}");
182 VE(DeclaredVariableTwice, "<?php class T { static $a = 1; static $a = 2;}");
183 VE(DeclaredVariableTwice, "<?php class T { var $a; static $a;}");
184 VE(DeclaredVariableTwice, "<?php class T { static $a; var $a;}");
185 VE(DeclaredVariableTwice, "<?php class T { var $a = 1; static $a;}");
186 VE(DeclaredVariableTwice, "<?php class T { var $a; static $a = 1;}");
187 VE(DeclaredVariableTwice, "<?php class T { var $a = 1; static $a = 2;}");
188 return true;
191 bool TestCodeError::TestDeclaredConstantTwice() {
192 VE(DeclaredConstantTwice, "<?php define('t', 1); define('t', 2);");
193 VE(DeclaredConstantTwice, "<?php class T { const A = 1; const A = 1;}");
194 return true;
197 bool TestCodeError::TestDeclaredMethodTwice() {
198 VE(DeclaredMethodTwice, "<?php class T { function foo(){} function foo(){}}");
199 return true;
202 bool TestCodeError::TestDeclaredAttributeTwice() {
203 WithOpt w0(Option::EnableHipHopSyntax);
205 VE(DeclaredAttributeTwice, "<?php << Foo, Foo >> class C {}");
206 VE(DeclaredAttributeTwice, "<?php << Foo, Foo >> function f() {}");
207 return true;
210 bool TestCodeError::TestBadDefine() {
211 VE(BadDefine, "<?php define($a, 1);");
212 return true;
215 bool TestCodeError::TestRequiredAfterOptionalParam() {
216 VE(RequiredAfterOptionalParam, "<?php function t($a = 1, $b) {}");
217 return true;
220 bool TestCodeError::TestRedundantParameter() {
221 VE(RedundantParameter, "<?php function t($a, $a) {}");
222 return true;
225 bool TestCodeError::TestTooFewArgument() {
226 VE(TooFewArgument, "<?php function test($a) {} test();");
227 VE(TooFewArgument, "<?php function test($a, $b) {} test(1);");
228 VE(TooFewArgument,
229 "<?php class T { function t($a) {}} $a = new T(); $a->t();");
230 VE(TooFewArgument,
231 "<?php class T { function t($a, $b) {}} $a = new T(); $a->t(1);");
232 VE(TooFewArgument,
233 "<?php class T { function __construct($a) {}} $a = new T();");
234 VE(TooFewArgument,
235 "<?php class T { function __construct($a, $b) {}} $a = new T(1);");
236 return true;
239 bool TestCodeError::TestTooManyArgument() {
240 VE(TooManyArgument, "<?php function test() {} test(1);");
241 VE(TooManyArgument,
242 "<?php class A { function t() {}} "
243 "function test() { $a = new A(); $a->t(1);}");
244 VE(TooManyArgument,
245 "<?php class T { function __construct($b) {}} $a = new T(1, 2);");
247 // negative cases
248 VEN(TooManyArgument,
249 "<?php function t() {} function t($a) {} t($a);");
250 return true;
253 bool TestCodeError::TestStatementHasNoEffect() {
254 VE(StatementHasNoEffect, "<?php $a;");
255 VE(StatementHasNoEffect, "<?php $a + $b;");
256 VE(StatementHasNoEffect, "<?php 'test';");
257 VE(StatementHasNoEffect, "<?php -$a;");
258 return true;
261 bool TestCodeError::TestUseVoidReturn() {
262 VE(UseVoidReturn, "<?php function test() {} $a = test();");
263 return true;
266 bool TestCodeError::TestMissingObjectContext() {
267 VE(MissingObjectContext,
268 "<?php class A { public $a = 123; "
269 "public static function test() { print $this->a;}} A::test();");
271 VE(MissingObjectContext,
272 "<?php class A { public function a() { } "
273 "public static function test() { $this->a();}} A::test();");
275 // negative case
276 VEN(MissingObjectContext,
277 "<?php class A { public function a() {} } "
278 "class B extends A { public function b() { A::a();}}");
280 VEN(MissingObjectContext,
281 "<?php class A { public function a() {} } print A::a();");
283 VEN(MissingObjectContext,
284 "<?php class A { public function a() {} } "
285 "class B { public function b() { A::a();}}");
287 return true;
290 bool TestCodeError::TestMoreThanOneDefault() {
291 VE(MoreThanOneDefault, "<?php switch ($a) { default: default: }");
292 return true;
295 bool TestCodeError::TestInvalidArrayElement() {
296 VE(InvalidArrayElement, "<?php if (isset($obj[])) var_dump($obj);");
297 return true;
300 bool TestCodeError::TestInvalidDerivation() {
301 VE(InvalidDerivation,
302 "<?php "
303 "interface RecurisiveFooFar extends RecurisiveFooFar {}");
304 VE(InvalidDerivation,
305 "<?php "
306 "class RecurisiveFooFar extends RecurisiveFooFar {}");
307 VE(InvalidDerivation,
308 "<?php "
309 "interface a extends b {}"
310 "interface b extends a {}");
311 VE(InvalidDerivation,
312 "<?php "
313 "interface a extends B {}"
314 "interface b extends a {}");
315 VE(InvalidDerivation,
316 "<?php "
317 "interface a extends b {}"
318 "interface B extends a {}");
319 VE(InvalidDerivation,
320 "<?php "
321 "interface a extends b {}"
322 "interface b extends A {}");
323 VE(InvalidDerivation,
324 "<?php "
325 "interface A extends B {}"
326 "interface b extends a {}");
327 VE(InvalidDerivation,
328 "<?php "
329 "interface a extends B {}"
330 "interface B extends a {}");
331 VE(InvalidDerivation,
332 "<?php "
333 "interface a extends b {}"
334 "interface B extends A {}");
335 VE(InvalidDerivation,
336 "<?php "
337 "interface A extends B {}"
338 "interface B extends a {}");
339 VE(InvalidDerivation,
340 "<?php "
341 "interface a extends B {}"
342 "interface B extends A {}");
343 VE(InvalidDerivation,
344 "<?php "
345 "class a extends b {}"
346 "class B extends A {}");
347 VE(InvalidDerivation,
348 "<?php "
349 "interface a extends b {}"
350 "class B extends A {}");
351 VE(InvalidDerivation, "<?php interface A {} class T implements A, A {}");
352 VE(InvalidDerivation, "<?php class A {} class B implements A {}");
353 VE(InvalidDerivation, "<?php class A {} interface B extends A {}");
354 VEN(InvalidDerivation,
355 "<?php "
356 "class A {} "
357 "interface B {} "
358 "class C extends A implements B {}");
359 VE(InvalidDerivation, "<?php interface I {} class C extends I {}");
361 return true;
364 bool TestCodeError::TestInvalidOverride() {
365 VE(InvalidOverride,
366 "<?php class A { protected $x; } class B extends A { private $x; }");
368 VE(InvalidOverride,
369 "<?php class A { public $x; } class B extends A { private $x; }");
371 VE(InvalidOverride,
372 "<?php class A { public $x; } class B extends A { protected $x; }");
374 return true;
377 bool TestCodeError::TestMissingAbstractMethodImpl() {
378 VE(MissingAbstractMethodImpl,
379 "<?php "
380 "abstract class A {"
381 " abstract function foo();"
383 "class B extends A {"
384 "}");
385 VE(MissingAbstractMethodImpl,
386 "<?php "
387 "interface A {"
388 " function foo();"
390 "class B implements A {"
391 "}");
392 VEN(MissingAbstractMethodImpl,
393 "<?php "
394 "if (true) {"
395 " abstract class A {"
396 " abstract function foo();"
397 " }"
398 "} else {"
399 " abstract class A {"
400 " }"
402 "class B extends A {"
403 "}");
404 VEN(MissingAbstractMethodImpl,
405 "interface A {"
406 " public function foo();"
408 "class B implements A {"
409 " public function foo() {"
410 " return;"
411 " }"
413 "interface C extends A { }"
414 "class D extends B implements C {}"
415 "class E extends D { }");
417 return true;
420 bool TestCodeError::TestBadPassByReference() {
421 VE(BadPassByReference,
422 "<?php "
423 "function set_to_null(&$i) { $i = null; }"
424 "set_to_null(1);");
425 VE(BadPassByReference,
426 "<?php "
427 "function set_to_null(&$i) { $i = null; }"
428 "class A { const C = 1; }"
429 "set_to_null(A::C);");
430 VE(BadPassByReference,
431 "<?php "
432 "function set_to_null(&$i) { $i = null; }"
433 "set_to_null($a + $b);");
434 VE(BadPassByReference,
435 "<?php "
436 "function set_to_null(&$i) { $i = null; }"
437 "set_to_null(foo() + foo());");
438 VE(BadPassByReference,
439 "<?php "
440 "function set_to_null(&$i) { $i = null; }"
441 "set_to_null(array(1));");
442 VE(BadPassByReference,
443 "<?php "
444 "function set_to_null(&$i) { $i = null; }"
445 "define('A', 1);"
446 "set_to_null(A);");
447 VE(BadPassByReference,
448 "<?php "
449 "function set_to_null(&$i) { $i = null; }"
450 "set_to_null($a ? $b : $c);");
451 VE(BadPassByReference,
452 "<?php "
453 "class A { function foo(&$a) { echo $a;} }"
454 "class B { function bar() { $obj = new A; $obj->foo(1); } }");
456 VEN(BadPassByReference,
457 "<?php "
458 "function set_to_null(&$i) { $i = null; }"
459 "function foo() { return 1; }"
460 "class A { var $m; static $n; function f() { return 1;} }"
461 "set_to_null($a);"
462 "set_to_null($a = 1);"
463 "set_to_null(($a = 1));"
464 "set_to_null(new A);"
465 "set_to_null(foo());"
466 "$a = 'foo';"
467 "$b = 'a';"
468 "set_to_null($a());"
469 "set_to_null($$b);"
470 "$i = 1;"
471 "set_to_null(++$i); set_to_null($i--);"
472 "set_to_null(--$i); set_to_null($i--);"
473 "$obj = new A;"
474 "set_to_null($obj->f());"
475 "set_to_null($obj->m);"
476 "set_to_null(A::$n);");
477 VEN(BadPassByReference,
478 "$ar = array("
479 " array('10', 11, 100, 100, 'a'),"
480 " array( 1, 2, '2', 3, 1)"
481 " );"
482 "array_multisort($ar[0], SORT_ASC, SORT_STRING,"
483 " $ar[1], SORT_NUMERIC, SORT_DESC);");
484 return true;
487 bool TestCodeError::TestConditionalClassLoading() {
488 VE(ConditionalClassLoading,
489 "<?php "
490 "function load_cls($x) { "
491 " if (class_exists($x)) { return; } "
492 " switch ($x) { "
493 " case 'C1': /* require_once somefile */ break; "
494 " case 'C2': /* require_once somefile */ break; "
495 " } "
496 "} "
497 "load_cls('C1');");
498 return true;
501 bool TestCodeError::TestBadArgumentType() {
502 VE(BadArgumentType,
503 "<?php "
504 "function foo(array $a) { }"
505 "foo(0);");
507 return true;
510 bool TestCodeError::TestGotoUndefLabel() {
511 VE(GotoUndefLabel,
512 "<?php goto foo_bar;");
514 VE(GotoUndefLabel,
515 "<?php function f() { goto baz; } baz:");
517 return true;
520 bool TestCodeError::TestGotoInvalidBlock() {
521 VE(GotoInvalidBlock,
522 "<?php goto my_block; do { my_block: } while (false);");
524 VE(GotoInvalidBlock,
525 "<?php "
526 "function f($x) {"
527 " goto foo;"
528 " for ($i = 0; $i < $x; $i++) {"
529 " foo: var_dump($i);"
530 " }"
531 "}");
533 return true;
536 bool TestCodeError::TestInvalidAttribute() {
537 VE(InvalidAttribute,
538 "<?php abstract class F { abstract $f; }");
540 VE(InvalidAttribute,
541 "<?php class F { abstract $f; }");
543 VE(InvalidAttribute,
544 "<?php final class F { final $f; }");
546 VE(InvalidAttribute,
547 "<?php class F { final $f; }");
549 VE(InvalidAttribute,
550 "<?php interface I { final function foo(); }");
552 VE(InvalidAttribute,
553 "<?php interface I { private function foo(); }");
555 VE(InvalidAttribute,
556 "<?php interface I { protected function foo(); }");
558 VE(InvalidAttribute,
559 "<?php interface I { abstract function foo(); }");
561 VE(InvalidAttribute,
562 "<?php class a { static function a() {} }");
564 VE(InvalidAttribute,
565 "<?php class a { static function __construct() {} }");
567 VEN(InvalidAttribute,
568 "<?php class a { function __construct() {} static function a() {} }");
570 return true;
573 bool TestCodeError::TestUnknownTrait() {
574 VE(UnknownTrait, "<?php class C { use T; }");
576 VE(UnknownTrait, "<?php trait T1 { use T2; }");
578 return true;
581 bool TestCodeError::TestMethodInMultipleTraits() {
582 VE(MethodInMultipleTraits,
583 "<?php\n"
584 "trait T1 {\n"
585 " public function Func() { }\n"
586 "}\n"
587 "trait T2 {\n"
588 " public function Func() { }\n"
589 "}\n"
590 "class C {\n"
591 " use T1, T2;\n"
592 "}\n");
594 VE(MethodInMultipleTraits,
595 "<?php\n"
596 "trait T1 {\n"
597 " public function Func() { }\n"
598 "}\n"
599 "trait T2 {\n"
600 " public function Func() { }\n"
601 "}\n"
602 "trait T3 {\n"
603 " use T2;\n"
604 "}\n"
605 "class C {\n"
606 " use T1, T3;\n"
607 "}\n");
609 VE(MethodInMultipleTraits,
610 "<?php\n"
611 "trait T1 {\n"
612 " public function Func() { }\n"
613 "}\n"
614 "trait T2 {\n"
615 " use T1;\n"
616 "}\n"
617 "trait T3 {\n"
618 " use T1;\n"
619 "}\n"
620 "class C {\n"
621 " use T2, T3;\n"
622 "}\n");
624 VE(MethodInMultipleTraits,
625 "<?php\n"
626 "trait T1 {\n"
627 " public function Func1() { }\n"
628 "}\n"
629 "trait T2 {\n"
630 " public function Func2() { }\n"
631 "}\n"
632 "trait T3 {\n"
633 " use T2 {\n"
634 " T2::Func2 as Func1;\n"
635 " }\n"
636 "}\n"
637 "class C {\n"
638 " use T1, T3;\n"
639 "}\n");
641 return true;
644 bool TestCodeError::TestUnknownTraitMethod() {
645 VE(UnknownTraitMethod,
646 "<?php\n"
647 "trait T1 {\n"
648 " public function Func1() { }\n"
649 "}\n"
650 "class C {\n"
651 " use T1 {\n"
652 " T1::Func2 as Func3;\n"
653 " }\n"
654 "}\n");
656 return true;
659 bool TestCodeError::TestCyclicDependentTraits() {
660 VE(CyclicDependentTraits,
661 "<?php\n"
662 "trait T1 {\n"
663 " use T2;\n"
664 "}\n"
665 "trait T2 {\n"
666 " use T1;\n"
667 "}\n");
669 VE(CyclicDependentTraits,
670 "<?php\n"
671 "trait T1 {\n"
672 " use T1;\n"
673 "}\n");
675 VE(CyclicDependentTraits,
676 "<?php\n"
677 "trait T1 {\n"
678 " use T2;\n"
679 "}\n"
680 "trait T2 {\n"
681 " use T3;\n"
682 "}\n"
683 "trait T3 {\n"
684 " use T1;\n"
685 "}\n");
687 return true;
690 bool TestCodeError::TestInvalidTraitStatement() {
691 VE(InvalidTraitStatement,
692 "<?php\n"
693 "trait T {\n"
694 " const y = 3;\n"
695 "}\n");
697 return true;
700 bool TestCodeError::TestRedeclaredTrait() {
701 VE(RedeclaredTrait,
702 "<?php\n"
703 "trait T {}\n"
704 "trait T {}\n");
706 VE(RedeclaredTrait,
707 "<?php\n"
708 "trait T {}\n"
709 "class T {}\n");
711 VE(RedeclaredTrait,
712 "<?php\n"
713 "class T {}\n"
714 "trait T {}\n");
716 VE(RedeclaredTrait,
717 "<?php\n"
718 "interface T {}\n"
719 "trait T {}\n");
721 return true;
724 bool TestCodeError::TestInvalidInstantiation() {
725 VE(InvalidInstantiation, "<?php interface T {}; $a = new T();");
726 VE(InvalidInstantiation,
727 "<?php abstract class T { abstract function foo(); };"
728 "$a = new T();");
730 VEN(InvalidInstantiation, "<?php class T {}; $a = new T();");
731 return true;
734 bool TestCodeError::TestInvalidYield() {
735 WithOpt w0(Option::EnableHipHopSyntax);
737 VE(InvalidYield, "<?php function f() { yield 1; return 2; }");
738 VE(InvalidYield, "<?php async function f() { await f(); yield 1; }");
739 VE(InvalidYield, "<?php yield 1; }");
740 VE(InvalidYield, "<?php class X { function __get() { yield 1; } }");
741 VE(InvalidYield, "<?php class X { function X() { yield 1; } }");
742 return true;
746 bool TestCodeError::TestInvalidAwait() {
747 WithOpt w0(Option::EnableHipHopSyntax);
749 VE(InvalidAwait, "<?php function f() { yield 1; await f(); }");
750 VE(InvalidAwait, "<?php await f(); }");
751 VE(InvalidAwait, "<?php class X { function __get() { await f(); } }");
752 VE(InvalidAwait, "<?php class X { function X() { await f(); } }");
753 return true;
757 bool TestCodeError::TestBadDefaultValueType() {
758 WithOpt w0(Option::EnableHipHopSyntax);
760 VE(BadDefaultValueType, "<?php class C { function f(int $i1 = array()) {} }");
761 VE(BadDefaultValueType, "<?php function f(int $i1 = array()) {}");
762 return true;
765 bool TestCodeError::TestInvalidMethodDefinition() {
766 VE(InvalidMethodDefinition, "<?php interface I {public function f() {}}");
767 return true;