-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
<?php | ||
|
||
/* | ||
* This file is part of PHP CS Fixer. | ||
* | ||
* (c) Fabien Potencier <fabien@symfony.com> | ||
* Dariusz Rumiński <dariusz.ruminski@gmail.com> | ||
* | ||
* This source file is subject to the MIT license that is bundled | ||
* with this source code in the file LICENSE. | ||
*/ | ||
|
||
namespace PhpCsFixer\Fixer\LanguageConstruct; | ||
|
||
use PhpCsFixer\AbstractFixer; | ||
use PhpCsFixer\FixerDefinition\FixerDefinition; | ||
use PhpCsFixer\FixerDefinition\VersionSpecification; | ||
use PhpCsFixer\FixerDefinition\VersionSpecificCodeSample; | ||
use PhpCsFixer\Tokenizer\CT; | ||
use PhpCsFixer\Tokenizer\Token; | ||
use PhpCsFixer\Tokenizer\Tokens; | ||
use PhpCsFixer\Tokenizer\TokensAnalyzer; | ||
use PhpCsFixer\Indicator\ClassyExistanceIndicator; | ||
|
||
/** | ||
* @author Dariusz Rumiński <dariusz.ruminski@gmail.com> | ||
*/ | ||
final class ClassKeywordFixer extends AbstractFixer | ||
{ | ||
/** | ||
* @var string[] | ||
*/ | ||
private $imports = array(); | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function getDefinition() | ||
{ | ||
return new FixerDefinition( | ||
'Converts FQCN strings to `*::class` keywords. Requires PHP >= 5.5.', | ||
array( | ||
new VersionSpecificCodeSample( | ||
'<?php | ||
use Foo\Bar\Baz; | ||
$className = Baz::class; | ||
', | ||
new VersionSpecification(50500) | ||
), | ||
) | ||
); | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function isCandidate(Tokens $tokens) | ||
{ | ||
return PHP_VERSION_ID >= 50500; | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
protected function applyFix(\SplFileInfo $file, Tokens $tokens) | ||
{ | ||
$indicator = new ClassyExistanceIndicator(); | ||
|
||
for ($index = $tokens->count() - 1; $index >= 0; --$index) { | ||
$token = $tokens[$index]; | ||
|
||
if ($token->isGivenKind(T_CONSTANT_ENCAPSED_STRING)) { | ||
$name = substr($token->getContent(), 1, -1); | ||
$name = ltrim($name, '\\'); | ||
$name = str_replace('\\\\', '\\', $name); | ||
|
||
if ($indicator->exists($name)) { | ||
try { | ||
$substitution = Tokens::fromCode("<?php echo \\$name::class;"); | ||
$substitution->clearRange(0, 2); | ||
$substitution[$substitution->getSize() - 1]->clear(); | ||
$substitution->clearEmptyTokens(); | ||
|
||
$token->clear(); | ||
$tokens->insertAt($index, $substitution); | ||
} catch (\Error $e) { | ||
var_dump("error with parsing class", $name); | ||
var_dump($e->getMessage()); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
<?php | ||
|
||
/* | ||
* This file is part of PHP CS Fixer. | ||
* | ||
* (c) Fabien Potencier <fabien@symfony.com> | ||
* Dariusz Rumiński <dariusz.ruminski@gmail.com> | ||
* | ||
* This source file is subject to the MIT license that is bundled | ||
* with this source code in the file LICENSE. | ||
*/ | ||
|
||
namespace PhpCsFixer\Indicator; | ||
|
||
/** | ||
* @internal | ||
*/ | ||
final class ClassyExistanceIndicator | ||
{ | ||
/** | ||
* @param string $name | ||
* | ||
* @return bool | ||
*/ | ||
public function exists($name) | ||
{ | ||
if (class_exists($name) || interface_exists($name) || trait_exists($name)) { | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
keradus
Author
Owner
|
||
$rc = new \ReflectionClass($name); | ||
|
||
return $rc->getName() === $name; | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
keradus
Author
Owner
|
||
} | ||
|
||
return false; | ||
} | ||
} |
5 comments
on commit 33be691
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(answering:
- 33be691#commitcomment-23106285
- [CodingStandard] ClassStringToClassCosntantFixer init deprecated-packages/symplify#262 (comment)
)
All rules are suppose to be context unaware. That means the fixer must rely only on code of single file passed for fixing. This fixer is violating that rule (that's why it's not in main repo), as it requires to be aware about whole fixing project files and deps to detect if given class exists or not.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you explain that in specific code? I don't understand this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let assume you have 2 files - Foo.php
(with Foo
class) and Bar.php
(with Bar
class),
then while fixing Foo.php
class, you have no idea does Bar
class exists or not in text-based file modifications. you even don't know that Bar
class exists.
This is being context-unaware. If you would know whole project files and code - you would be context-aware.
And then keep in mind that some context is vendor. so Bar
could come from vendor, that needs to be first installed from external source
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see.
I'd still have context unaware fixer that can fail in 1 % of cases and fixes the rest than my manuall work on 99 % of them.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
then it's good for one-time job, but not for continuous verification.
This won't work when php-cs-fixer is installed as
composer create-project ...
and run on another code base, will it?