Skip to content

Commit

Permalink
Merge pull request #47 from lmc-eu/feature/ecs-update
Browse files Browse the repository at this point in the history
Update ECS, backport removed sniffs
  • Loading branch information
OndraM committed Dec 7, 2020
2 parents 3619809 + 3cda75e commit ada6a50
Show file tree
Hide file tree
Showing 34 changed files with 1,080 additions and 31 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
<!-- There is always Unreleased section on the top. Subsections (Added, Changed, Fixed, Removed) should be added as needed. -->

## Unreleased
- Replace `Symplify\CodingStandard\Sniffs\Naming\[AbstractClassNameSniff, ClassNameSuffixByParentSniff, InterfaceNameSniff and TraitNameSniff]` with equivalent versions backported to this repository.

## 2.1.0 - 2020-11-25
- Add various dangerous function calls to list of forbidden functions.
Expand Down
28 changes: 19 additions & 9 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,17 @@
"require": {
"php": "^7.2",
"friendsofphp/php-cs-fixer": "^2.16.3",
"symplify/auto-bind-parameter": "<7.2.20",
"symplify/autowire-array-parameter": "<7.2.20",
"symplify/coding-standard": "<7.2.20",
"symplify/easy-coding-standard": "^7.2.3",
"symplify/package-builder": "<7.2.20",
"symplify/set-config-resolver": "<7.2.20",
"symplify/smart-file-system": "<7.2.20"
"slevomat/coding-standard": "^6.4.1",
"symplify/auto-bind-parameter": "<8.1.21",
"symplify/autowire-array-parameter": "<8.1.21",
"symplify/coding-standard": "<8.1.21",
"symplify/console-color-diff": "<8.1.21",
"symplify/easy-coding-standard": "<8.1.21",
"symplify/package-builder": "<8.1.21",
"symplify/parameter-name-guard": "<8.1.21",
"symplify/phpstan-extensions": "<8.1.21",
"symplify/set-config-resolver": "<8.1.21",
"symplify/smart-file-system": "<8.1.21"
},
"require-dev": {
"j13k/yaml-lint": "dev-master",
Expand All @@ -29,7 +33,10 @@
"phpunit/phpunit": "^7.1 || ^8.0"
},
"config": {
"sort-packages": true
"sort-packages": true,
"preferred-install": {
"squizlabs/php_codesniffer": "source"
}
},
"autoload": {
"psr-4": {
Expand All @@ -49,9 +56,12 @@
"@test"
],
"analyze": [
"vendor/bin/ecs check src/ tests/ -vv --ansi",
"vendor/bin/ecs check src/ tests/ --ansi",
"vendor/bin/phpstan.phar analyze -c phpstan.neon --ansi"
],
"fix": [
"./vendor/bin/ecs check ./src/ ./tests/ --ansi --fix"
],
"lint": [
"for FILE_NAME in *.yml *.yaml; do vendor/bin/yaml-lint \"$FILE_NAME\"; done",
"vendor/bin/yaml-sort-checker"
Expand Down
27 changes: 8 additions & 19 deletions easy-coding-standard.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,14 @@ imports:
services:
# Function http_build_query() should always have specified `$arg_separator` parameter
Lmc\CodingStandard\Fixer\SpecifyArgSeparatorFixer: ~
# Abstract class should have prefix "Abstract"
Lmc\CodingStandard\Sniffs\Naming\AbstractClassNameSniff: ~
# Classes should have suffix by theirs parent class/interface
Lmc\CodingStandard\Sniffs\Naming\ClassNameSuffixByParentSniff:
# Interface should have suffix "Interface"
Lmc\CodingStandard\Sniffs\Naming\InterfaceNameSniff: ~
# Trait should have suffix "Trait"
Lmc\CodingStandard\Sniffs\Naming\TraitNameSniff: ~

# Class and Interface names should be unique in a project, they should never be duplicated
PHP_CodeSniffer\Standards\Generic\Sniffs\Classes\DuplicateClassNameSniff: ~
Expand Down Expand Up @@ -250,25 +258,6 @@ services:
SlevomatCodingStandard\Sniffs\Exceptions\ReferenceThrowableOnlySniff: ~
# The @param, @return, @var and inline @var annotations should keep standard format
Symplify\CodingStandard\Fixer\Commenting\ParamReturnAndVarTagMalformsFixer: ~
# Abstract class should have prefix "Abstract"
Symplify\CodingStandard\Sniffs\Naming\AbstractClassNameSniff: ~
# Classes should have suffix by theirs parent class/interface
Symplify\CodingStandard\Sniffs\Naming\ClassNameSuffixByParentSniff:
defaultParentClassToSuffixMap:
'*Command': 'Command'
'*Controller': 'Controller'
'*Repository': 'Repository'
'*Presenter': 'Presenter'
'*Request': 'Request'
'*Response': 'Response'
'*FixerInterface': 'Fixer'
'*Sniff': 'Sniff'
'*Exception': 'Exception'
'*Handler': 'Handler'
# Interface should have suffix "Interface"
Symplify\CodingStandard\Sniffs\Naming\InterfaceNameSniff: ~
# Trait should have suffix "Trait"
Symplify\CodingStandard\Sniffs\Naming\TraitNameSniff: ~

parameters:
skip:
Expand Down
4 changes: 4 additions & 0 deletions phpstan.neon
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,14 @@ parameters:
paths:
- src/
- tests/
bootstrapFiles:
- vendor/squizlabs/php_codesniffer/autoload.php
- vendor/squizlabs/php_codesniffer/src/Util/Tokens.php
ignoreErrors:
- message: '#Parameter \#(2|3) \$(argumentStart|argumentEnd) of method PhpCsFixer\\Tokenizer\\Analyzer\\ArgumentsAnalyzer::getArgumentInfo\(\) expects int#'
path: %currentWorkingDirectory%/src/Fixer/SpecifyArgSeparatorFixer.php
- message: '#Parameter \#1 \$code of static method PhpCsFixer\\Tokenizer\\Tokens::fromCode\(\) expects string, string\|false given#'
path: %currentWorkingDirectory%/tests/Fixer/SpecifyArgSeparatorFixerTest.php
- message: '#Parameter \#1 \$filename of function file_get_contents expects string, string\|false given.#'
path: %currentWorkingDirectory%/tests/Fixer/SpecifyArgSeparatorFixerTest.php
checkMissingIterableValueType: false
2 changes: 1 addition & 1 deletion phpunit.xml.dist
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<phpunit
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd"
bootstrap="./vendor/autoload.php"
bootstrap="./vendor/squizlabs/php_codesniffer/tests/bootstrap.php"
colors="true"
>
<testsuites>
Expand Down
161 changes: 161 additions & 0 deletions src/Helper/Naming.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
<?php declare(strict_types=1);

/*
* Originally part of https://github.com/symplify/symplify
*
* MIT License
*
* (c) 2020 Tomas Votruba <tomas.vot@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/

namespace Lmc\CodingStandard\Helper;

use PHP_CodeSniffer\Files\File;
use SlevomatCodingStandard\Helpers\ClassHelper;
use SlevomatCodingStandard\Helpers\NamespaceHelper;
use SlevomatCodingStandard\Helpers\ReferencedNameHelper;
use SlevomatCodingStandard\Helpers\TokenHelper;

final class Naming
{
/**
* @var string
*/
private const NAMESPACE_SEPARATOR = '\\';

/**
* @var string[]
*/
private const CLASS_NAMES_BY_FILE_PATH = [];

/**
* @var mixed[][]
*/
private $referencedNamesByFilePath = [];

/**
* @var string[][]
*/
private $fqnClassNameByFilePathAndClassName = [];

public function getFileClassName(File $file): ?string
{
// get name by path
if (isset(self::CLASS_NAMES_BY_FILE_PATH[$file->path])) {
return self::CLASS_NAMES_BY_FILE_PATH[$file->path];
}

$classPosition = TokenHelper::findNext($file, T_CLASS, 1);
if ($classPosition === null) {
return null;
}

$className = ClassHelper::getFullyQualifiedName($file, $classPosition);

return ltrim($className, '\\');
}

public function getClassName(File $file, int $classNameStartPosition): string
{
$tokens = $file->getTokens();

$firstNamePart = $tokens[$classNameStartPosition]['content'];

// is class <name>
if ($this->isClassName($file, $classNameStartPosition)) {
$namespace = NamespaceHelper::findCurrentNamespaceName($file, $classNameStartPosition);
if ($namespace) {
return $namespace . '\\' . $firstNamePart;
}

return $firstNamePart;
}

$classNameParts = [];
$classNameParts[] = $firstNamePart;

$nextTokenPointer = $classNameStartPosition + 1;
while ($tokens[$nextTokenPointer]['code'] === T_NS_SEPARATOR) {
++$nextTokenPointer;
$classNameParts[] = $tokens[$nextTokenPointer]['content'];
++$nextTokenPointer;
}

$completeClassName = implode(self::NAMESPACE_SEPARATOR, $classNameParts);

$fqnClassName = $this->getFqnClassName($file, $completeClassName, $classNameStartPosition);
if ($fqnClassName !== '') {
return ltrim($fqnClassName, self::NAMESPACE_SEPARATOR);
}

return $completeClassName;
}

private function getFqnClassName(File $file, string $className, int $classTokenPosition): string
{
$referencedNames = $this->getReferencedNames($file);

foreach ($referencedNames as $referencedName) {
if (isset($this->fqnClassNameByFilePathAndClassName[$file->path][$className])) {
return $this->fqnClassNameByFilePathAndClassName[$file->path][$className];
}

$resolvedName = NamespaceHelper::resolveClassName(
$file,
$referencedName->getNameAsReferencedInFile(),
$classTokenPosition
);

if ($referencedName->getNameAsReferencedInFile() === $className) {
$this->fqnClassNameByFilePathAndClassName[$file->path][$className] = $resolvedName;

return $resolvedName;
}
}

return '';
}

/**
* As in:
* class <name>
*/
private function isClassName(File $file, int $position): bool
{
return (bool) $file->findPrevious(T_CLASS, $position, max(1, $position - 3));
}

/**
* @return mixed[]
*/
private function getReferencedNames(File $file): array
{
if (isset($this->referencedNamesByFilePath[$file->path])) {
return $this->referencedNamesByFilePath[$file->path];
}

$referencedNames = ReferencedNameHelper::getAllReferencedNames($file, 0);

$this->referencedNamesByFilePath[$file->path] = $referencedNames;

return $referencedNames;
}
}
Loading

0 comments on commit ada6a50

Please sign in to comment.