1
0
mirror of https://github.com/danog/psalm.git synced 2024-11-27 04:45:20 +01:00

Move var docblocks within function

This commit is contained in:
Matthew Brown 2019-06-01 12:25:57 -04:00
parent dc5a5bcd9d
commit 909e02d441
10 changed files with 150 additions and 33 deletions

View File

@ -0,0 +1,23 @@
<?php
namespace Psalm\CodeLocation;
use PhpParser;
class DocblockTypeLocation extends \Psalm\CodeLocation
{
public function __construct(
\Psalm\FileSource $file_source,
int $file_start,
int $file_end,
int $line_number
) {
$this->file_start = $file_start;
$this->file_end = $file_end;
$this->file_path = $file_source->getFilePath();
$this->file_name = $file_source->getFileName();
$this->single_line = false;
$this->preview_start = $this->file_start;
$this->line_number = $line_number;
}
}

View File

@ -36,9 +36,7 @@ class CommentAnalyzer
FileSource $source,
Aliases $aliases,
array $template_type_map = null,
?array $type_aliases = null,
?Codebase $codebase = null,
?string $calling_method_id = null
?array $type_aliases = null
) {
$var_id = null;
@ -66,6 +64,9 @@ class CommentAnalyzer
continue;
}
$type_start = null;
$type_end = null;
$line_parts = self::splitDocLine($var_line);
if ($line_parts && $line_parts[0]) {
@ -73,6 +74,11 @@ class CommentAnalyzer
throw new IncorrectDocblockException('Misplaced variable');
}
if (($start_offset = strpos($comment->getText(), $line_parts[0])) !== false) {
$type_start = $start_offset + $comment->getFilePos();
$type_end = $type_start + strlen($line_parts[0]);
}
try {
$var_type_tokens = Type::fixUpLocalType(
$line_parts[0],
@ -118,6 +124,8 @@ class CommentAnalyzer
$var_comment->original_type = $original_type;
$var_comment->var_id = $var_id;
$var_comment->line_number = $var_line_number;
$var_comment->type_start = $type_start;
$var_comment->type_end = $type_end;
$var_comment->deprecated = isset($comments['specials']['deprecated']);
$var_comment->internal = isset($comments['specials']['internal']);
if (isset($comments['specials']['psalm-internal'])) {

View File

@ -52,11 +52,7 @@ class ForeachAnalyzer
$var_comments = CommentAnalyzer::getTypeFromComment(
$doc_comment,
$statements_analyzer->getSource(),
$statements_analyzer->getSource()->getAliases(),
null,
null,
$codebase,
$context->calling_method_id
$statements_analyzer->getSource()->getAliases()
);
} catch (DocblockParseException $e) {
if (IssueBuffer::accepts(

View File

@ -80,9 +80,7 @@ class AssignmentAnalyzer
$statements_analyzer->getSource(),
$statements_analyzer->getAliases(),
$template_type_map,
$file_storage->type_aliases,
$codebase,
$context->calling_method_id
$file_storage->type_aliases
);
} catch (IncorrectDocblockException $e) {
if (IssueBuffer::accepts(
@ -122,6 +120,25 @@ class AssignmentAnalyzer
$statements_analyzer->getSuppressedIssues()
);
if ($codebase->method_migrations
&& $context->calling_method_id
&& isset($codebase->method_migrations[strtolower($context->calling_method_id)])
&& $var_comment->type_start
&& $var_comment->type_end
&& $var_comment->line_number
&& $var_comment_type->hasNamedObject()
) {
$destination_method_id = $codebase->method_migrations[strtolower($context->calling_method_id)];
$codebase->classlikes->airliftDocblockType(
$var_comment_type,
explode('::', $destination_method_id)[0],
$statements_analyzer->getFilePath(),
$var_comment->type_start,
$var_comment->type_end
);
}
if (!$var_comment->var_id || $var_comment->var_id === $var_id) {
$comment_type = $var_comment_type;
continue;

View File

@ -1371,11 +1371,7 @@ class ExpressionAnalyzer
$var_comments = CommentAnalyzer::getTypeFromComment(
$doc_comment,
$statements_analyzer,
$statements_analyzer->getAliases(),
null,
null,
$codebase,
$context->calling_method_id
$statements_analyzer->getAliases()
);
} catch (DocblockParseException $e) {
if (IssueBuffer::accepts(

View File

@ -52,11 +52,7 @@ class ReturnAnalyzer
$var_comments = CommentAnalyzer::getTypeFromComment(
$doc_comment,
$source,
$source->getAliases(),
null,
null,
$codebase,
$context->calling_method_id
$source->getAliases()
);
} catch (DocblockParseException $e) {
if (IssueBuffer::accepts(
@ -78,6 +74,25 @@ class ReturnAnalyzer
$statements_analyzer->getParentFQCLN()
);
if ($codebase->method_migrations
&& $context->calling_method_id
&& isset($codebase->method_migrations[strtolower($context->calling_method_id)])
&& $var_comment->type_start
&& $var_comment->type_end
&& $var_comment->line_number
&& $comment_type->hasNamedObject()
) {
$destination_method_id = $codebase->method_migrations[strtolower($context->calling_method_id)];
$codebase->classlikes->airliftDocblockType(
$comment_type,
explode('::', $destination_method_id)[0],
$statements_analyzer->getFilePath(),
$var_comment->type_start,
$var_comment->type_end
);
}
if (!$var_comment->var_id) {
$var_comment_type = $comment_type;
continue;

View File

@ -910,10 +910,7 @@ class StatementsAnalyzer extends SourceAnalyzer implements StatementsSource
$doc_comment,
$this->getSource(),
$this->getAliases(),
$this->getTemplateTypeMap(),
null,
$codebase,
$context->calling_method_id
$this->getTemplateTypeMap()
);
} catch (\Psalm\Exception\IncorrectDocblockException $e) {
if (IssueBuffer::accepts(
@ -953,6 +950,25 @@ class StatementsAnalyzer extends SourceAnalyzer implements StatementsSource
$this->getSuppressedIssues()
);
if ($codebase->method_migrations
&& $context->calling_method_id
&& isset($codebase->method_migrations[strtolower($context->calling_method_id)])
&& $var_comment->type_start
&& $var_comment->type_end
&& $var_comment->line_number
&& $var_comment_type->hasNamedObject()
) {
$destination_method_id = $codebase->method_migrations[strtolower($context->calling_method_id)];
$codebase->classlikes->airliftDocblockType(
$var_comment_type,
explode('::', $destination_method_id)[0],
$this->getFilePath(),
$var_comment->type_start,
$var_comment->type_end
);
}
if (!$var_comment->var_id || $var_comment->var_id === $var_id) {
$comment_type = $var_comment_type;
continue;

View File

@ -820,6 +820,41 @@ class ClassLikes
);
}
public function airliftDocblockType(
Type\Union $type,
string $destination_fq_class_name,
string $source_file_path,
int $source_start,
int $source_end
) : void {
$project_analyzer = \Psalm\Internal\Analyzer\ProjectAnalyzer::getInstance();
$codebase = $project_analyzer->getCodebase();
$destination_class_storage = $codebase->classlike_storage_provider->get($destination_fq_class_name);
if (!$destination_class_storage->aliases) {
throw new \UnexpectedValueException('Aliases should not be null');
}
$file_manipulations = [];
$file_manipulations[] = new \Psalm\FileManipulation(
$source_start,
$source_end,
$type->toNamespacedString(
$destination_class_storage->aliases->namespace,
$destination_class_storage->aliases->uses_flipped,
$destination_class_storage->name,
false
)
);
FileManipulationBuffer::add(
$source_file_path,
$file_manipulations
);
}
/**
* @param string $class_name
* @param mixed $visibility

View File

@ -28,6 +28,16 @@ class VarDocblockComment
*/
public $line_number;
/**
* @var int|null
*/
public $type_start;
/**
* @var int|null
*/
public $type_end;
/**
* Whether or not the property is deprecated
*

View File

@ -2601,16 +2601,17 @@ class ReflectorVisitor extends PhpParser\NodeVisitorAbstract implements PhpParse
$property_storage->type = null;
} else {
if ($var_comment && $var_comment->line_number) {
$doc_var_location = new CodeLocation(
if ($var_comment
&& $var_comment->type_start
&& $var_comment->type_end
&& $var_comment->line_number
) {
$doc_var_location = new CodeLocation\DocblockTypeLocation(
$this->file_scanner,
$stmt,
null,
false,
CodeLocation::VAR_TYPE,
$var_comment->original_type
$var_comment->type_start,
$var_comment->type_end,
$var_comment->line_number
);
$doc_var_location->setCommentLine($var_comment->line_number);
}
if ($doc_var_group_type) {