create(ParserFactory::PREFER_PHP7); } public function setUp() { $config = new TestConfig(); $config->throw_exception = true; FileChecker::clearCache(); $this->project_checker = new \Psalm\Checker\ProjectChecker(); } 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(); } 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ public function testMissingPropertyType() { $stmts = self::$parser->parse('project_checker, $stmts); $file_checker->visitAndAnalyzeMethods(); } /** * @expectedException \Psalm\Exception\CodeException * @expectedExceptionMessage InvalidPropertyAssignment */ 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 */ 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 */ public function testBadFetch() { $stmts = self::$parser->parse('foo; '); $file_checker = new FileChecker('somefile.php', $this->project_checker, $stmts); $file_checker->visitAndAnalyzeMethods(); } public function testSharedPropertyInIf() { $stmts = self::$parser->parse('foo; } '); $file_checker = new FileChecker('somefile.php', $this->project_checker, $stmts); $context = new Context('somefile.php'); $file_checker->visitAndAnalyzeMethods($context); $this->assertEquals('null|string|int', (string) $context->vars_in_scope['$b']); } public function testSharedPropertyInElseIf() { $stmts = self::$parser->parse('foo; } '); $file_checker = new FileChecker('somefile.php', $this->project_checker, $stmts); $context = new Context('somefile.php'); $file_checker->visitAndAnalyzeMethods($context); $this->assertEquals('null|string|int', (string) $context->vars_in_scope['$b']); } /** * @expectedException \Psalm\Exception\CodeException * @expectedExceptionMessage MixedPropertyFetch */ 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('somefile.php'); $file_checker->visitAndAnalyzeMethods($context); } /** * @expectedException \Psalm\Exception\CodeException * @expectedExceptionMessage MixedPropertyAssignment */ 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('somefile.php'); $file_checker->visitAndAnalyzeMethods($context); } /** * @expectedException \Psalm\Exception\CodeException * @expectedExceptionMessage NullPropertyAssignment */ public function testNullablePropertyAssignment() { $stmts = self::$parser->parse('foo = "hello"; '); $file_checker = new FileChecker('somefile.php', $this->project_checker, $stmts); $context = new Context('somefile.php'); $file_checker->visitAndAnalyzeMethods($context); } /** * @expectedException \Psalm\Exception\CodeException * @expectedExceptionMessage NullPropertyFetch */ public function testNullablePropertyFetch() { $stmts = self::$parser->parse('foo; '); $file_checker = new FileChecker('somefile.php', $this->project_checker, $stmts); $context = new Context('somefile.php'); $file_checker->visitAndAnalyzeMethods($context); } 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('somefile.php'); $file_checker->visitAndAnalyzeMethods($context); } 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('somefile.php'); $file_checker->visitAndAnalyzeMethods($context); } public function testNullableStaticPropertyWithIfCheck() { $stmts = self::$parser->parse('project_checker, $stmts); $context = new Context('somefile.php'); $file_checker->visitAndAnalyzeMethods($context); } public function testReflectionProperties() { $stmts = self::$parser->parse('name . " - " . $a->class; '); $file_checker = new FileChecker('somefile.php', $this->project_checker, $stmts); $context = new Context('somefile.php'); $file_checker->visitAndAnalyzeMethods($context); } public function testGrandparentReflectedProperties() { $stmts = self::$parser->parse('ownerDocument; '); $file_checker = new FileChecker('somefile.php', $this->project_checker, $stmts); $context = new Context('somefile.php'); $file_checker->visitAndAnalyzeMethods($context); $this->assertEquals('DOMDocument', (string) $context->vars_in_scope['$owner']); } public function testGoodArrayProperties() { Config::getInstance()->setCustomErrorLevel('MixedAssignment', Config::REPORT_SUPPRESS); $context = new Context('somefile.php'); $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 */ public function testBadArrayProperty() { Config::getInstance()->setCustomErrorLevel('MixedAssignment', Config::REPORT_SUPPRESS); $context = new Context('somefile.php'); $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); } }