Skip to content

Commit

Permalink
WIP Add DTO analysis objects instead of arrays + fix some code review…
Browse files Browse the repository at this point in the history
… comments.
  • Loading branch information
veewee committed Dec 3, 2017
1 parent 88e4217 commit 9eb9cc8
Show file tree
Hide file tree
Showing 16 changed files with 728 additions and 265 deletions.
1 change: 1 addition & 0 deletions .php_cs.dist
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ $config = PhpCsFixer\Config::create()
'combine_consecutive_unsets' => true,
'compact_nullable_typehint' => true,
'explicit_indirect_variable' => true,
'fully_qualified_strict_types' => true,
'header_comment' => ['header' => $header],
'heredoc_to_nowdoc' => true,
'list_syntax' => ['syntax' => 'long'],
Expand Down
31 changes: 18 additions & 13 deletions src/Fixer/Import/FullyQualifiedStrictTypesFixer.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
use PhpCsFixer\FixerDefinition\FixerDefinition;
use PhpCsFixer\FixerDefinition\VersionSpecification;
use PhpCsFixer\FixerDefinition\VersionSpecificCodeSample;
use PhpCsFixer\Tokenizer\Analyzer\Analysis\NamespaceAnalysis;
use PhpCsFixer\Tokenizer\Analyzer\Analysis\NamespaceUseAnalysis;
use PhpCsFixer\Tokenizer\Analyzer\FunctionsAnalyzer;
use PhpCsFixer\Tokenizer\Analyzer\NamespacesAnalyzer;
use PhpCsFixer\Tokenizer\Analyzer\NamespaceUsesAnalyzer;
Expand Down Expand Up @@ -81,9 +83,12 @@ public function isCandidate(Tokens $tokens)
*/
protected function applyFix(\SplFileInfo $file, Tokens $tokens)
{
$fullNameOnly = function (array $info) { return $info['fullName']; };
$namespaces = array_map($fullNameOnly, (new NamespacesAnalyzer())->getDeclarations($tokens));
$useMap = array_map($fullNameOnly, (new NamespaceUsesAnalyzer())->getDeclarationsFromTokens($tokens));
$namespaces = array_map(function (NamespaceAnalysis $info) {
return $info->getFullName();
}, (new NamespacesAnalyzer())->getDeclarations($tokens));
$useMap = array_map(function (NamespaceUseAnalysis $info) {
return $info->getFullName();
}, (new NamespaceUsesAnalyzer())->getDeclarationsFromTokens($tokens));

if (!count($namespaces) && !count($useMap)) {
return;
Expand Down Expand Up @@ -114,18 +119,18 @@ private function fixFunctionArguments(Tokens $tokens, $index, array $namespaces,
$arguments = (new FunctionsAnalyzer())->getFunctionArguments($tokens, $index);

foreach ($arguments as $argument) {
if (!$argument['type'] || $argument['type_index_start'] < 0) {
if (!$argument->hasType()) {
continue;
}

$shortType = $this->detectShortType($argument['type'], $namespaces, $useMap);
if ($shortType === $argument['type']) {
$shortType = $this->detectShortType($argument->getType(), $namespaces, $useMap);
if ($shortType === $argument->getType()) {
continue;
}

$tokens->overrideRange(
$argument['type_index_start'],
$argument['type_index_end'],
$argument->getTypeIndexStart(),
$argument->getTypeIndexEnd(),
$this->generateTokensForShortType($shortType)
);
}
Expand All @@ -144,14 +149,14 @@ private function fixFunctionReturnType(Tokens $tokens, $index, array $namespaces
return;
}

$shortType = $this->detectShortType($returnType['type'], $namespaces, $useMap);
if ($shortType === $returnType['type']) {
$shortType = $this->detectShortType($returnType->getType(), $namespaces, $useMap);
if ($shortType === $returnType->getType()) {
return;
}

$tokens->overrideRange(
$returnType['start_index'],
$returnType['end_index'],
$returnType->getStartIndex(),
$returnType->getEndIndex(),
$this->generateTokensForShortType($shortType)
);
}
Expand Down Expand Up @@ -200,7 +205,7 @@ private function detectShortType($type, array $namespaces, array $useMap)
/**
* @param string $shortType
*
* @return array
* @return Token[]
*/
private function generateTokensForShortType($shortType)
{
Expand Down
34 changes: 21 additions & 13 deletions src/Fixer/Import/NoUnusedImportsFixer.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@
use PhpCsFixer\AbstractFixer;
use PhpCsFixer\FixerDefinition\CodeSample;
use PhpCsFixer\FixerDefinition\FixerDefinition;
use PhpCsFixer\Tokenizer\Analyzer\Analysis\NamespaceAnalysis;
use PhpCsFixer\Tokenizer\Analyzer\Analysis\NamespaceUseAnalysis;
use PhpCsFixer\Tokenizer\Analyzer\Analysis\StartEndTokenAwareAnalysis;
use PhpCsFixer\Tokenizer\Analyzer\NamespacesAnalyzer;
use PhpCsFixer\Tokenizer\Analyzer\NamespaceUsesAnalyzer;
use PhpCsFixer\Tokenizer\Token;
Expand Down Expand Up @@ -94,7 +97,7 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens)

/**
* @param string $content
* @param array $useDeclarations
* @param NamespaceUseAnalysis[] $useDeclarations
*
* @return array
*/
Expand All @@ -111,7 +114,7 @@ private function detectUseUsages($content, array $useDeclarations)

/**
* @param Tokens $tokens
* @param array $partials
* @param StartEndTokenAwareAnalysis[] $partials
*
* @return string
*/
Expand All @@ -123,7 +126,7 @@ private function generateCodeWithoutPartials(Tokens $tokens, array $partials)
$allowToAppend = true;

foreach ($partials as $partial) {
if ($partial['start'] <= $index && $index <= $partial['end']) {
if ($partial->getStartIndex() <= $index && $index <= $partial->getEndIndex()) {
$allowToAppend = false;

break;
Expand All @@ -147,17 +150,17 @@ private function removeUnusedUseDeclarations(Tokens $tokens, array $useDeclarati
}
}

private function removeUseDeclaration(Tokens $tokens, array $useDeclaration)
private function removeUseDeclaration(Tokens $tokens, NamespaceUseAnalysis $useDeclaration)
{
for ($index = $useDeclaration['end'] - 1; $index >= $useDeclaration['start']; --$index) {
for ($index = $useDeclaration->getEndIndex() - 1; $index >= $useDeclaration->getStartIndex(); --$index) {
$tokens->clearTokenAndMergeSurroundingWhitespace($index);
}

if ($tokens[$useDeclaration['end']]->equals(';')) {
$tokens->clearAt($useDeclaration['end']);
if ($tokens[$useDeclaration->getEndIndex()]->equals(';')) {
$tokens->clearAt($useDeclaration->getEndIndex());
}

$prevIndex = $useDeclaration['start'] - 1;
$prevIndex = $useDeclaration->getStartIndex() - 1;
$prevToken = $tokens[$prevIndex];

if ($prevToken->isWhitespace()) {
Expand All @@ -171,11 +174,11 @@ private function removeUseDeclaration(Tokens $tokens, array $useDeclaration)
$prevToken = $tokens[$prevIndex];
}

if (!isset($tokens[$useDeclaration['end'] + 1])) {
if (!isset($tokens[$useDeclaration->getEndIndex() + 1])) {
return;
}

$nextIndex = $tokens->getNonEmptySibling($useDeclaration['end'], 1);
$nextIndex = $tokens->getNonEmptySibling($useDeclaration->getEndIndex(), 1);
if (null === $nextIndex) {
return;
}
Expand Down Expand Up @@ -213,22 +216,27 @@ private function removeUseDeclaration(Tokens $tokens, array $useDeclaration)
}
}

/**
* @param Tokens $tokens
* @param NamespaceUseAnalysis[] $useDeclarations
* @param NamespaceAnalysis[] $namespaceDeclarations
*/
private function removeUsesInSameNamespace(Tokens $tokens, array $useDeclarations, array $namespaceDeclarations)
{
// safeguard for files with multiple namespaces to avoid breaking them until we support this case
if (1 !== count($namespaceDeclarations)) {
return;
}

$namespace = $namespaceDeclarations[0]['fullName'];
$namespace = $namespaceDeclarations[0]->getFullName();
$nsLength = strlen($namespace.'\\');

foreach ($useDeclarations as $useDeclaration) {
if ($useDeclaration['aliased']) {
if ($useDeclaration->isAliased()) {
continue;
}

$useDeclarationFullName = ltrim($useDeclaration['fullName'], '\\');
$useDeclarationFullName = ltrim($useDeclaration->getFullName(), '\\');

if (0 !== strpos($useDeclarationFullName, $namespace.'\\')) {
continue;
Expand Down
141 changes: 141 additions & 0 deletions src/Tokenizer/Analyzer/Analysis/ArgumentAnalysis.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
<?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\Tokenizer\Analyzer\Analysis;

/**
* @internal
*/
final class ArgumentAnalysis
{

/**
* The default value of the argument.
*
* @var string|null
*/
private $default;

/**
* The name of the argument.
*
* @var string
*/
private $name;

/**
* The index where the name is located in the supplied Tokens object.
*
* @var int
*/
private $nameIndex;

/**
* The type of the argument.
*
* @var string|null
*/
private $type;

/**
* @var int|null
*/
private $typeIndexStart;

/**
* @var int|null
*/
private $typeIndexEnd;

/**
* ArgumentAnalysis constructor.
* @param string $name
* @param int $nameIndex
* @param string|null $default
* @param string|null $type
* @param int|null $typeIndexStart
* @param int|null $typeIndexEnd
*/
public function __construct($name, $nameIndex, $default, $type, $typeIndexStart, $typeIndexEnd)
{
$this->name = (string) $name;
$this->nameIndex = (int) $nameIndex;
$this->default = $default ? (string) $default : null;
$this->type = $type ? (string) $type : null;
$this->typeIndexStart = $typeIndexStart ? (int) $typeIndexStart : null;
$this->typeIndexEnd = $typeIndexEnd ? (int) $typeIndexEnd : null;
}

/**
* @return null|string
*/
public function getDefault()
{
return $this->default;
}

/**
* @return bool
*/
public function hasDefault()
{
return null !== $this->default;
}

/**
* @return string
*/
public function getName()
{
return $this->name;
}

/**
* @return int
*/
public function getNameIndex()
{
return $this->nameIndex;
}

/**
* @return null|string
*/
public function getType()
{
return $this->type;
}

/**
* @return bool
*/
public function hasType()
{
return null !== $this->type;
}

/**
* @return int|null
*/
public function getTypeIndexStart()
{
return $this->typeIndexStart;
}

/**
* @return int|null
*/
public function getTypeIndexEnd()
{
return $this->typeIndexEnd;
}
}
Loading

0 comments on commit 9eb9cc8

Please sign in to comment.