create(ParserFactory::PREFER_PHP7); self::$config = new TestConfig(); } /** * @return void */ public function setUp() { FileChecker::clearCache(); $this->project_checker = new \Psalm\Checker\ProjectChecker(); $this->project_checker->setConfig(self::$config); } /** * @expectedException \Psalm\Exception\CodeException * @expectedExceptionMessage PossiblyUndefinedVariable - somefile.php:3 - Possibly undefined variable $array, first seen on line 3 * @return void */ public function testPossiblyUndefinedArrayInForeach() { $stmts = self::$parser->parse('project_checker, $stmts); $file_checker->visitAndAnalyzeMethods(); } /** * @expectedException \Psalm\Exception\CodeException * @expectedExceptionMessage PossiblyUndefinedVariable - somefile.php:4 - Possibly undefined variable $array, first seen on line 4 * @return void */ public function testPossiblyUndefinedArrayInWhileAndForeach() { $stmts = self::$parser->parse('project_checker, $stmts); $file_checker->visitAndAnalyzeMethods(); } /** * @expectedException \Psalm\Exception\CodeException * @expectedExceptionMessage PossiblyUndefinedVariable - somefile.php:6 - Possibly undefined variable $car, first seen on line 3 * @return void */ public function testPossiblyUndefinedVariableInForeach() { $stmts = self::$parser->parse('project_checker, $stmts); $file_checker->visitAndAnalyzeMethods(); } /** * @return void */ public function testSwitchVariableWithContinue() { $stmts = self::$parser->parse('project_checker, $stmts); $file_checker->visitAndAnalyzeMethods(); } /** * @return void */ public function testSwitchVariableWithContinueAndIfs() { $stmts = self::$parser->parse('project_checker, $stmts); $file_checker->visitAndAnalyzeMethods(); } /** * @return void */ public function testSwitchVariableWithFallthrough() { $stmts = self::$parser->parse('project_checker, $stmts); $file_checker->visitAndAnalyzeMethods(); } /** * @return void */ public function testSwitchVariableWithFallthroughStatement() { $stmts = self::$parser->parse('project_checker, $stmts); $file_checker->visitAndAnalyzeMethods(); } /** * @return void */ public function testWhileVar() { $stmts = self::$parser->parse('project_checker, $stmts); $context = new Context(); $file_checker->visitAndAnalyzeMethods($context); $this->assertEquals('bool', (string) $context->vars_in_scope['$worked']); } /** * @return void */ public function testDoWhileVar() { $stmts = self::$parser->parse('project_checker, $stmts); $context = new Context(); $file_checker->visitAndAnalyzeMethods($context); $this->assertEquals('bool', (string) $context->vars_in_scope['$worked']); } /** * @return void */ public function testDoWhileVarAndBreak() { $stmts = self::$parser->parse('project_checker, $stmts); $context = new Context(); $file_checker->visitAndAnalyzeMethods($context); } /** * @expectedException \Psalm\Exception\CodeException * @expectedExceptionMessage PossiblyUndefinedVariable - somefile.php:9 - Possibly undefined variable $a, first seen on line 4 * @return void */ public function testPossiblyUndefinedVariableInForeachAndIf() { $stmts = self::$parser->parse('project_checker, $stmts); $file_checker->visitAndAnalyzeMethods(); } /** * @return void */ public function testObjectValue() { $stmts = self::$parser->parse('child = rand(0, 1) ? new A() : new B(); } } function makeA() : A { return new A(); } $a = makeA(); while ($a instanceof A) { $a = $a->child; } '); $file_checker = new FileChecker('somefile.php', $this->project_checker, $stmts); $context = new Context(); $file_checker->visitAndAnalyzeMethods($context); $this->assertEquals('B', (string) $context->vars_in_scope['$a']); } /** * @return void */ public function testSecondLoopWithNotNullCheck() { $stmts = self::$parser->parse('project_checker, $stmts); $file_checker->visitAndAnalyzeMethods(); } /** * @return void */ public function testSecondLoopWithIntCheck() { $stmts = self::$parser->parse('project_checker, $stmts); $file_checker->visitAndAnalyzeMethods(); } /** * @return void */ public function testSecondLoopWithIntCheckAndConditionalSet() { $stmts = self::$parser->parse('project_checker, $stmts); $file_checker->visitAndAnalyzeMethods(); } /** * @return void */ public function testSecondLoopWithIntCheckAndAssignmentsInIfAndElse() { $stmts = self::$parser->parse('project_checker, $stmts); $file_checker->visitAndAnalyzeMethods(); } /** * @return void */ public function testSecondLoopWithIntCheckAndLoopSet() { $stmts = self::$parser->parse('project_checker, $stmts); $file_checker->visitAndAnalyzeMethods(); } /** * @return void */ public function testSecondLoopWithReturnInElseif() { $stmts = self::$parser->parse('project_checker, $stmts); $file_checker->visitAndAnalyzeMethods(); } /** * @return void */ public function testThirdLoopWithIntCheckAndLoopSet() { $stmts = self::$parser->parse('project_checker, $stmts); $file_checker->visitAndAnalyzeMethods(); } /** * @return void */ public function testAssignInsideForeach() { $stmts = self::$parser->parse('project_checker, $stmts); $context = new Context(); $file_checker->visitAndAnalyzeMethods($context); $this->assertSame('bool', (string) $context->vars_in_scope['$b']); } /** * @return void */ public function testAssignInsideForeachWithBreak() { $stmts = self::$parser->parse('project_checker, $stmts); $context = new Context(); $file_checker->visitAndAnalyzeMethods($context); $this->assertSame('bool', (string) $context->vars_in_scope['$b']); } /** * @expectedException \Psalm\Exception\CodeException * @expectedExceptionMessage PossiblyNullReference * @return void */ public function testPossiblyNullCheckInsideForeachWithNoLeaveStatement() { $stmts = self::$parser->parse(' */ public static function loadMultiple() { return [new A, null]; } /** @return void */ public function barBar() { } } foreach (A::loadMultiple() as $a) { if ($a === null) { // do nothing } $a->barBar(); } '); $file_checker = new FileChecker('somefile.php', $this->project_checker, $stmts); $file_checker->visitAndAnalyzeMethods(); } /** * @return void */ public function testNullCheckInsideForeachWithContinue() { $stmts = self::$parser->parse(' */ public static function loadMultiple() { return [new A, null]; } /** @return void */ public function barBar() { } } foreach (A::loadMultiple() as $a) { if ($a === null) { continue; } $a->barBar(); } '); $file_checker = new FileChecker('somefile.php', $this->project_checker, $stmts); $file_checker->visitAndAnalyzeMethods(); } }