create(ParserFactory::PREFER_PHP7); } /** * @return void */ public function setUp() { $config = new TestConfig(); $config->throw_exception = true; FileChecker::clearCache(); $this->project_checker = new \Psalm\Checker\ProjectChecker(); } /** * @return void */ public function testNewVarInIf() { $stmts = self::$parser->parse('foo = []; } if (!is_array($this->foo)) { // do something } } } '); $file_checker = new FileChecker('somefile.php', $this->project_checker, $stmts); $file_checker->visitAndAnalyzeMethods(); } /** * @return void */ public function testPropertyWithoutTypeSuppressingIssue() { Config::getInstance()->setCustomErrorLevel('MissingPropertyType', Config::REPORT_SUPPRESS); Config::getInstance()->setCustomErrorLevel('MixedAssignment', Config::REPORT_SUPPRESS); $stmts = self::$parser->parse('foo; '); $file_checker = new FileChecker('somefile.php', $this->project_checker, $stmts); $file_checker->visitAndAnalyzeMethods(); } /** * @expectedException \Psalm\Exception\CodeException * @expectedExceptionMessage UndefinedPropertyAssignment * @return void */ public function testUndefinedPropertyAssignment() { $stmts = self::$parser->parse('foo = "cool"; '); $file_checker = new FileChecker('somefile.php', $this->project_checker, $stmts); $file_checker->visitAndAnalyzeMethods(); } /** * @expectedException \Psalm\Exception\CodeException * @expectedExceptionMessage UndefinedPropertyFetch * @return void */ public function testUndefinedPropertyFetch() { $stmts = self::$parser->parse('foo; '); $file_checker = new FileChecker('somefile.php', $this->project_checker, $stmts); $file_checker->visitAndAnalyzeMethods(); } /** * @expectedException \Psalm\Exception\CodeException * @expectedExceptionMessage UndefinedThisPropertyAssignment * @return void */ public function testUndefinedThisPropertyAssignment() { $stmts = self::$parser->parse('foo = "cool"; } } '); $file_checker = new FileChecker('somefile.php', $this->project_checker, $stmts); $file_checker->visitAndAnalyzeMethods(); } /** * @expectedException \Psalm\Exception\CodeException * @expectedExceptionMessage UndefinedThisPropertyFetch * @return void */ public function testUndefinedThisPropertyFetch() { $stmts = self::$parser->parse('foo; } } '); $file_checker = new FileChecker('somefile.php', $this->project_checker, $stmts); $file_checker->visitAndAnalyzeMethods(); } /** * @expectedException \Psalm\Exception\CodeException * @expectedExceptionMessage MissingPropertyDeclaration * @return void */ public function testMissingPropertyDeclaration() { $stmts = self::$parser->parse('foo = "cool"; } '); $file_checker = new FileChecker('somefile.php', $this->project_checker, $stmts); $file_checker->visitAndAnalyzeMethods(); } /** * @expectedException \Psalm\Exception\CodeException * @expectedExceptionMessage MissingPropertyType * @return void */ public function testMissingPropertyType() { $stmts = self::$parser->parse('project_checker, $stmts); $file_checker->visitAndAnalyzeMethods(); } /** * @expectedException \Psalm\Exception\CodeException * @expectedExceptionMessage InvalidPropertyAssignment * @return void */ public function testBadAssignment() { $stmts = self::$parser->parse('foo = 5; } } '); $file_checker = new FileChecker('somefile.php', $this->project_checker, $stmts); $file_checker->visitAndAnalyzeMethods(); } /** * @expectedException \Psalm\Exception\CodeException * @expectedExceptionMessage InvalidPropertyAssignment * @return void */ public function testBadAssignmentAsWell() { $stmts = self::$parser->parse('foo = "bar"; '); $file_checker = new FileChecker('somefile.php', $this->project_checker, $stmts); $file_checker->visitAndAnalyzeMethods(); } /** * @expectedException \Psalm\Exception\CodeException * @expectedExceptionMessage InvalidPropertyFetch * @return void */ public function testBadFetch() { $stmts = self::$parser->parse('foo; '); $file_checker = new FileChecker('somefile.php', $this->project_checker, $stmts); $file_checker->visitAndAnalyzeMethods(); } /** * @return void */ public function testSharedPropertyInIf() { $stmts = self::$parser->parse('foo; } '); $file_checker = new FileChecker('somefile.php', $this->project_checker, $stmts); $context = new Context(); $file_checker->visitAndAnalyzeMethods($context); $this->assertEquals('null|string|int', (string) $context->vars_in_scope['$b']); } /** * @return void */ public function testSharedPropertyInElseIf() { $stmts = self::$parser->parse('foo; } '); $file_checker = new FileChecker('somefile.php', $this->project_checker, $stmts); $context = new Context(); $file_checker->visitAndAnalyzeMethods($context); $this->assertEquals('null|string|int', (string) $context->vars_in_scope['$b']); } /** * @expectedException \Psalm\Exception\CodeException * @expectedExceptionMessage MixedPropertyFetch * @return void */ public function testMixedPropertyFetch() { Config::getInstance()->setCustomErrorLevel('MissingPropertyType', Config::REPORT_SUPPRESS); Config::getInstance()->setCustomErrorLevel('MixedAssignment', Config::REPORT_SUPPRESS); $stmts = self::$parser->parse('foo; '); $file_checker = new FileChecker('somefile.php', $this->project_checker, $stmts); $context = new Context(); $file_checker->visitAndAnalyzeMethods($context); } /** * @expectedException \Psalm\Exception\CodeException * @expectedExceptionMessage MixedPropertyAssignment * @return void */ public function testMixedPropertyAssignment() { Config::getInstance()->setCustomErrorLevel('MissingPropertyType', Config::REPORT_SUPPRESS); Config::getInstance()->setCustomErrorLevel('MixedAssignment', Config::REPORT_SUPPRESS); $stmts = self::$parser->parse('foo = "hello"; '); $file_checker = new FileChecker('somefile.php', $this->project_checker, $stmts); $context = new Context(); $file_checker->visitAndAnalyzeMethods($context); } /** * @expectedException \Psalm\Exception\CodeException * @expectedExceptionMessage NullPropertyAssignment * @return void */ public function testNullablePropertyAssignment() { $stmts = self::$parser->parse('foo = "hello"; '); $file_checker = new FileChecker('somefile.php', $this->project_checker, $stmts); $context = new Context(); $file_checker->visitAndAnalyzeMethods($context); } /** * @expectedException \Psalm\Exception\CodeException * @expectedExceptionMessage NullPropertyFetch * @return void */ public function testNullablePropertyFetch() { $stmts = self::$parser->parse('foo; '); $file_checker = new FileChecker('somefile.php', $this->project_checker, $stmts); $context = new Context(); $file_checker->visitAndAnalyzeMethods($context); } /** * @return void */ public function testNullablePropertyCheck() { $stmts = self::$parser->parse('bb) && $b->bb->aa === "aa") { echo $b->bb->aa; } '); $file_checker = new FileChecker('somefile.php', $this->project_checker, $stmts); $context = new Context(); $file_checker->visitAndAnalyzeMethods($context); } /** * @return void */ public function testNullablePropertyAfterGuard() { $stmts = self::$parser->parse('aa) { $a->aa = "hello"; } echo substr($a->aa, 1); '); $file_checker = new FileChecker('somefile.php', $this->project_checker, $stmts); $context = new Context(); $file_checker->visitAndAnalyzeMethods($context); } /** * @return void */ public function testNullableStaticPropertyWithIfCheck() { $stmts = self::$parser->parse('project_checker, $stmts); $context = new Context(); $file_checker->visitAndAnalyzeMethods($context); } /** * @return void */ public function testReflectionProperties() { $stmts = self::$parser->parse('name . " - " . $a->class; '); $file_checker = new FileChecker('somefile.php', $this->project_checker, $stmts); $context = new Context(); $file_checker->visitAndAnalyzeMethods($context); } /** * @return void */ public function testGrandparentReflectedProperties() { $stmts = self::$parser->parse('ownerDocument; '); $file_checker = new FileChecker('somefile.php', $this->project_checker, $stmts); $context = new Context(); $file_checker->visitAndAnalyzeMethods($context); $this->assertEquals('DOMDocument', (string) $context->vars_in_scope['$owner']); } /** * @return void */ public function testGoodArrayProperties() { Config::getInstance()->setCustomErrorLevel('MixedAssignment', Config::REPORT_SUPPRESS); $context = new Context(); $stmts = self::$parser->parse(' */ public $is; } $c = new C1; $c->is = [new A1]; $c->is = [new A1, new A1]; $c->is = [new A1, new B1]; '); $file_checker = new FileChecker('somefile.php', $this->project_checker, $stmts); $file_checker->visitAndAnalyzeMethods($context); } /** * @expectedException \Psalm\Exception\CodeException * @expectedExceptionMessage InvalidPropertyAssignment * @return void */ public function testBadArrayProperty() { Config::getInstance()->setCustomErrorLevel('MixedAssignment', Config::REPORT_SUPPRESS); $context = new Context(); $stmts = self::$parser->parse(' */ public $bb; } $c = new C; $c->bb = [new A, new B]; '); $file_checker = new FileChecker('somefile.php', $this->project_checker, $stmts); $file_checker->visitAndAnalyzeMethods($context); } /** * @return void */ public function testIssetPropertyDoesNotExist() { $stmts = self::$parser->parse('bar)) { } '); $file_checker = new FileChecker('somefile.php', $this->project_checker, $stmts); $context = new Context(); $file_checker->visitAndAnalyzeMethods($context); } }