Giter Site home page Giter Site logo

slevomat / coding-standard Goto Github PK

View Code? Open in Web Editor NEW
1.4K 28.0 167.0 5.54 MB

Slevomat Coding Standard for PHP_CodeSniffer provides many useful sniffs

License: MIT License

PHP 100.00%
php php7 php8 coding-standard code-style phpcs phpcodesniffer

coding-standard's Introduction

Slevomat Coding Standard

Latest version Downloads Build status Code coverage PHPStan

Slevomat Coding Standard for PHP_CodeSniffer provides sniffs that fall into three categories:

  • Functional - improving the safety and behaviour of code
  • Cleaning - detecting dead code
  • Formatting - rules for consistent code looks

Table of contents

  1. Alphabetical list of sniffs
  2. Installation
  3. How to run the sniffs
  1. Fixing errors automatically
  2. Suppressing sniffs locally
  3. Contributing

Alphabetical list of sniffs

๐Ÿ”ง = Automatic errors fixing

๐Ÿšง = Sniff check can be suppressed locally

Installation

The recommended way to install Slevomat Coding Standard is through Composer.

{
	"require-dev": {
		"slevomat/coding-standard": "~8.0"
	}
}

It's also recommended to install php-parallel-lint/php-parallel-lint which checks source code for syntax errors. Sniffs count on the processed code to be syntactically valid (no parse errors), otherwise they can behave unexpectedly. It is advised to run PHP-Parallel-Lint in your build tool before running PHP_CodeSniffer and exiting the build process early if PHP-Parallel-Lint fails.

How to run the sniffs

You can choose one of two ways to run only selected sniffs from the standard on your codebase:

Choose which sniffs to run

The recommended way is to write your own ruleset.xml by referencing only the selected sniffs. This is a sample ruleset.xml:

<?xml version="1.0"?>
<ruleset name="AcmeProject">
	<config name="installed_paths" value="../../slevomat/coding-standard"/><!-- relative path from PHPCS source location -->
	<rule ref="SlevomatCodingStandard.Arrays.TrailingArrayComma"/>
	<!-- other sniffs to include -->
</ruleset>

Then run the phpcs executable the usual way:

vendor/bin/phpcs --standard=ruleset.xml --extensions=php --tab-width=4 -sp src tests

Exclude sniffs you don't want to run

You can also mention Slevomat Coding Standard in your project's ruleset.xml and exclude only some sniffs:

<?xml version="1.0"?>
<ruleset name="AcmeProject">
	<rule ref="vendor/slevomat/coding-standard/SlevomatCodingStandard/ruleset.xml"><!-- relative path to your ruleset.xml -->
		<!-- sniffs to exclude -->
	</rule>
</ruleset>

However it is not a recommended way to use Slevomat Coding Standard, because your build can break when moving between minor versions of the standard (which can happen if you use ^ or ~ version constraint in composer.json). We regularly add new sniffs even in minor versions meaning your code won't most likely comply with new minor versions of the package.

Fixing errors automatically

Sniffs in this standard marked by the ๐Ÿ”ง symbol support automatic fixing of coding standard violations. To fix your code automatically, run phpcbf instead of phpcs:

vendor/bin/phpcbf --standard=ruleset.xml --extensions=php --tab-width=4 -sp src tests

Always remember to back up your code before performing automatic fixes and check the results with your own eyes as the automatic fixer can sometimes produce unwanted results.

Suppressing sniffs locally

Selected sniffs in this standard marked by the ๐Ÿšง symbol can be suppressed for a specific piece of code using an annotation. Consider the following example:

/**
 * @param int $max
 */
public function createProgressBar($max = 0): ProgressBar
{

}

The parameter $max could have a native int scalar typehint. But because the method in the parent class does not have this typehint, so this one cannot have it either. PHP_CodeSniffer shows a following error:

----------------------------------------------------------------------
FOUND 1 ERROR AFFECTING 1 LINE
----------------------------------------------------------------------
 67 | ERROR | [x] Method ErrorsConsoleStyle::createProgressBar()
    |       |     does not have native type hint for its parameter $max
    |       |     but it should be possible to add it based on @param
    |       |     annotation "int".
    |       |     (SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint)

If we want to suppress this error instead of fixing it, we can take the error code (SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint) and use it with a @phpcsSuppress annotation like this:

/**
 * @phpcsSuppress SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint
 * @param int $max
 */
public function createProgressBar($max = 0): ProgressBar
{

}

Contributing

To make this repository work on your machine, clone it and run these two commands in the root directory of the repository:

composer install
bin/phing

After writing some code and editing or adding unit tests, run phing again to check that everything is OK:

bin/phing

We are always looking forward to your bugreports, feature requests and pull requests. Thank you.

Code of Conduct

This project adheres to a Contributor Code of Conduct. By participating in this project and its community, you are expected to uphold this code.

coding-standard's People

Contributors

50bhan avatar aadmathijssen avatar alexndlm avatar arxeiss avatar bkdotcom avatar carusogabriel avatar derrabus avatar dg avatar donatj avatar grogy avatar grongor avatar jost125 avatar jrfnl avatar kukulich avatar majkl578 avatar mhujer avatar michnovka avatar nightlinus avatar ntzm avatar ondrejmirtes avatar paxal avatar pepakriz avatar rikap avatar schlndh avatar simpod avatar szepeviktor avatar thewilkybarkid avatar tysonandre avatar vasekpurchart avatar vrtak-cz avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

coding-standard's Issues

Notices are thrown because T_RETURN_TYPE is missing

Commit cf23871 causes phpcs to throw notices:

PHP Notice: Use of undefined constant T_RETURN_TYPE - assumed 'T_RETURN_TYPE' in /home/ubuntu/example/vendor/slevomat/coding-standard/SlevomatCodingStandard/Helpers/ReferencedNameHelper.php on line 121

Uses of traits are not registered

The SlevomatCodingStandard.Namespaces.MultipleUsesPerLine sniff does not register multiple uses of traits in class. Is that intentional?

This in combination with SlevomatCodingStandard.Namespaces.UnusedUses.UnusedUse sniff gives false hope for secure removal of unused use.

Example:

<?php

namespace Project;

use Package\TPhotoGallery;
use Package\TSeoInfo;

class CompetitionEntity 
{
    use TSeoInfo, TPhotoGallery;
}

When both mentioned sniffs are enabled, the UnusedUses will report TPhotoGallery as unused use available for automatic removal. The MultipleUsesPerLine does not register anything.

Unused private properties when using magic __get

Hi, I want to use magic method for simple properties in object like in the example bellow. You can access them using {$order->orderNumber} in template thanks to the @method annotation. With this approach it's super easy to write custom getter without breaking code in the template. It's somehow possible to take @method annotations into account? Or should I think about better approach? Thanks! :)

<?php

/**
 * @method getOrderNumber()
 */
class OrderDTO extends \Nette\Object
{

    private $orderNumber; //Warning: unused private element

    public function __construct(\App\Orders\Order $order)
    {
        $this->orderNumber = $order->getId();
    }

}

ReturnTypehintSpacingSniff - array return typehint is not checked

This method signature has whitespace between closing brace and return typehint colon. The sniff does not report this error.

public function createData(FooClass $foo) : array

Issue is limited only to array type, If the return typehint contains anything else, the error is reported.

Missing function doc comment error

Hi,
I have problem with Missing function doc comment.
When i have comment above a method, which i don't need, it properly returns error Method \App\Router\RouterFactory::createRouter() does not need documentation comment.

/**
 * @return RouteList
 */
public function createRouter(): RouteList

So i remove comment and it returns Missing function doc comment.

I don't know, where this error is located. I found it in PEAR_Sniffs_Commenting_FunctionCommentSniff, but i don't use this sniff and even when i remove whole slevomat coding standard, this problem disappear.

Can i fix it anyway?

Btw. I use erything but this slevomat coding standards

<rule ref="vendor/slevomat/coding-standard/SlevomatCodingStandard/ruleset.xml">
    <exclude name="SlevomatCodingStandard.Namespaces.FullyQualifiedClassNameAfterKeyword"/>
    <exclude name="SlevomatCodingStandard.Namespaces.FullyQualifiedExceptions"/>
    <exclude name="SlevomatCodingStandard.Namespaces.FullyQualifiedClassNameInAnnotation"/>
    <exclude name="SlevomatCodingStandard.Namespaces.UseOnlyWhitelistedNamespaces"/>
    <exclude name="SlevomatCodingStandard.Namespaces.AlphabeticallySortedUses"/>
    <!--<exclude name="SlevomatCodingStandard.Types.EmptyLinesAroundTypeBraces"/>-->
    <exclude name="SlevomatCodingStandard.Files.TypeNameMatchesFileName"/>
</rule>

TypeHintDeclaration with disabled enableNullableTypeHints does not work with optional parameters

The fixer for enableNullableTypeHints disabled tries to add = null to the parameter even if it is already there.

Minimal reproducible example:

<?php

class Foo
{

	/**
	 * @param string|null $baz
	 */
	public function bar($baz = null)
	{
		
	}

}

Is converted to:

<?php

class Foo
{

	/**
	 * @param string|null $baz
	 */
	public function bar(string $baz = null = null)
	{
		
	}

}

So it produces string $baz = null = null, which is obviously incorrect. I think it is needed to look if the null (or probably any other default value) is already present.

differencies in configuration properties

When playing with SlevomatCodingStandard.Files.TypeNameMatchesFileName sniff, I found that there is a difference in the way different properties are treated. Given configuration

<rule ref="SlevomatCodingStandard.Files.TypeNameMatchesFileName">
    <properties>
        <property name="rootNamespaces" type="array" value="
            src=>X,
            tests/src=>X\Tests,
        " />
        <property name="skipDirs" type="array" value="Exceptions," />
        <property name="extensions" type="array" value="php,phpt," />
    </properties>
</rule>

results in two rootNamespaces, one skipDirs, but three extensions (last one empty).

rootNamespaces, skipDirs are trimmed too, but there's no way how to use multi-line configuration (as for rootNamespaces) with extensions.

I'm not sure if that is a bug or expected behavior. I just found the multi-line array configuration more readable (git diff mainly).

phpcs result depending on SlevomatCodingStandard.Files.TypeNameMatchesFileName configuration

Hi,

I've just met strange behavior of subject's rule. When trying to configure my namespaces, I found that:

<rule ref="SlevomatCodingStandard.Files.TypeNameMatchesFileName">
    <properties>
        <property name="rootNamespaces" type="array" value="tests/src=>X\Tests,tests=>X\Tests,"/>
    </properties>
</rule>

works as expected. But this:

<rule ref="SlevomatCodingStandard.Files.TypeNameMatchesFileName">
    <properties>
        <property name="rootNamespaces" type="array" value="tests=>X\Tests,tests/src=>X\Tests,"/>
    </properties>
</rule>

results in an error. There's an example of configuration in documentation (README.md, line 180, I don't know how to link better, sorry), but it's not mentioning the importance of values order.

Expected behavior

Sniff should work regardless on configuration values order.

composer configuration
"slevomat/coding-standard": "^3.0"

PHPStorm inspections does not work with TypeNameMatchesFileNameSniff

When you use path checking rules (e.g. TypeNameMatchesFileNameSniff), PHPStorm CodeSniffer inspection will report false-positives because temporary file with incorrect path is used for validation.

See the PHPStorm issue: https://youtrack.jetbrains.com/issue/WI-30583

(I know this is not an issue of the sniffs or the coding standard itself, but I think it may be useful to have it noted here. Since the PHPStorm is widely used IDE I am probably not the last one to discover this problem.)

Unused use warning for class in @return

I get fillowing even when my use is specified in @return doc comment.

Type ReturnedClass is not used in this file (SlevomatCodingStandard.Namespaces.UnusedUses.UnusedUse)

Consider this:

use Some\Space\ReturnedClassFactory;
use Some\Space\ReturnedClass;

class MyClass {

    /**
     * Text
     * @param string $type
     * @return ReturnedClass
     */
    private function getWriter($type) {
        ...
        return ReturnedClassFactory::createWriter($type);
    }

}

false positive for UnusedPrivateElements writeOnlyProperty

There is a false positive for SlevomatCodingStandard.Classes.UnusedPrivateElements sniff when private property is used in a double-quoted string. The sniff is then reporting it as unused writeOnlyProperty.

<?php

class FalsePositiveWriteOnlyProperty
{
    private $dir;

    public function __construct($name)
    {
        $this->dir = dirname($name);
    }

    protected function buildIconPath($name)
    {
        return "$this->dir/$name.png"; // here the property is used
    }
}

Sniff AlphabeticallySortedUses sorts alphabetically also functions

I know this it not so common, but this sniff behaves differently then optimizing use statements for example in PhpStorm. I don't know if this is intentional so I'm noticing it here.

Expected order by this sniff (strict alphabetical):

use Doctrine\ORM\EntityManager;
use function GuzzleHttp\Psr7\str as format_http_message;
use GuzzleHttp\Exception\RequestException;

Optimized by PhpStorm (functions at the end):

use Doctrine\ORM\EntityManager;
use GuzzleHttp\Exception\RequestException;
use function GuzzleHttp\Psr7\str as format_http_message;

UnusedUses MismatchingCaseSensitivity on valid code

Example:

<?php declare(strict_types = 1);

namespace Hele\Sms;

use Nette\Http\Url;

class Test
{

    const URL = 'https://foo.com';  // line 10

    public function sendMessage()
    {
        $url = new Url(self::URL);
        $url->getAbsoluteUrl();
    }

}

lint output:

----------------------------------------------------------------------
FOUND 1 ERROR AFFECTING 1 LINE
----------------------------------------------------------------------
 10 | ERROR | Case of reference name URL and use statement Url do not
    |       | match
    |       | (SlevomatCodingStandard.Namespaces.UnusedUses.MismatchingCaseSensitivity)
----------------------------------------------------------------------

False Multiline array must have trailing comma

With next piece of code it shows false error "Multiline array must have trailing comma"

    return [
        //
    ];

It's just empty array with empty comment, a lot of this stubs are generated in Laravel framework and it's not violating standard.

Documentation

Please can you create full documentaion for all sniffs?

Dubious "Unused use" case

Hi.

Imagine a class like

<?php

namespace App;

use Other;


class One
{

    /**
     * @var Other\Two
     * @inject
     */
    public $property;

}

The injected property might be used somewhere else (let's pretend One is a magic class somewhow), but the real issue is that use Other is tagged as unused. I have the annotation parsing enabled for this sniff.

I think it assumes that because it is at the "root" and the annotation also starts with Other at the root so it is not necessary. However, this is not always the case. Imagine there would be a class \App\Other\Two. Then the use clause actually distinguishes between that and \Other\Two. I think the use here should only be declared useless if the annotation uses absolute namespace (starting with \)

I have created a little project you can use to check the various cases

git clone https://github.com/Fuco1/slevomat-example
cd slevomat-example
composer update
composer phpcs

Namespaces.ReferenceUsedNamesOnly & Throwable

Hi, can you tell me please what is the best way to solve the following problem? We want to check if Throwable is used absolutely in catch statements, same as other exceptions.

I know I can solve it simply using the specialExceptionNames property like this

<rule ref="SlevomatCodingStandard.Namespaces.ReferenceUsedNamesOnly">
    <properties>
        <property name="specialExceptionNames" type="array" value="
            Throwable
        "/>
    </properties>
</rule>

But wouldn't it be cleaner to have a condition for it in the sniff? Since Throwable is not really a "special case" it should imho have same behaviour as other exceptions and so should the other new exceptions in PHP7.

What do you think? How should this be solved? I'd like to discuss this before I send a PR and spend time writing tests.

False positive on UnusedUsesSniff

I have a use statement for GuzzleHttp\Promise. In my code I'm using a bare function from that namespace, as Promise\settle(). The UnusedUsesSniff is complaining that I'm not using GuzzleHttp\Promise, which I believe to be false.

I also tried use GuzzleHttp\Promise\settle and then using settle(), and I get an error from the sniff here too.

UnusedUses - invalid behaviour

use ArrayAccess;
use Countable;
use Iterator;

class NodeList implements ArrayAccess, Countable, Iterator
{

    public function count()
    {
    }

    public function current()
    {
    }

    public function next()
    {
    }

    public function key()
    {
    }

    public function valid()
    {
    }

    public function rewind()
    {
    }

    public function offsetExists($offset)
    {
    }

    public function offsetGet($offset)
    {
    }

    public function offsetSet($offset, $value)
    {
    }

    public function offsetUnset($offset)
    {
    }

}

CodeSniffer result is:

 11 | ERROR | [x] Type Iterator is not used in this file
    |       |     (SlevomatCodingStandard.Namespaces.UnusedUses.UnusedUse)

When I have changed order like this:

class NodeList implements Countable, Iterator, ArrayAccess
{

Result is:

 11 | ERROR | [x] Type ArrayAccess is not used in this file
    |       |     (SlevomatCodingStandard.Namespaces.UnusedUses.UnusedUse)

Can you help me please?

TypeHintDeclarationSniff incorrectly reports about missing typehint when parameter docBlock contains union of two types, one is traversable and the second one does not specify the traversable type

FOUND 3 ERRORS AFFECTING 3 LINES
----------------------------------------------------------------------
 273 | ERROR | [x] Method \Vanio\Stdlib\Uri::withQuery() does not
     |       |     have parameter type hint for its parameter $query
     |       |     but it should be possible to add it based on
     |       |     @param annotation "string|array".

I think it should report only when the annotation is something like "array|string[]". Am I right?
I guess you would probably typed it like string|mixed[] and then it would be probably quite OK but I don't use this notation for mixed arrays. I've excluded "MissingTraversableParameterTypeHintSpecification, MissingTraversablePropertyTypeHintSpecification and MissingTraversableReturnTypeHintSpecification" but still consider this sniff very handy.

BTW thanks for open sourcing this repo.

PDOException should (or should not?) be referenced via a fully qualified name

When checking this snippet of code in my code base, in setup_info.php, I get inconsistent advice:

// Attempt to connect to the database via PDO
try
{
    $test_pdo_db = new PDO("mysql:host=$db_host; port=$db_port; dbname=$db_name; charset=utf8mb4", $db_user, $db_pwd);
    $variables['pdo_conn_test'] = true;
    $variables['pdo_server_ver'] = $test_pdo_db->getAttribute(constant("PDO::ATTR_SERVER_VERSION"));
}
catch (\PDOException $e)
{
    $err_msg = "Unable to connect to the " . $db_type .
               " Database.<br>\n Database Error: ".
               $e->getMessage() . "<br>\n";
    $variables['pdo_conn_test'] = false;
    $variables['pdo_conn_err'] = $err_msg;
}

# [03/13/17 09:39:22 PM] [[email protected]] [tki] $ php vendor/bin/phpcs --standard=vendor/bin/phpcs.xml --ignore=templates,vendor . -s

FILE: /var/www/html/tki/setup_info.php
----------------------------------------------------------------------
FOUND 1 ERROR AFFECTING 1 LINE
----------------------------------------------------------------------
 150 | ERROR | Exception PDOException **should be referenced via a fully
     |       | qualified name.**
     |       | (SlevomatCodingStandard.Namespaces.FullyQualifiedExceptions.NonFullyQualifiedException)
----------------------------------------------------------------------

Time: 5.11 secs; Memory: 26Mb

( EDIT setup_info.php to remove \ in front of \PDOException )
# [03/13/17 09:39:49 PM] [[email protected]] [tki] $ php vendor/bin/phpcs --standard=vendor/bin/phpcs.xml --ignore=templates,vendor . -s

FILE: /var/www/html/tki/setup_info.php
----------------------------------------------------------------------
FOUND 1 ERROR AFFECTING 1 LINE
----------------------------------------------------------------------
 150 | ERROR | [x] Type \PDOException **should not be referenced via a
     |       |     fully qualified name**, but via an unqualified name without
     |       |     the leading \, because the file does not have a namespace
     |       |     and the type cannot be put in a use statement.
     |       |     (SlevomatCodingStandard.Namespaces.ReferenceUsedNamesOnly.ReferenceViaFullyQualifiedNameWithoutNamespace)
----------------------------------------------------------------------
PHPCBF CAN FIX THE 1 MARKED SNIFF VIOLATIONS AUTOMATICALLY
----------------------------------------------------------------------

Time: 5.65 secs; Memory: 26Mb

UnusedPrivateElementsSniff incorrectly reports about methods returning references

----------------------------------------------------------------------
FOUND 1 ERROR AFFECTING 1 LINE
----------------------------------------------------------------------
 121 | ERROR | Class UniversalJsonDeserializer contains unused
     |       | private method &().
----------------------------------------------------------------------

It expects the method name to consist of one token but in case of returning reference it consists of two where the first one is the reference (T_BITWISE_AND).

Documentation of sniffs

Hello,

any plans to create documentation for these awesome sniffs? I mean documenation in standard format like UnnecessaryStringConcatStandard doc.

When I use this sniff in my ruleset.xml and run

phpcs --standard=/etc/php/ruleset.xml --generator=HTML > coding-standards.html

documentation in HTML will be generated.
screen shot 2016-10-19 at 16 48 33

Thank you!

PHP Fatal error when running against my project

Installed using:

        "slevomat/coding-standard": "^2.0",
        "consistence/coding-standard": "^0.13",

and php composer.phar update / php composer.phar install.

Then edited vendor/bin/phpcs.xml to add:

    <rule ref="vendor/consistence/coding-standard/Consistence/ruleset.xml" />
    <rule ref="vendor/slevomat/coding-standard/SlevomatCodingStandard/ruleset.xml" />

Not sure I understand the nature of the error, but its entirely possible that I installed wrong, am running it incorrectly, or that my project (with some code from php-4 days) is triggering an unusual corner case.

$ php vendor/bin/phpcs --standard=vendor/bin/phpcs.xml . --ignore=templates,vendor
PHP Fatal error:  Uncaught SlevomatCodingStandard\Sniffs\Namespaces\NoKeywordsException: Sniff SlevomatCodingStandard\Sniffs\Namespaces\FullyQualifiedClassNameAfterKeywordSniff requires an array of keywords set in property keywordsToCheck in /var/www/html/tki/vendor/slevomat/coding-standard/SlevomatCodingStandard/Sniffs/Namespaces/FullyQualifiedClassNameAfterKeywordSniff.php:42
Stack trace:
#0 /var/www/html/tki/vendor/squizlabs/php_codesniffer/CodeSniffer.php(1480): SlevomatCodingStandard\Sniffs\Namespaces\FullyQualifiedClassNameAfterKeywordSniff->register()
#1 /var/www/html/tki/vendor/squizlabs/php_codesniffer/CodeSniffer.php(595): PHP_CodeSniffer->populateTokenListeners()
#2 /var/www/html/tki/vendor/squizlabs/php_codesniffer/CodeSniffer/CLI.php(956): PHP_CodeSniffer->initStandard(Array, Array, Array)
#3 /var/www/html/tki/vendor/squizlabs/php_codesniffer/CodeSniffer/CLI.php(113): PHP_CodeSniffer_CLI->process()
#4 /var/www/html/tki/vendor/squizlabs/php_codesniffer/scripts/phpcs(25): PHP_CodeSniffer_CLI->runphpcs()
#5 {main}
   in /var/www/html/tki/vendor/slevomat/coding-standard/SlevomatCodingStandard/Sniffs/Namespaces/FullyQualifiedClassNameAfterKeywordSniff.php on line 42

Unused use warning for class in type comment

As far as I know, there is no support for parsing type comments by SlevomatCodingStandard.Namespaces.UnusedUses.

Consider this, which will be found as error SlevomatCodingStandard.Namespaces.UnusedUses.UnusedUse

use Bar\Something;
use Foo\MyType;

...

/* @var $variable MyType */
$variable = Something::create();

Could support for that be added please?

TypeHintDeclarationSniff: support for @inheritdoc

Since this sniff does not support @inheritdoc for looking up @param and @return annotations in superclasses, when I extend framework classes I am forced to copy/paste annotations from there to my classes, or the sniff will report errors. Good examples might be Symfony forms or Doctrine types. Is there any intention to support this annotation, or does it pose significant issues/overhead?

TypeHintDeclarationSniff: optional nullable parameter reported as useless even if @param has description

I am using version 2.4.4 of the coding standard, with phpcs 2.9.1.

Ruleset:

<rule ref="vendor/slevomat/coding-standard/SlevomatCodingStandard/Sniffs/TypeHints/TypeHintDeclarationSniff.php" />
  <rule ref="SlevomatCodingStandard.TypeHints.TypeHintDeclaration">
    <properties>
        <property name="enableEachParameterAndReturnInspection" value="true" />
    </properties>
</rule>
class TestClass
{

    /**
     * @param string|null $param2 Has description
     * @param string|null $param3 Has description
     */
    public function method(string $param1 = "", ?string $param2 = null, ?string $param3 = null): void
    {
    }
}

results in:

FILE: /var/www/TestClass.php
----------------------------------------------------------------------
FOUND 1 ERROR AFFECTING 1 LINE
----------------------------------------------------------------------
 31 | ERROR | [x] Method
    |       |     \TestClass::method()
    |       |     has useless @param annotation for parameter
    |       |     $param3.
----------------------------------------------------------------------
PHPCBF CAN FIX THE 1 MARKED SNIFF VIOLATIONS AUTOMATICALLY
----------------------------------------------------------------------

NOTE: If I remove $param3, the same error is found for $param2. Looks like it only happens for the last parameter of the list. Not sure if related to the nullability or to the default value.

This seems related to #165 (BTW, thanks for fixing that and providing a tagged release so quickly!), probably an uncovered edge case.

TypeHints.TypeHintDeclaration and traversableTypeHints

Hi.

I'm not sure how to configure this. I only got it working if I set fully qualified types in the codesniffer configuration and then use the same fully qualified type in the @var annotation. Is this expected behaviour? Shouldn't it infer the types based on the use declarations? Surely that is possible because the UnusedUses sniff does the resolutions somehow.

TypeHintDeclarationSniff settings

I am on PHP 7.1, but I put this in my ruleset.xml for testing purposes:

<rule ref="SlevomatCodingStandard.TypeHints.TypeHintDeclaration">
    <properties>
        <property name="enableNullableTypeHints" value="false"/>
        <property name="enableVoidTypeHint" value="false"/>
    </properties>
</rule>

This however doesn't seem to have any effect, even though I have nullable types and void returns in my codebase. Shouldn't it scream at me, or is there something I am missing?

[2.0-dev] Unused use when used only as nullable return type

When use is used only as nullable return type hint, CS thinks that it is unused (2.0-dev - latest):

<?php

declare(strict_types = 1);

namespace Driveto\AppBundle\Catalog;

use DateTimeImmutable;

class Foo
{

	public function getDeleted($entity): ?DateTimeImmutable
	{
		return $entity->getDeleted();
	}

}

TypeHintDeclarationSniff : Useless annotation reported even if it's needed to document a specific parameter

I am using version 2.4.3 of the coding standard, with phpcs 2.9.1.

My ruleset:

<?xml version="1.0"?>
    <rule ref="vendor/slevomat/coding-standard/SlevomatCodingStandard/Sniffs/TypeHints/TypeHintDeclarationSniff.php" />
  
    <rule ref="SlevomatCodingStandard.TypeHints.TypeHintDeclaration">
        <properties>
            <!-- If I don't set this property, @param annotations are never reported as useless even when they have no comment -->
            <property name="enableEachParameterAndReturnInspection" value="true" />
        </properties>
    </rule>
</ruleset>

The class I'm using to test:

<?php
declare(strict_types=1);

class SomeClass
{
    /**
     * @param string $param1 I want to document this parameter, but not the other
     * @return void I want to document this return value
     */
    public function method(string $param1, int $param2): void
    {
    }
}

I'm getting this output:

FILE: /var/www/SomeClass.php
----------------------------------------------------------------------
FOUND 1 ERROR AFFECTING 1 LINE
----------------------------------------------------------------------
 12 | ERROR | [x] \SomeClass::method() has
    |       |     useless @param annotation for parameter $param1.
----------------------------------------------------------------------
PHPCBF CAN FIX THE 1 MARKED SNIFF VIOLATIONS AUTOMATICALLY
----------------------------------------------------------------------

Time: 27ms; Memory: 6Mb

But I would expect the violation not to be there since, as it's done correctly for @return annotations, they are not reported as useless if there is an actual comment after them.

Is this a bug or am I misusing the sniff?

Disable ReferenceViaFullyQualifiedName for certain types

Type \DateTime should not be referenced via a fully qualified name, but via a use statement (SlevomatCodingStandard.Namespaces.ReferenceUsedNamesOnly.ReferenceViaFullyQualifiedName)

Is there a way to disable it for this type? Thanks!

Apply TypeNameMatchesFileName to .phpt files

I'm trying apply SlevomatCodingStandard.Files.TypeNameMatchesFileName to all .php and .phpt files in my project but its working only for .php files.

Error:

 11 | ERROR   | Class name MyProject\Test\ExampleTest does not match
    |         | filepath
    |         | /Users/radek/WebServer/MyProject/tests/ExampleTest.phpt.
    |         | (SlevomatCodingStandard.Files.TypeNameMatchesFileName.NoMatchBetweenTypeNameAndFileName)

My ruleset looks like this::

<rule ref="SlevomatCodingStandard.Files.TypeNameMatchesFileName">
        <properties>
            <property name="rootNamespaces" type="array"
                      value="src/MyProject=>MyProject,tests=>MyProject\Test"/>
        </properties>
</rule>

This ruleset doesn't work too:

<rule ref="SlevomatCodingStandard.Files.TypeNameMatchesFileName">
        <properties>
            <property name="rootNamespaces" type="array"
                      value="src/MyProject=>MyProject,tests=>MyProject\Test"/>
            <property name="extensions" type="array" value="php,phpt"/>
            <property name="skipDirs" type="array" value="tests"/>
        </properties>
</rule>

File tests\ExampleTest.phpt looks like this:

<?php

namespace MyProject\Test;

use Nette\DI\Container;
use Tester\Assert;
use Tester\TestCase;

$container = include __DIR__ . '/bootstrap.php';

class ExampleTest extends TestCase
{

    /**
     * @var Container
     */
    private $container;

    public function __construct(Container $container)
    {
        $this->container = $container;
    }

    public function setUp()
    {
    }

    public function testSomething()
    {
        Assert::true(is_array($this->container->getParameters()));
    }
}

$test = new ExampleTest($container);
$test->run();

Composer conflicts in requirements when following README in download

Your requirements could not be resolved to an installable set of packages.

Problem 1
- consistence/coding-standard 0.10 requires squizlabs/php_codesniffer ~2.5.0 -> satisfiable by squizlabs/php_codesniffer[2.5.0, 2.5.1].
- consistence/coding-standard 0.10.1 requires squizlabs/php_codesniffer ~2.5.1 -> satisfiable by squizlabs/php_codesniffer[2.5.1].
- Can only install one of: squizlabs/php_codesniffer[2.8.1, 2.5.0].
- Can only install one of: squizlabs/php_codesniffer[2.8.1, 2.5.1].
- slevomat/coding-standard 2.0 requires squizlabs/php_codesniffer ^2.8.1 -> satisfiable by squizlabs/php_codesniffer[2.8.1].
- Installation request for slevomat/coding-standard ^2.0 -> satisfiable by slevomat/coding-standard[2.0].
- Installation request for consistence/coding-standard ^0.10 -> satisfiable by consistence/coding-standard[0.10, 0.10.1].

False positiv for missingReturnTypeHint

I'm getting a missingReturnTypeHint error on this function:

    /**
     * Returns a map of possible roles for a user with descriptions
     *
     * @return array
     */
    public static function getRoles(): array
    {
        return self::getTypeMap(
            self::ROLE_ADMIN,
            self::ROLE_USER
        );
    }

I'm using the php7 branch.

Class contains unused private method when I use array_map

I have a class like as:

class AwesomeClass {

    public function foo(): array
    {
        $a = array_map([$this, 'bar'], [1, 2, 3]);
    }

    private function bar(array $data): array
    {
        return $data;
    }
}

And I got error:

Class AwesomeClass contains unused private method bar().
(SlevomatCodingStandard.Classes.UnusedPrivateElements.UnusedMethod)

NoKeywordsException

Doesn't seem to work out of the box.

I added the 2 deps to composer, added the sample ruleset, and ran the example command, then got the error below.

dneilsen:rhino-debug davidneilsen$ vendor/bin/parallel-lint classes
PHP 7.0.0 | 10 parallel jobs
..........                                                   10/10 (100 %)


Checked 10 files in 0 seconds
No syntax error found
dneilsen:rhino-debug davidneilsen$ vendor/bin/phpcs --standard=ruleset.xml --extensions=php --encoding=utf-8 --tab-width=4 -sp classes
PHP Fatal error:  Uncaught SlevomatCodingStandard\Sniffs\Namespaces\NoKeywordsException: Sniff SlevomatCodingStandard\Sniffs\Namespaces\FullyQualifiedClassNameAfterKeywordSniff requires an array of keywords set in property keywordsToCheck in /Users/davidneilsen/work/rhino/rhino-debug/vendor/slevomat/coding-standard/SlevomatCodingStandard/Sniffs/Namespaces/FullyQualifiedClassNameAfterKeywordSniff.php:43
Stack trace:
#0 /Users/davidneilsen/work/rhino/rhino-debug/vendor/squizlabs/php_codesniffer/CodeSniffer.php(1394): SlevomatCodingStandard\Sniffs\Namespaces\FullyQualifiedClassNameAfterKeywordSniff->register()
#1 /Users/davidneilsen/work/rhino/rhino-debug/vendor/squizlabs/php_codesniffer/CodeSniffer.php(561): PHP_CodeSniffer->populateTokenListeners()
#2 /Users/davidneilsen/work/rhino/rhino-debug/vendor/squizlabs/php_codesniffer/CodeSniffer/CLI.php(818): PHP_CodeSniffer->initStandard(Array, Array)
#3 /Users/davidneilsen/work/rhino/rhino-debug/vendor/squizlabs/php_codesniffer/CodeSniffer/CLI.php(95): PHP_CodeSniffer_CLI->process()
 in /Users/davidneilsen/work/rhino/rhino-debug/vendor/slevomat/coding-standard/SlevomatCodingStandard/Sniffs/Namespaces/FullyQualifiedClassNameAfterKeywordSniff.php on line 43

Fatal error: Uncaught SlevomatCodingStandard\Sniffs\Namespaces\NoKeywordsException: Sniff SlevomatCodingStandard\Sniffs\Namespaces\FullyQualifiedClassNameAfterKeywordSniff requires an array of keywords set in property keywordsToCheck in /Users/davidneilsen/work/rhino/rhino-debug/vendor/slevomat/coding-standard/SlevomatCodingStandard/Sniffs/Namespaces/FullyQualifiedClassNameAfterKeywordSniff.php:43
Stack trace:
#0 /Users/davidneilsen/work/rhino/rhino-debug/vendor/squizlabs/php_codesniffer/CodeSniffer.php(1394): SlevomatCodingStandard\Sniffs\Namespaces\FullyQualifiedClassNameAfterKeywordSniff->register()
#1 /Users/davidneilsen/work/rhino/rhino-debug/vendor/squizlabs/php_codesniffer/CodeSniffer.php(561): PHP_CodeSniffer->populateTokenListeners()
#2 /Users/davidneilsen/work/rhino/rhino-debug/vendor/squizlabs/php_codesniffer/CodeSniffer/CLI.php(818): PHP_CodeSniffer->initStandard(Array, Array)
#3 /Users/davidneilsen/work/rhino/rhino-debug/vendor/squizlabs/php_codesniffer/CodeSniffer/CLI.php(95): PHP_CodeSniffer_CLI->process()
 in /Users/davidneilsen/work/rhino/rhino-debug/vendor/slevomat/coding-standard/SlevomatCodingStandard/Sniffs/Namespaces/FullyQualifiedClassNameAfterKeywordSniff.php on line 43

DeclareStrictTypes fails with TypeError

<rule ref="SlevomatCodingStandard.TypeHints.DeclareStrictTypes">
    <properties>
        <property name="spacesCountAroundEqualsSign" value="1"/>
    </properties>
</rule>

TypeError: str_repeat() expects parameter 2 to be integer, string given in path/vendor/slevomat/coding-standard/SlevomatCodingStandard/Sniffs/TypeHints/DeclareStrictTypesSniff.php on line 101

It works if you add an (int) cast to that line. But then there is also another problem with phpcbf, which cannot handle spacesCountAroundEqualsSign=0 and ends with ERROR. (caused by a conflicting sniff)

I can prepare a PR if you want.

Installing globally?

Is it possible to install this package globally and have it work via the command line when not in a folder?

For example, I have the PHPCS sublime plugin which runs on save. I want to use this over the default PSR2 ruleset. But I believe I would need to install this globally to get it to work properly.

Any thoughts?

Something enforces long type hint parameter

160 | ERROR | [ ] Expected type hint "integer"; found "int" for $positionId

/**
 * @param int $positionId
 * @return void
 */
public function handleRelease(int $positionId): void

Same ruleset as here #121

False positives with multiple interface inheritance

<?php declare(strict_types = 1);

namespace Hele\Type\Enum;

use Hele\Type\Comparable;
use Hele\Type\Type;

interface Enum extends Type, Comparable
{

    public static function getAvailableValues(): array;

}

Result:

FOUND 1 ERROR AFFECTING 1 LINE
----------------------------------------------------------------------
 5 | ERROR | [x] Type Hele\Type\Comparable is not used in this file
   |       |     (SlevomatCodingStandard.Namespaces.UnusedUses.UnusedUse)
----------------------------------------------------------------------

False positives with *Error types

Newly introduced checking of *Error types in 1.1 has false positives, when a class is named *Error, but is not part of PHP's internal errors.

What's worse is that even PHP has class(es?) which are named like this, but are not an "exception".
In our code base I ran into:

$xml = @simplexml_load_string($result);
if (!($xml instanceof SimpleXMLElement) || libxml_get_last_error() instanceof LibXMLError) {
    // ...
}

which then reports error on LibXMLError, which is just a "normal" class.

This could have probably occurred with *Exception as well, although it is probably less likely.

I think, there should be a configurable list of types which are not "exceptions" - similar to the configurations of special exception names, which provide inverse functionality.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.