create(ParserFactory::PREFER_PHP7); } /** * @return void */ public function setUp() { FileChecker::clearCache(); $this->project_checker = new \Psalm\Checker\ProjectChecker(); $this->project_checker->setConfig(new TestConfig()); } /** * @return void */ public function testFunctionTypeHints() { $stmts = self::$parser->parse('project_checker, $stmts); $context = new Context(); $file_checker->visitAndAnalyzeMethods($context); $this->assertEquals('int', (string) $context->vars_in_scope['$a']); } /** * @return void */ public function testMethodTypeHints() { $stmts = self::$parser->parse('project_checker, $stmts); $context = new Context(); $file_checker->visitAndAnalyzeMethods($context); $this->assertEquals('int', (string) $context->vars_in_scope['$a']); } /** * @return void */ public function testNullCoalesce() { Config::getInstance()->setCustomErrorLevel('MixedAssignment', Config::REPORT_SUPPRESS); $stmts = self::$parser->parse('project_checker, $stmts); $context = new Context(); $file_checker->visitAndAnalyzeMethods($context); $this->assertEquals('mixed', (string) $context->vars_in_scope['$a']); } /** * @return void */ public function testSpaceship() { $stmts = self::$parser->parse(' 1; '); $file_checker = new FileChecker('somefile.php', $this->project_checker, $stmts); $context = new Context(); $file_checker->visitAndAnalyzeMethods($context); $this->assertEquals('int', (string) $context->vars_in_scope['$a']); } /** * @return void */ public function testDefineArray() { $stmts = self::$parser->parse('project_checker, $stmts); $context = new Context(); $file_checker->visitAndAnalyzeMethods($context); $this->assertEquals('string', (string) $context->vars_in_scope['$a']); } /** * @return void */ public function testAnonymousClassLogger() { $stmts = self::$parser->parse('logger = $logger; } } $app = new Application; $app->setLogger(new class implements Logger { public function log(string $msg) { echo $msg; } }); '); $file_checker = new FileChecker('somefile.php', $this->project_checker, $stmts); $context = new Context(); $file_checker->visitAndAnalyzeMethods($context); } /** * @expectedException \Psalm\Exception\CodeException * @expectedExceptionMessage UndefinedClass * @return void */ public function testAnonymousClassWithBadStatement() { $stmts = self::$parser->parse('project_checker, $stmts); $context = new Context(); $file_checker->visitAndAnalyzeMethods($context); } /** * @expectedException \Psalm\Exception\CodeException * @expectedExceptionMessage InvalidReturnType * @return void */ public function testAnonymousClassWithInvalidFunctionReturnType() { $stmts = self::$parser->parse('project_checker, $stmts); $context = new Context(); $file_checker->visitAndAnalyzeMethods($context); } /** * @return void */ public function testAnonymousClassFunctionReturnType() { $stmts = self::$parser->parse('f()); '); $file_checker = new FileChecker('somefile.php', $this->project_checker, $stmts); $context = new Context(); $file_checker->visitAndAnalyzeMethods($context); } /** * @return void */ public function testGeneratorWithReturn() { $stmts = self::$parser->parse(' * @psalm-generator-return string */ function fooFoo(int $i) : Generator { if ($i === 1) { return "bash"; } yield 1; } '); $file_checker = new FileChecker('somefile.php', $this->project_checker, $stmts); $context = new Context(); $file_checker->visitAndAnalyzeMethods($context); } /** * @return void */ public function testGeneratorDelegation() { Config::getInstance()->setCustomErrorLevel('MixedAssignment', Config::REPORT_SUPPRESS); $stmts = self::$parser->parse(' * @psalm-generator-return int */ function count_to_ten() : Generator { yield 1; yield 2; yield from [3, 4]; yield from new ArrayIterator([5, 6]); yield from seven_eight(); return yield from nine_ten(); } /** * @return Generator */ function seven_eight() : Generator { yield 7; yield from eight(); } /** * @return Generator */ function eight() : Generator { yield 8; } /** * @return Generator * @psalm-generator-return int */ function nine_ten() : Generator { yield 9; return 10; } $gen = count_to_ten(); foreach ($gen as $num) { echo "$num "; } $gen2 = $gen->getReturn(); '); $file_checker = new FileChecker('somefile.php', $this->project_checker, $stmts); $context = new Context(); $file_checker->visitAndAnalyzeMethods($context); $this->assertEquals('Generator', (string) $context->vars_in_scope['$gen']); $this->assertEquals('mixed', (string) $context->vars_in_scope['$gen2']); } /** * @return void */ public function testMultipleUse() { $stmts = self::$parser->parse('project_checker, $stmts); $context = new Context(); $file_checker->visitAndAnalyzeMethods($context); } }