Skip to content
Permalink
Browse files

Migrate class references in static calls

  • Loading branch information...
muglug committed Jun 1, 2019
1 parent 7ec9818 commit 7e4de611bfa06a9beb7102abc6ed2843a46aac27
@@ -8,16 +8,31 @@ class Aliases
*/
public $uses;
/**
* @var array<string, string>
*/
public $uses_flipped;
/**
* @var array<string, string>
*/
public $functions;
/**
* @var array<string, string>
*/
public $functions_flipped;
/**
* @var array<string, string>
*/
public $constants;
/**
* @var array<string, string>
*/
public $constants_flipped;
/** @var string|null */
public $namespace;
@@ -26,16 +41,25 @@ class Aliases
* @param array<string, string> $uses
* @param array<string, string> $functions
* @param array<string, string> $constants
* @param array<string, string> $uses_flipped
* @param array<string, string> $functions_flipped
* @param array<string, string> $constants_flipped
*/
public function __construct(
$namespace = null,
array $uses = [],
array $functions = [],
array $constants = []
array $constants = [],
array $uses_flipped = [],
array $functions_flipped = [],
array $constants_flipped = []
) {
$this->namespace = $namespace;
$this->uses = $uses;
$this->functions = $functions;
$this->constants = $constants;
$this->uses_flipped = $uses_flipped;
$this->functions_flipped = $functions_flipped;
$this->constants_flipped = $constants_flipped;
}
}
@@ -821,6 +821,8 @@ function (Assertion $assertion) use ($found_generic_params) : Assertion {
}
}
$moved_call = false;
foreach ($codebase->call_transforms as $original_pattern => $transformation) {
if ($declaring_method_id
&& strtolower($declaring_method_id) . '\((.*\))' === $original_pattern
@@ -851,10 +853,28 @@ function (Assertion $assertion) use ($found_generic_params) : Assertion {
);
FileManipulationBuffer::add($statements_analyzer->getFilePath(), $file_manipulations);
$moved_call = true;
}
}
}
if (!$moved_call
&& $codebase->method_migrations
&& $context->calling_method_id
&& isset($codebase->method_migrations[strtolower($context->calling_method_id)])
) {
$destination_method_id = $codebase->method_migrations[strtolower($context->calling_method_id)];
$codebase->classlikes->airliftClassLikeReference(
$fq_class_name,
explode('::', $destination_method_id)[0],
$statements_analyzer->getFilePath(),
(int) $stmt->class->getAttribute('startFilePos'),
(int) $stmt->class->getAttribute('endFilePos') + 1
);
}
if ($config->after_method_checks) {
$file_manipulations = [];
@@ -143,25 +143,15 @@ public static function analyzeClassConst(
if ($codebase->method_migrations
&& $context->calling_method_id
&& isset($codebase->method_migrations[strtolower($context->calling_method_id)])
&& strtolower(explode('::', $context->calling_method_id)[0]) === strtolower($fq_class_name)
&& !$stmt->class instanceof PhpParser\Node\Name\FullyQualified
) {
$file_manipulations = [];
$destination_method_id = $codebase->method_migrations[strtolower($context->calling_method_id)];
$file_manipulations[] = new \Psalm\FileManipulation(
(int) $stmt->class->getAttribute('startFilePos'),
(int) $stmt->class->getAttribute('endFilePos') + 1,
Type::getStringFromFQCLN(
$fq_class_name,
null,
[],
null
)
);
\Psalm\Internal\FileManipulation\FileManipulationBuffer::add(
$codebase->classlikes->airliftClassLikeReference(
$fq_class_name,
explode('::', $destination_method_id)[0],
$statements_analyzer->getFilePath(),
$file_manipulations
(int) $stmt->class->getAttribute('startFilePos'),
(int) $stmt->class->getAttribute('endFilePos') + 1
);
}
@@ -785,6 +785,41 @@ public function refactorMethods(Methods $methods, Progress $progress = null)
FileManipulationBuffer::addCodeMigrations($code_migrations);
}
public function airliftClassLikeReference(
string $fq_class_name,
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::getStringFromFQCLN(
$fq_class_name,
$destination_class_storage->aliases->namespace,
$destination_class_storage->aliases->uses_flipped,
$destination_class_storage->name
)
);
FileManipulationBuffer::add(
$source_file_path,
$file_manipulations
);
}
/**
* @param string $class_name
* @param mixed $visibility
@@ -165,7 +165,10 @@ public function enterNode(PhpParser\Node $node)
$node->name ? implode('\\', $node->name->parts) : '',
$this->aliases->uses,
$this->aliases->functions,
$this->aliases->constants
$this->aliases->constants,
$this->aliases->uses_flipped,
$this->aliases->functions_flipped,
$this->aliases->constants_flipped
);
} elseif ($node instanceof PhpParser\Node\Stmt\Use_) {
foreach ($node->uses as $use) {
@@ -176,14 +179,17 @@ public function enterNode(PhpParser\Node $node)
switch ($use->type !== PhpParser\Node\Stmt\Use_::TYPE_UNKNOWN ? $use->type : $node->type) {
case PhpParser\Node\Stmt\Use_::TYPE_FUNCTION:
$this->aliases->functions[strtolower($use_alias)] = $use_path;
$this->aliases->functions_flipped[strtolower($use_path)] = $use_alias;
break;
case PhpParser\Node\Stmt\Use_::TYPE_CONSTANT:
$this->aliases->constants[$use_alias] = $use_path;
$this->aliases->constants_flipped[$use_path] = $use_alias;
break;
case PhpParser\Node\Stmt\Use_::TYPE_NORMAL:
$this->aliases->uses[strtolower($use_alias)] = $use_path;
$this->aliases->uses_flipped[strtolower($use_path)] = $use_alias;
break;
}
}
@@ -197,14 +203,17 @@ public function enterNode(PhpParser\Node $node)
switch ($use->type !== PhpParser\Node\Stmt\Use_::TYPE_UNKNOWN ? $use->type : $node->type) {
case PhpParser\Node\Stmt\Use_::TYPE_FUNCTION:
$this->aliases->functions[strtolower($use_alias)] = $use_path;
$this->aliases->functions_flipped[strtolower($use_path)] = $use_alias;
break;
case PhpParser\Node\Stmt\Use_::TYPE_CONSTANT:
$this->aliases->constants[$use_alias] = $use_path;
$this->aliases->constants_flipped[$use_path] = $use_alias;
break;
case PhpParser\Node\Stmt\Use_::TYPE_NORMAL:
$this->aliases->uses[strtolower($use_alias)] = $use_path;
$this->aliases->uses_flipped[strtolower($use_path)] = $use_alias;
break;
}
}
@@ -809,6 +818,7 @@ private function registerClassLike(PhpParser\Node\Stmt\ClassLike $node)
$storage->location = $name_location;
$storage->user_defined = !$this->codebase->register_stub_files;
$storage->stubbed = $this->codebase->register_stub_files;
$storage->aliases = $this->aliases;
$doc_comment = $node->getDocComment();
@@ -2739,8 +2749,6 @@ private function visitClassConstDeclaration(
} else {
$storage->public_class_constant_nodes[$const->name->name] = $const->value;
}
$storage->aliases = $this->aliases;
}
if ($deprecated) {

0 comments on commit 7e4de61

Please sign in to comment.
You can’t perform that action at this time.