file_provider = new \Psalm\Tests\Provider\FakeFileProvider(); $config = new TestConfig(); $config->throw_exception = false; $providers = new Providers( $this->file_provider, new \Psalm\Tests\Provider\ParserInstanceCacheProvider(), null, null, new Provider\FakeFileReferenceCacheProvider() ); $this->project_checker = new ProjectChecker( $config, $providers, false, true, ProjectChecker::TYPE_CONSOLE, 1, false ); $this->project_checker->infer_types_from_usage = true; } /** * @dataProvider providerTestErrorFix * * @param array> $file_stages * @param array $error_positions * @param array $error_levels * * @return void */ public function testErrorFix( array $file_stages, array $error_positions, array $error_levels = [] ) { $this->project_checker->diff_methods = true; $codebase = $this->project_checker->getCodebase(); $config = $codebase->config; foreach ($error_levels as $error_type => $error_level) { $config->setCustomErrorLevel($error_type, $error_level); } $start_files = array_shift($file_stages); // first batch foreach ($start_files as $file_path => $contents) { $this->file_provider->registerFile($file_path, $contents); $codebase->file_provider->openFile($file_path); $codebase->addFilesToAnalyze([$file_path => $file_path]); } $codebase->scanFiles(); $codebase->analyzer->analyzeFiles($this->project_checker, 1, false); $data = \Psalm\IssueBuffer::clear(); $found_positions = array_map( /** @param array{from: int} $a */ function (array $a) : int { return $a['from']; }, $data ); $this->assertSame($error_positions[0], $found_positions); foreach ($file_stages as $i => $file_stage) { foreach ($file_stage as $file_path => $contents) { $codebase->addTemporaryFileChanges( $file_path, $contents ); $codebase->invalidateInformationForFile($file_path); $codebase->scanTemporaryFileChanges($file_path); } foreach ($file_stage as $file_path => $contents) { $codebase->addFilesToAnalyze([$file_path => $file_path]); } $codebase->analyzer->analyzeFiles($this->project_checker, 1, false); $data = \Psalm\IssueBuffer::clear(); $found_positions = array_map( /** @param array{from: int} $a */ function (array $a) : int { return $a['from']; }, $data ); $this->assertSame($error_positions[$i + 1], $found_positions); } } /** * @return array */ public function providerTestErrorFix() { return [ 'fixMissingColonSyntaxError' => [ [ [ getcwd() . DIRECTORY_SEPARATOR . 'A.php' => ' ' ' [[], [230], []], ], 'addReturnTypesToSingleMethod' => [ [ [ getcwd() . DIRECTORY_SEPARATOR . 'A.php' => 'foo(); } }', ], [ getcwd() . DIRECTORY_SEPARATOR . 'A.php' => 'foo(); } }', ], [ getcwd() . DIRECTORY_SEPARATOR . 'A.php' => 'foo(); } }', ], ], 'error_positions' => [[136, 317, 273], [323, 279], [329]], ], 'addSpaceAffectingOffsets' => [ [ [ getcwd() . DIRECTORY_SEPARATOR . 'A.php' => 'foo(); } }', ], [ getcwd() . DIRECTORY_SEPARATOR . 'A.php' => 'foo(); } }', ], [ getcwd() . DIRECTORY_SEPARATOR . 'A.php' => 'foo(); } }', ], ], 'error_positions' => [[373], [374], [375]], [ 'MixedAssignment' => \Psalm\Config::REPORT_INFO, ] ], 'fixReturnType' => [ [ [ getcwd() . DIRECTORY_SEPARATOR . 'A.php' => ' ' ' [[189, 144, 332, 290], [338, 296], []], [ 'MissingReturnType' => \Psalm\Config::REPORT_INFO, ] ], 'resolveNamesInDifferentFunction' => [ [ [ getcwd() . DIRECTORY_SEPARATOR . 'A.php' => ' ' [[333], []], [ 'InvalidDocblock' => \Psalm\Config::REPORT_INFO, ] ], 'bridgeStatements' => [ [ [ getcwd() . DIRECTORY_SEPARATOR . 'A.php' => ' ' ' [[136, 273], [279], [186, 144]], [ 'MissingReturnType' => \Psalm\Config::REPORT_INFO, ] ], 'colonReturnType' => [ [ [ getcwd() . DIRECTORY_SEPARATOR . 'A.php' => ' ' [[136, 273], [144, 136, 275]], [ 'MissingReturnType' => \Psalm\Config::REPORT_INFO, ] ], 'noChangeJustWeirdDocblocks' => [ [ [ getcwd() . DIRECTORY_SEPARATOR . 'A.php' => ' ' [[127], [127]], ], 'removeUseShouldInvalidate' => [ [ [ getcwd() . DIRECTORY_SEPARATOR . 'A.php' => ' ' [[], [197]], ], 'removeGroupUseShouldInvalidate' => [ [ [ getcwd() . DIRECTORY_SEPARATOR . 'A.php' => ' ' [[], [197]], ], 'removeUseWithAliasShouldInvalidate' => [ [ [ getcwd() . DIRECTORY_SEPARATOR . 'A.php' => ' ' [[], [197]], ], 'removeGroupUseWithAliasShouldInvalidate' => [ [ [ getcwd() . DIRECTORY_SEPARATOR . 'A.php' => ' ' [[], [197]], ], 'removeUseShouldInvalidateNoNamespace' => [ [ [ getcwd() . DIRECTORY_SEPARATOR . 'A.php' => ' ' [[], [147]], ], 'removeGroupUseShouldInvalidateNoNamespace' => [ [ [ getcwd() . DIRECTORY_SEPARATOR . 'A.php' => ' ' [[], [197]], ], 'removeUseWithAliasShouldInvalidateNoNamespace' => [ [ [ getcwd() . DIRECTORY_SEPARATOR . 'A.php' => ' ' [[], [153]], ], 'removeGroupUseWithAliasShouldInvalidateNoNamespace' => [ [ [ getcwd() . DIRECTORY_SEPARATOR . 'A.php' => ' ' [[], [197]], ], 'addUseShouldValidate' => [ [ [ getcwd() . DIRECTORY_SEPARATOR . 'A.php' => ' ' ' ' [[197], []], ], ]; } }