1
0
mirror of https://github.com/danog/psalm.git synced 2024-12-02 09:37:59 +01:00

Improve ergonomics of PHPStorm meta parsing

This commit is contained in:
Matthew Brown 2019-02-16 18:50:25 -05:00
parent 2ef82d785f
commit 356a45a155
7 changed files with 30 additions and 41 deletions

View File

@ -26,7 +26,6 @@
<file name="tests/performance/a.test"/> <file name="tests/performance/a.test"/>
<file name="tests/performance/b.test"/> <file name="tests/performance/b.test"/>
<file name="tests/ErrorBaselineTest.php"/> <file name="tests/ErrorBaselineTest.php"/>
<file name="tests/Plugin/phpstorm.meta.php" />
</ignoreFiles> </ignoreFiles>
</projectFiles> </projectFiles>

View File

@ -1213,12 +1213,6 @@ class Config
$phpstorm_meta_path = $this->base_dir . DIRECTORY_SEPARATOR . '.phpstorm.meta.php'; $phpstorm_meta_path = $this->base_dir . DIRECTORY_SEPARATOR . '.phpstorm.meta.php';
if (file_exists($phpstorm_meta_path)) { if (file_exists($phpstorm_meta_path)) {
$meta_statements = $codebase->statements_provider->getStatementsForFile(
$phpstorm_meta_path
);
PhpStormMetaScanner::scan($meta_statements, $codebase);
$stub_files[] = $phpstorm_meta_path; $stub_files[] = $phpstorm_meta_path;
} }

View File

@ -498,6 +498,10 @@ class Scanner
if (!isset($this->classlike_files[$fq_classlike_name_lc])) { if (!isset($this->classlike_files[$fq_classlike_name_lc])) {
if ($classlikes->doesClassLikeExist($fq_classlike_name_lc)) { if ($classlikes->doesClassLikeExist($fq_classlike_name_lc)) {
if ($fq_classlike_name_lc === 'self') {
continue;
}
if ($this->debug_output) { if ($this->debug_output) {
echo 'Using reflection to get metadata for ' . $fq_classlike_name . "\n"; echo 'Using reflection to get metadata for ' . $fq_classlike_name . "\n";
} }
@ -675,6 +679,10 @@ class Scanner
return true; return true;
} }
if ($fq_class_name === 'self') {
return false;
}
if (isset($this->existing_classlikes_lc[$fq_class_name_lc])) { if (isset($this->existing_classlikes_lc[$fq_class_name_lc])) {
throw new \InvalidArgumentException('Why are you asking about a builtin class?'); throw new \InvalidArgumentException('Why are you asking about a builtin class?');
} }

View File

@ -17,36 +17,11 @@ use Psalm\Type;
*/ */
class PhpStormMetaScanner class PhpStormMetaScanner
{ {
/**
* @param array<PhpParser\Node\Stmt> $stmts
* @return void
*/
public static function scan(array $stmts, Codebase $codebase)
{
foreach ($stmts as $stmt) {
if ($stmt instanceof PhpParser\Node\Stmt\Namespace_
&& $stmt->name
&& $stmt->name->parts === ['PHPSTORM_META']
) {
foreach ($stmt->stmts as $meta_stmt) {
if ($meta_stmt instanceof PhpParser\Node\Stmt\Expression
&& $meta_stmt->expr instanceof PhpParser\Node\Expr\FuncCall
&& $meta_stmt->expr->name instanceof PhpParser\Node\Name
&& $meta_stmt->expr->name->parts === ['override']
&& count($meta_stmt->expr->args) > 1
) {
self::handleOverride($meta_stmt->expr->args, $codebase);
}
}
}
}
}
/** /**
* @param array<PhpParser\Node\Arg> $args * @param array<PhpParser\Node\Arg> $args
* @return void * @return void
*/ */
private static function handleOverride(array $args, Codebase $codebase) public static function handleOverride(array $args, Codebase $codebase)
{ {
$identifier = $args[0]->value; $identifier = $args[0]->value;

View File

@ -12,6 +12,7 @@ use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Codebase; use Psalm\Codebase;
use Psalm\Internal\Codebase\CallMap; use Psalm\Internal\Codebase\CallMap;
use Psalm\Internal\Codebase\PropertyMap; use Psalm\Internal\Codebase\PropertyMap;
use Psalm\Internal\Scanner\PhpStormMetaScanner;
use Psalm\CodeLocation; use Psalm\CodeLocation;
use Psalm\Config; use Psalm\Config;
use Psalm\DocComment; use Psalm\DocComment;
@ -451,6 +452,22 @@ class ReflectorVisitor extends PhpParser\NodeVisitorAbstract implements PhpParse
{ {
if ($node instanceof PhpParser\Node\Stmt\Namespace_) { if ($node instanceof PhpParser\Node\Stmt\Namespace_) {
$this->aliases = $this->file_aliases; $this->aliases = $this->file_aliases;
if ($this->codebase->register_stub_files
&& $node->name
&& $node->name->parts === ['PHPSTORM_META']
) {
foreach ($node->stmts as $meta_stmt) {
if ($meta_stmt instanceof PhpParser\Node\Stmt\Expression
&& $meta_stmt->expr instanceof PhpParser\Node\Expr\FuncCall
&& $meta_stmt->expr->name instanceof PhpParser\Node\Name
&& $meta_stmt->expr->name->parts === ['override']
&& count($meta_stmt->expr->args) > 1
) {
PhpStormMetaScanner::handleOverride($meta_stmt->expr->args, $this->codebase);
}
}
}
} elseif ($node instanceof PhpParser\Node\Stmt\ClassLike) { } elseif ($node instanceof PhpParser\Node\Stmt\ClassLike) {
if (!$this->fq_classlike_names) { if (!$this->fq_classlike_names) {
throw new \LogicException('$this->fq_classlike_names should not be empty'); throw new \LogicException('$this->fq_classlike_names should not be empty');

View File

@ -131,20 +131,16 @@ class StubTest extends TestCase
<projectFiles> <projectFiles>
<directory name="src" /> <directory name="src" />
</projectFiles> </projectFiles>
<stubs>
<file name="tests/stubs/phpstorm.meta.php" />
</stubs>
</psalm>' </psalm>'
) )
); );
$file_path = getcwd() . '/src/somefile.php'; $file_path = getcwd() . '/src/somefile.php';
$codebase = $this->project_analyzer->getCodebase();
$meta_statements = $codebase->statements_provider->getStatementsForFile(
__DIR__ . DIRECTORY_SEPARATOR . 'Plugin' . DIRECTORY_SEPARATOR . 'phpstorm.meta.php'
);
\Psalm\Internal\Scanner\PhpStormMetaScanner::scan($meta_statements, $codebase);
$this->addFile( $this->addFile(
$file_path, $file_path,
'<?php '<?php