Skip to content
Permalink
Browse files

Move method calls outside classes and __CLASS__ constants

  • Loading branch information...
muglug committed Jun 14, 2019
1 parent 58b6ce3 commit 1bc1af140f2ab3ad5e012557e0c064c10f7a621a
@@ -125,53 +125,56 @@ public static function analyze(
} elseif ($stmt instanceof PhpParser\Node\Scalar\EncapsedStringPart) {
// do nothing
} elseif ($stmt instanceof PhpParser\Node\Scalar\MagicConst) {
switch (strtolower($stmt->getName())) {
case '__line__':
$stmt->inferredType = Type::getInt();
break;
case '__class__':
if (!$context->self) {
if (IssueBuffer::accepts(
new UndefinedConstant(
'Cannot get __class__ outside a class',
new CodeLocation($statements_analyzer->getSource(), $stmt)
),
$statements_analyzer->getSuppressedIssues()
)) {
// fall through
}
if ($stmt instanceof PhpParser\Node\Scalar\MagicConst\Line) {
$stmt->inferredType = Type::getInt();
} elseif ($stmt instanceof PhpParser\Node\Scalar\MagicConst\Class_) {
if (!$context->self) {
if (IssueBuffer::accepts(
new UndefinedConstant(
'Cannot get __class__ outside a class',
new CodeLocation($statements_analyzer->getSource(), $stmt)
),
$statements_analyzer->getSuppressedIssues()
)) {
// fall through
}
$stmt->inferredType = Type::getClassString();
break;
$stmt->inferredType = Type::getClassString();
} else {
if ($codebase->alter_code) {
$moved_class = $codebase->classlikes->handleClassLikeReferenceInMigration(
$codebase,
$statements_analyzer,
$stmt,
$context->self,
$context->calling_method_id
);
}
$stmt->inferredType = Type::getLiteralClassString($context->self);
break;
case '__namespace__':
$namespace = $statements_analyzer->getNamespace();
if ($namespace === null &&
IssueBuffer::accepts(
}
} elseif ($stmt instanceof PhpParser\Node\Scalar\MagicConst\Namespace_) {
$namespace = $statements_analyzer->getNamespace();
if ($namespace === null
&& IssueBuffer::accepts(
new UndefinedConstant(
'Cannot get __namespace__ outside a namespace',
new CodeLocation($statements_analyzer->getSource(), $stmt)
),
$statements_analyzer->getSuppressedIssues()
)) {
// fall through
}
$stmt->inferredType = Type::getString($namespace);
break;
)
) {
// fall through
}
case '__file__':
case '__dir__':
case '__function__':
case '__trait__':
case '__method__':
$stmt->inferredType = Type::getString();
break;
$stmt->inferredType = Type::getString($namespace);
} elseif ($stmt instanceof PhpParser\Node\Scalar\MagicConst\File
|| $stmt instanceof PhpParser\Node\Scalar\MagicConst\Dir
|| $stmt instanceof PhpParser\Node\Scalar\MagicConst\Function_
|| $stmt instanceof PhpParser\Node\Scalar\MagicConst\Trait_
|| $stmt instanceof PhpParser\Node\Scalar\MagicConst\Method
) {
$stmt->inferredType = Type::getString();
}
} elseif ($stmt instanceof PhpParser\Node\Scalar\LNumber) {
$stmt->inferredType = Type::getInt(false, $stmt->value);
@@ -987,7 +987,8 @@ public function handleClassLikeReferenceInMigration(
$destination_class,
$source->getFilePath(),
(int) $class_name_node->getAttribute('startFilePos'),
(int) $class_name_node->getAttribute('endFilePos') + 1
(int) $class_name_node->getAttribute('endFilePos') + 1,
$class_name_node instanceof PhpParser\Node\Scalar\MagicConst\Class_
);
return true;
@@ -1059,6 +1060,7 @@ public function handleClassLikeReferenceInMigration(
$uses_flipped,
$migrated_source_fqcln
)
. ($class_name_node instanceof PhpParser\Node\Scalar\MagicConst\Class_ ? '::class' : '')
);
FileManipulationBuffer::add($source->getFilePath(), $file_manipulations);
@@ -1094,21 +1096,41 @@ public function handleClassLikeReferenceInMigration(
$destination_class,
$source->getFilePath(),
(int) $class_name_node->getAttribute('startFilePos'),
(int) $class_name_node->getAttribute('endFilePos') + 1
(int) $class_name_node->getAttribute('endFilePos') + 1,
$class_name_node instanceof PhpParser\Node\Scalar\MagicConst\Class_
);
}
return true;
}
if ($force_change && $calling_fq_class_name) {
$this->airliftClassLikeReference(
$fq_class_name,
$calling_fq_class_name,
$source->getFilePath(),
(int) $class_name_node->getAttribute('startFilePos'),
(int) $class_name_node->getAttribute('endFilePos') + 1
);
if ($force_change) {
if ($calling_fq_class_name) {
$this->airliftClassLikeReference(
$fq_class_name,
$calling_fq_class_name,
$source->getFilePath(),
(int) $class_name_node->getAttribute('startFilePos'),
(int) $class_name_node->getAttribute('endFilePos') + 1
);
} else {
$source_namespace = $source->getNamespace();
$file_manipulations = [];
$file_manipulations[] = new \Psalm\FileManipulation(
(int) $class_name_node->getAttribute('startFilePos'),
(int) $class_name_node->getAttribute('endFilePos') + 1,
Type::getStringFromFQCLN(
$fq_class_name,
$source->getNamespace(),
$source->getAliasedClassesFlipped(),
null
)
);
FileManipulationBuffer::add($source->getFilePath(), $file_manipulations);
}
return true;
}
@@ -1247,7 +1269,8 @@ public function airliftClassLikeReference(
string $destination_fq_class_name,
string $source_file_path,
int $source_start,
int $source_end
int $source_end,
bool $add_class_constant = false
) : void {
$project_analyzer = \Psalm\Internal\Analyzer\ProjectAnalyzer::getInstance();
$codebase = $project_analyzer->getCodebase();
@@ -1268,7 +1291,7 @@ public function airliftClassLikeReference(
$destination_class_storage->aliases->namespace,
$destination_class_storage->aliases->uses_flipped,
$destination_class_storage->name
)
) . ($add_class_constant ? '::class' : '')
);
FileManipulationBuffer::add(
@@ -322,6 +322,7 @@ public function foo(ArrayObject $a) : Exception {
}
echo \A::class;
echo __CLASS__;
ArrayObject::foo();
@@ -353,6 +354,7 @@ public function foo(\ArrayObject $a) : Exception {
}
echo self::class;
echo self::class;
\ArrayObject::foo();
@@ -85,6 +85,8 @@ public function providerValidCodeParse()
use ArrayObject;
A::Foo();
class A {
/**
* @return ArrayObject<int, int>
@@ -105,6 +107,8 @@ public static function bar() : void {
use ArrayObject;
B::Fe();
class A {
}

0 comments on commit 1bc1af1

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