From ec5fe544bbd4539cb1459a58af09307e85b1c887 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9o=20FIDRY?= Date: Sat, 17 Feb 2018 15:21:13 +0000 Subject: [PATCH 1/2] Prefix constants Prefix the constants whenever possible, i.e. when the constant is not internal. --- ...h-single-level-use-statement-and-alias.php | 2 +- ...global-with-single-level-use-statement.php | 2 +- specs/const/global-scope-global.php | 28 +++++++++++++++++-- ...h-single-level-use-statement-and-alias.php | 3 +- ...global-with-single-level-use-statement.php | 3 +- specs/const/namespace-global.php | 3 +- specs/use/use-const.php | 4 +-- src/NodeVisitor/NameStmtPrefixer.php | 8 ++++-- src/NodeVisitor/UseStmt/UseStmtPrefixer.php | 4 +++ src/Reflector.php | 21 ++++++++++++++ 10 files changed, 66 insertions(+), 12 deletions(-) diff --git a/specs/const/global-scope-global-with-single-level-use-statement-and-alias.php b/specs/const/global-scope-global-with-single-level-use-statement-and-alias.php index 6bdea324..4eae6b77 100644 --- a/specs/const/global-scope-global-with-single-level-use-statement-and-alias.php +++ b/specs/const/global-scope-global-with-single-level-use-statement-and-alias.php @@ -67,7 +67,7 @@ namespace Humbug; use const Humbug\DUMMY_CONST as FOO; -\FOO; +\Humbug\FOO; PHP ], diff --git a/specs/const/global-scope-global-with-single-level-use-statement.php b/specs/const/global-scope-global-with-single-level-use-statement.php index f2a73a3d..9ae06dd7 100644 --- a/specs/const/global-scope-global-with-single-level-use-statement.php +++ b/specs/const/global-scope-global-with-single-level-use-statement.php @@ -67,7 +67,7 @@ namespace Humbug; use const Humbug\DUMMY_CONST; -\DUMMY_CONST; +\Humbug\DUMMY_CONST; PHP ], diff --git a/specs/const/global-scope-global.php b/specs/const/global-scope-global.php index ceb1858f..240055ac 100644 --- a/specs/const/global-scope-global.php +++ b/specs/const/global-scope-global.php @@ -23,6 +23,7 @@ [ 'spec' => <<<'SPEC' Constant call in the global namespace: +- prefix the constant - transforms the call into a FQ call SPEC , @@ -35,7 +36,28 @@ namespace Humbug; -\DUMMY_CONST; +\Humbug\DUMMY_CONST; + +PHP + ], + + [ + 'spec' => <<<'SPEC' +Internal constant call in the global namespace: +- do not prefix the constant +- transforms the call into a FQ call +SPEC + , + 'payload' => <<<'PHP' + <<<'SPEC' FQ constant call in the global namespace: -- do nothing +- prefix the constant SPEC , 'payload' => <<<'PHP' @@ -55,7 +77,7 @@ namespace Humbug; -\DUMMY_CONST; +\Humbug\DUMMY_CONST; PHP ], diff --git a/specs/const/namespace-global-with-single-level-use-statement-and-alias.php b/specs/const/namespace-global-with-single-level-use-statement-and-alias.php index 99169981..88f0dbb4 100644 --- a/specs/const/namespace-global-with-single-level-use-statement-and-alias.php +++ b/specs/const/namespace-global-with-single-level-use-statement-and-alias.php @@ -57,6 +57,7 @@ Constant call imported with an aliased use statement: - prefix the namespace - prefix the use statement +- prefix the constant call SPEC , 'payload' => <<<'PHP' @@ -73,7 +74,7 @@ namespace Humbug\A; use const Humbug\DUMMY_CONST as FOO; -\FOO; +\Humbug\FOO; PHP ], diff --git a/specs/const/namespace-global-with-single-level-use-statement.php b/specs/const/namespace-global-with-single-level-use-statement.php index 476b5e9a..6f38b09b 100644 --- a/specs/const/namespace-global-with-single-level-use-statement.php +++ b/specs/const/namespace-global-with-single-level-use-statement.php @@ -57,6 +57,7 @@ FQ constant call imported with a use statement: - prefix the namespace - prefix the use statement +- prefix the constant call SPEC , 'payload' => <<<'PHP' @@ -73,7 +74,7 @@ namespace Humbug\A; use const Humbug\DUMMY_CONST; -\DUMMY_CONST; +\Humbug\DUMMY_CONST; PHP ], diff --git a/specs/const/namespace-global.php b/specs/const/namespace-global.php index 28321827..1725ecd7 100644 --- a/specs/const/namespace-global.php +++ b/specs/const/namespace-global.php @@ -47,6 +47,7 @@ 'spec' => <<<'SPEC' FQ constant call in a namespace: - prefix the namespace +- prefix the constant call SPEC , 'payload' => <<<'PHP' @@ -60,7 +61,7 @@ namespace Humbug\A; -\DUMMY_CONST; +\Humbug\DUMMY_CONST; PHP ], diff --git a/specs/use/use-const.php b/specs/use/use-const.php index dd8ad1b3..78017a63 100644 --- a/specs/use/use-const.php +++ b/specs/use/use-const.php @@ -44,7 +44,7 @@ [ 'spec' => <<<'SPEC' Constant use statement for an internal constant belonging to the global namespace: -- prefix the use statement +- do not prefix the use statement SPEC , 'payload' => <<<'PHP' @@ -57,7 +57,7 @@ namespace Humbug; -use const Humbug\DIRECTORY_SEPARATOR; +use const DIRECTORY_SEPARATOR; PHP ], diff --git a/src/NodeVisitor/NameStmtPrefixer.php b/src/NodeVisitor/NameStmtPrefixer.php index d32f9f26..9c91ec14 100644 --- a/src/NodeVisitor/NameStmtPrefixer.php +++ b/src/NodeVisitor/NameStmtPrefixer.php @@ -128,8 +128,12 @@ private function prefixName(Name $name): Node } if ($parentNode instanceof ConstFetch - && 1 === count($resolvedName->parts) - && null === $resolvedValue->getUse() + && ( + $this->reflector->isConstantInternal($resolvedName->toString()) + // Constants have a fallback autoloading so we cannot prefix them when the name is ambiguous + // See https://wiki.php.net/rfc/fallback-to-root-scope-deprecation + || false === ($resolvedName instanceof FullyQualified) + ) ) { return $resolvedName; } diff --git a/src/NodeVisitor/UseStmt/UseStmtPrefixer.php b/src/NodeVisitor/UseStmt/UseStmtPrefixer.php index 3aca6186..2a8ac8c6 100644 --- a/src/NodeVisitor/UseStmt/UseStmtPrefixer.php +++ b/src/NodeVisitor/UseStmt/UseStmtPrefixer.php @@ -74,6 +74,10 @@ private function shouldPrefixUseStmt(UseUse $use): bool return false === $this->reflector->isFunctionInternal($use->name->getFirst()); } + if (Use_::TYPE_CONSTANT === $useType) { + return false === $this->reflector->isConstantInternal($use->name->getFirst()); + } + return Use_::TYPE_NORMAL !== $useType || false === $this->reflector->isClassInternal($use->name->getFirst()); } diff --git a/src/Reflector.php b/src/Reflector.php index a5d549d4..06265ada 100644 --- a/src/Reflector.php +++ b/src/Reflector.php @@ -14,16 +14,21 @@ namespace Humbug\PhpScoper; +use function array_key_exists; +use function array_values; +use function get_defined_constants; use ReflectionException; use ReflectionFunction; use Roave\BetterReflection\Reflector\ClassReflector; use Roave\BetterReflection\Reflector\Exception\IdentifierNotFound; use Roave\BetterReflection\Reflector\FunctionReflector; +use function strtoupper; final class Reflector { private $classReflector; private $functionReflector; + private $constants; public function __construct(ClassReflector $classReflector, FunctionReflector $functionReflector) { @@ -51,4 +56,20 @@ public function isFunctionInternal(string $name): bool return false; } } + + public function isConstantInternal(string $name): bool + { + if (null === $this->constants) { + $constants = get_defined_constants(true); + + unset($constants['user']); + + $this->constants = array_merge(...array_values($constants)); + + unset($constants); + } + + // TODO: find a better solution + return array_key_exists(strtoupper($name), $this->constants); + } } From 82edd033299bdaa9eba91436c9cc8a2785074a62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9o=20FIDRY?= Date: Sat, 17 Feb 2018 15:28:51 +0000 Subject: [PATCH 2/2] Fix CS --- src/Reflector.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Reflector.php b/src/Reflector.php index 06265ada..ff7df97c 100644 --- a/src/Reflector.php +++ b/src/Reflector.php @@ -14,14 +14,14 @@ namespace Humbug\PhpScoper; -use function array_key_exists; -use function array_values; -use function get_defined_constants; use ReflectionException; use ReflectionFunction; use Roave\BetterReflection\Reflector\ClassReflector; use Roave\BetterReflection\Reflector\Exception\IdentifierNotFound; use Roave\BetterReflection\Reflector\FunctionReflector; +use function array_key_exists; +use function array_values; +use function get_defined_constants; use function strtoupper; final class Reflector