├── .github
├── PULL_REQUEST_TEMPLATE.md
└── workflows
│ └── ci.yml
├── .license
├── GlueStreamSpecific
├── Sniffs
│ └── Classes
│ │ ├── AbstractStringInConstantOnlySniff.php
│ │ └── DependencyProviderStringInConstantOnlySniff.php
└── ruleset.xml
├── LICENSE
├── README.md
├── Spryker
├── Sniffs
│ ├── AbstractSniffs
│ │ ├── AbstractApiClassDetectionSprykerSniff.php
│ │ ├── AbstractClassDetectionSprykerSniff.php
│ │ ├── AbstractMethodAnnotationSniff.php
│ │ └── AbstractSprykerSniff.php
│ ├── Arrays
│ │ └── DisallowImplicitArrayCreationSniff.php
│ ├── Classes
│ │ ├── ClassFileNameSniff.php
│ │ ├── MethodArgumentDefaultValueSniff.php
│ │ ├── MethodDeclarationSniff.php
│ │ ├── MethodTypeHintSniff.php
│ │ ├── PropertyDefaultValueSniff.php
│ │ ├── ReturnTypeHintSniff.php
│ │ └── SelfAccessorSniff.php
│ ├── Commenting
│ │ ├── AttributesSniff.php
│ │ ├── DisallowArrayTypeHintSyntaxSniff.php
│ │ ├── DocBlockApiAnnotationSniff.php
│ │ ├── DocBlockConstSniff.php
│ │ ├── DocBlockConstructorSniff.php
│ │ ├── DocBlockInheritSniff.php
│ │ ├── DocBlockNoEmptySniff.php
│ │ ├── DocBlockNoInlineAlignmentSniff.php
│ │ ├── DocBlockParamAllowDefaultValueSniff.php
│ │ ├── DocBlockParamArraySniff.php
│ │ ├── DocBlockParamNotJustNullSniff.php
│ │ ├── DocBlockParamSniff.php
│ │ ├── DocBlockPipeSpacingSniff.php
│ │ ├── DocBlockReturnNullSniff.php
│ │ ├── DocBlockReturnNullableTypeSniff.php
│ │ ├── DocBlockReturnSelfSniff.php
│ │ ├── DocBlockReturnTagSniff.php
│ │ ├── DocBlockReturnVoidSniff.php
│ │ ├── DocBlockSniff.php
│ │ ├── DocBlockStructureSniff.php
│ │ ├── DocBlockTagGroupingSniff.php
│ │ ├── DocBlockTagIterableSniff.php
│ │ ├── DocBlockTagOrderSniff.php
│ │ ├── DocBlockTagSniff.php
│ │ ├── DocBlockTestGroupAnnotation2Sniff.php
│ │ ├── DocBlockTestGroupAnnotationSniff.php
│ │ ├── DocBlockThrowsSniff.php
│ │ ├── DocBlockTypeOrderSniff.php
│ │ ├── DocBlockVarNotJustNullSniff.php
│ │ ├── DocBlockVarSniff.php
│ │ ├── DocCommentSniff.php
│ │ ├── FileDocBlockSniff.php
│ │ ├── FullyQualifiedClassNameInDocBlockSniff.php
│ │ ├── InlineDocBlockSniff.php
│ │ ├── SprykerAnnotationSniff.php
│ │ ├── SprykerConstantsSniff.php
│ │ └── TypeHintSniff.php
│ ├── ControlStructures
│ │ ├── ConditionalExpressionOrderSniff.php
│ │ ├── ControlStructureSpacingSniff.php
│ │ ├── DisallowCloakingCheckSniff.php
│ │ ├── ElseIfDeclarationSniff.php
│ │ └── NoInlineAssignmentSniff.php
│ ├── DependencyProvider
│ │ └── FacadeNotInBridgeReturnedSniff.php
│ ├── Factory
│ │ ├── CreateVsGetMethodsSniff.php
│ │ ├── NoPrivateMethodsSniff.php
│ │ └── OneNewPerMethodSniff.php
│ ├── Formatting
│ │ ├── ArrayDeclarationSniff.php
│ │ └── MethodSignatureParametersLineBreakMethodSniff.php
│ ├── Internal
│ │ ├── SprykerBridgeSniff.php
│ │ ├── SprykerDisallowFunctionsSniff.php
│ │ ├── SprykerFacadeSniff.php
│ │ ├── SprykerNoDemoshopSniff.php
│ │ └── SprykerPreferStaticOverSelfSniff.php
│ ├── MethodAnnotation
│ │ ├── ConfigMethodAnnotationSniff.php
│ │ ├── EntityManagerMethodAnnotationSniff.php
│ │ ├── FacadeMethodAnnotationSniff.php
│ │ ├── FactoryMethodAnnotationSniff.php
│ │ ├── QueryContainerMethodAnnotationSniff.php
│ │ └── RepositoryMethodAnnotationSniff.php
│ ├── Namespaces
│ │ ├── FunctionNamespaceSniff.php
│ │ ├── SprykerNamespaceSniff.php
│ │ ├── SprykerNoCrossNamespaceSniff.php
│ │ ├── SprykerNoPyzSniff.php
│ │ ├── UseStatementSniff.php
│ │ └── UseWithAliasingSniff.php
│ ├── PHP
│ │ ├── DeclareStrictTypesAfterFileDocSniff.php
│ │ ├── DisallowFunctionsSniff.php
│ │ ├── DisallowTrailingCommaInSingleLineSniff.php
│ │ ├── ExitSniff.php
│ │ ├── NoIsNullSniff.php
│ │ ├── NotEqualSniff.php
│ │ ├── PhpSapiConstantSniff.php
│ │ ├── PreferCastOverFunctionSniff.php
│ │ ├── RemoveFunctionAliasSniff.php
│ │ ├── ShortCastSniff.php
│ │ └── SingleQuoteSniff.php
│ ├── Testing
│ │ ├── AssertPrimitivesSniff.php
│ │ ├── ExpectExceptionSniff.php
│ │ └── MockSniff.php
│ └── WhiteSpace
│ │ ├── CommaSpacingSniff.php
│ │ ├── ConcatenationSpacingSniff.php
│ │ ├── DocBlockSpacingSniff.php
│ │ ├── EmptyEnclosingLineSniff.php
│ │ ├── EmptyLinesSniff.php
│ │ ├── FunctionSpacingSniff.php
│ │ ├── ImplicitCastSpacingSniff.php
│ │ ├── MemberVarSpacingSniff.php
│ │ ├── MethodSpacingSniff.php
│ │ ├── NamespaceSpacingSniff.php
│ │ ├── ObjectAttributeSpacingSniff.php
│ │ └── TernarySpacingSniff.php
├── Tools
│ ├── SniffsAndTests.php
│ └── Tokenizer.php
├── Traits
│ ├── BasicsTrait.php
│ ├── BridgeTrait.php
│ ├── CommentingTrait.php
│ ├── NamespaceTrait.php
│ ├── SignatureTrait.php
│ └── UseStatementsTrait.php
└── ruleset.xml
├── SprykerStrict
├── Sniffs
│ └── TypeHints
│ │ ├── ParameterTypeHintSniff.php
│ │ ├── PropertyTypeHintSniff.php
│ │ └── ReturnTypeHintSniff.php
└── ruleset.xml
├── bin
├── tokenize
├── tokenize.bat
└── tokenize.php
├── composer.json
├── docs
├── README.md
├── generate.php
└── sniffs.md
├── phpcs.xml
├── phpstan.neon
└── tests
├── Spryker
└── Sniffs
│ ├── AllSniffTest.php
│ ├── Commenting
│ ├── DisallowArrayTypeHintSyntaxSniffTest.php
│ ├── DocBlockConstSniffTest.php
│ ├── DocBlockParamAllowDefaultValueSniffTest.php
│ ├── DocBlockParamArraySniffTest.php
│ ├── DocBlockReturnNullSniffTest.php
│ ├── DocBlockReturnNullableTypeSniffTest.php
│ ├── DocBlockReturnTagSniffTest.php
│ ├── DocBlockReturnVoidSniffTest.php
│ ├── DocBlockThrowsSniffTest.php
│ ├── DocBlockVarSniffTest.php
│ ├── FullyQualifiedClassNameInDocBlockSniffTest.php
│ ├── InlineDocBlockSniffTest.php
│ └── TypeHintSniffTest.php
│ ├── ControlStructures
│ └── DisallowCloakingCheckSniffTest.php
│ ├── Formatting
│ └── MethodSignatureParametersLineBreakMethodSniffTest.php
│ ├── Internal
│ └── SprykerPreferStaticOverSelfSniffTest.php
│ ├── Namespaces
│ └── UseStatementSniffTest.php
│ ├── PHP
│ └── DeclareStrictTypesAfterFileDocSniffTest.php
│ └── WhiteSpace
│ ├── EmptyEnclosingLineSniffTest.php
│ └── EmptyLinesSniffTest.php
├── TestCase.php
├── _data
├── All
│ ├── after.php
│ └── before.php
├── DeclareStrictTypesAfterFileDoc
│ ├── after.php
│ └── before.php
├── DisallowArrayTypeHintSyntax
│ ├── after.php
│ └── before.php
├── DisallowCloakingCheck
│ ├── after.php
│ └── before.php
├── DocBlockConst
│ ├── after.php
│ └── before.php
├── DocBlockParamAllowDefaultValue
│ ├── after.php
│ └── before.php
├── DocBlockParamArray
│ ├── after.php
│ └── before.php
├── DocBlockReturnNull
│ ├── after.php
│ └── before.php
├── DocBlockReturnNullableType
│ ├── after.php
│ └── before.php
├── DocBlockReturnTag
│ ├── after.php
│ └── before.php
├── DocBlockReturnVoid
│ ├── after.php
│ └── before.php
├── DocBlockThrows
│ ├── after.php
│ └── before.php
├── DocBlockVar
│ ├── after.php
│ └── before.php
├── EmptyEnclosingLine
│ ├── after.php
│ └── before.php
├── EmptyLines
│ ├── after.php
│ └── before.php
├── FullyQualifiedClassNameInDocBlock
│ ├── after.php
│ └── before.php
├── InlineDocBlock
│ ├── after.php
│ └── before.php
├── MethodSignatureParametersLineBreakMethod
│ ├── after.php
│ └── before.php
├── SprykerPreferStaticOverSelf
│ ├── after.php
│ └── before.php
├── TypeHint
│ ├── after.php
│ └── before.php
└── UseStatement
│ ├── after.php
│ └── before.php
├── bootstrap.php
├── generate.php
├── old
├── bootstrap.php
└── files
│ ├── Architecture
│ ├── WhitespaceComma.php
│ ├── WhitespaceCommaBefore.php
│ └── WhitespaceCommaPass.php
│ ├── Commenting
│ ├── DocBlockApiAnnotationMissingInFacade.php
│ ├── DocBlockApiDocBlockMissingInFacade.php
│ ├── DocBlockApiIgnoreClassPass.php
│ ├── DocBlockApiPass.php
│ └── DocBlockSingleLinePass.php
│ └── Namespaces
│ ├── UseInAlphabeticalOrderPass.php
│ └── UseWithLeadingBackslashFail.php
└── xmllint.sh
/.github/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | ## PR Description
2 | Add a meaningful description here that will let us know what you want to fix with this PR or what functionality you want to add.
3 |
4 | ## Steps before you submit a PR
5 | - Please add tests for the code you add if it's possible.
6 | - Please check out our contribution guide: https://docs.spryker.com/docs/dg/dev/code-contribution-guide.html
7 | - Add a `contribution-license-agreement.txt` file with the following content:
8 | `I hereby agree to Spryker\'s Contribution License Agreement in https://github.com/spryker/code-sniffer/blob/HASH_OF_COMMIT_YOU_ARE_BASING_YOUR_BRANCH_FROM_MASTER_BRANCH/CONTRIBUTING.md.`
9 |
10 | This is a mandatory step to make sure you are aware of the license agreement and agree to it. `HASH_OF_COMMIT_YOU_ARE_BASING_YOUR_BRANCH_FROM_MASTER_BRANCH` is a hash of the commit you are basing your branch from the master branch. You can take it from commits list of master branch before you submit a PR.
11 |
12 | ## Checklist
13 | - [x] I agree with the Code Contribution License Agreement in CONTRIBUTING.md
14 |
--------------------------------------------------------------------------------
/.github/workflows/ci.yml:
--------------------------------------------------------------------------------
1 | name: CI
2 |
3 | on:
4 | pull_request:
5 | push:
6 | branches:
7 | - master
8 | workflow_dispatch:
9 |
10 | jobs:
11 | validation:
12 | runs-on: ubuntu-22.04
13 | strategy:
14 | fail-fast: false
15 | matrix:
16 | php-version:
17 | - '8.1'
18 | - '8.3'
19 |
20 | steps:
21 | - name: Setup PHP
22 | uses: shivammathur/setup-php@v2
23 | with:
24 | php-version: ${{ matrix.php-version }}
25 | extensions: mbstring, intl, pdo_mysql
26 |
27 | - uses: actions/checkout@v3
28 |
29 | - name: Get Composer Cache Directory
30 | id: composer-cache
31 | run: |
32 | echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
33 |
34 | - uses: actions/cache@v3
35 | with:
36 | path: ${{ steps.composer-cache.outputs.dir }}
37 | key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
38 | restore-keys: |
39 | ${{ runner.os }}-composer-
40 |
41 | - name: Validate composer.json and composer.lock
42 | run: composer validate
43 |
44 | - name: Composer install
45 | run: composer install --optimize-autoloader
46 |
47 | - name: Run tests
48 | run: composer test
49 |
50 | - name: PHPStan checks
51 | run: composer stan
52 |
53 | - name: CodeStyle checks
54 | run: composer cs-check
55 |
56 | prefer-lowest:
57 | runs-on: ubuntu-22.04
58 | strategy:
59 | fail-fast: false
60 | matrix:
61 | php-version:
62 | - '8.1'
63 |
64 | steps:
65 | - name: Setup PHP
66 | uses: shivammathur/setup-php@v2
67 | with:
68 | php-version: ${{ matrix.php-version }}
69 | extensions: mbstring, intl, pdo_mysql
70 |
71 | - uses: actions/checkout@v3
72 |
73 | - name: Get Composer Cache Directory
74 | id: composer-cache
75 | run: |
76 | echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
77 |
78 | - uses: actions/cache@v3
79 | with:
80 | path: ${{ steps.composer-cache.outputs.dir }}
81 | key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
82 | restore-keys: |
83 | ${{ runner.os }}-composer-
84 |
85 | - name: Validate composer.json and composer.lock
86 | run: composer validate
87 |
88 | xml-validation:
89 | runs-on: ubuntu-22.04
90 | steps:
91 | - name: Install xmllint tool
92 | run: |
93 | sudo apt-get update
94 | sudo apt-get install -y libxml2-utils
95 |
96 | - name: Setup PHP
97 | uses: shivammathur/setup-php@v2
98 | with:
99 | php-version: '8.2'
100 |
101 | - uses: actions/checkout@v3
102 |
103 | - name: Get Composer Cache Directory
104 | id: composer-cache
105 | run: |
106 | echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
107 |
108 | - uses: actions/cache@v3
109 | with:
110 | path: ${{ steps.composer-cache.outputs.dir }}
111 | key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
112 | restore-keys: |
113 | ${{ runner.os }}-composer-
114 |
115 | - name: Composer install
116 | run: composer install --optimize-autoloader
117 |
118 | - name: XML checks
119 | run: composer xml
120 |
--------------------------------------------------------------------------------
/.license:
--------------------------------------------------------------------------------
1 | /**
2 | * MIT License
3 | * For full license information, please view the LICENSE file that was distributed with this source code.
4 | */
5 |
--------------------------------------------------------------------------------
/GlueStreamSpecific/Sniffs/Classes/AbstractStringInConstantOnlySniff.php:
--------------------------------------------------------------------------------
1 | findNext(T_CONSTANT_ENCAPSED_STRING, $stackPtr);
31 | $tokens = $phpcsFile->getTokens();
32 |
33 | if (!$this->isRuleApplicable($phpcsFile)) {
34 | return;
35 | }
36 |
37 | if (!$tokenIndex) {
38 | return;
39 | }
40 |
41 | if ($tokens[$tokenIndex]['level'] === 1) {
42 | return;
43 | }
44 |
45 | $error = '%s string should be introduced as a class or module constant.';
46 | $data = [
47 | $tokens[$stackPtr]['content'],
48 | ];
49 | $phpcsFile->addError($error, $stackPtr, 'NoMatch', $data);
50 | }
51 |
52 | /**
53 | * @param \PHP_CodeSniffer\Files\File $phpCsFile
54 | *
55 | * @return bool
56 | */
57 | abstract protected function isRuleApplicable(File $phpCsFile): bool;
58 | }
59 |
--------------------------------------------------------------------------------
/GlueStreamSpecific/Sniffs/Classes/DependencyProviderStringInConstantOnlySniff.php:
--------------------------------------------------------------------------------
1 | getClassName($phpCsFile);
22 | $hasCorrectSuffix = (substr($className, -18) === 'DependencyProvider');
23 |
24 | return $hasCorrectSuffix;
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/GlueStreamSpecific/ruleset.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Glue specific Coding Standard (experimental).
5 |
6 | All sniffs in ./Sniffs will be auto loaded
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016-present Spryker Systems GmbH
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/Spryker/Sniffs/Arrays/DisallowImplicitArrayCreationSniff.php:
--------------------------------------------------------------------------------
1 | getFilename();
25 | if ($this->hasLegacyImplicitCreation($fileName)) {
26 | return;
27 | }
28 |
29 | parent::process($phpcsFile, $stackPtr);
30 | }
31 |
32 | /**
33 | * @param string $fileName
34 | *
35 | * @return bool
36 | */
37 | protected function hasLegacyImplicitCreation(string $fileName): bool
38 | {
39 | if (strpos($fileName, DIRECTORY_SEPARATOR . 'config_') !== false || strpos($fileName, DIRECTORY_SEPARATOR . 'config.') !== false) {
40 | return true;
41 | }
42 | if (strpos($fileName, DIRECTORY_SEPARATOR . 'cronjobs' . DIRECTORY_SEPARATOR) !== false) {
43 | return true;
44 | }
45 |
46 | return false;
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/Spryker/Sniffs/Classes/ClassFileNameSniff.php:
--------------------------------------------------------------------------------
1 |
22 | * @author Marc McIntyre
23 | * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
24 | * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
25 | * @version Release: @package_version@
26 | * @link http://pear.php.net/package/PHP_CodeSniffer
27 | */
28 | class ClassFileNameSniff extends AbstractSprykerSniff
29 | {
30 | /**
31 | * @inheritDoc
32 | */
33 | public function register(): array
34 | {
35 | return [
36 | T_CLASS,
37 | T_INTERFACE,
38 | ];
39 | }
40 |
41 | /**
42 | * @inheritDoc
43 | */
44 | public function process(File $phpcsFile, $stackPtr): void
45 | {
46 | $fullPath = basename($phpcsFile->getFilename());
47 | $fileName = substr($fullPath, 0, strrpos($fullPath, '.') ?: 0);
48 | if ($fileName === '') {
49 | // No filename probably means STDIN, so we can't do this check.
50 | return;
51 | }
52 |
53 | $tokens = $phpcsFile->getTokens();
54 |
55 | $previous = $phpcsFile->findPrevious([T_CLASS, T_INTERFACE], $stackPtr - 1);
56 | if ($previous) {
57 | // Probably more than a single declaration per file, we only check first one then.
58 | return;
59 | }
60 | $declaredNameIndex = $phpcsFile->findNext(T_STRING, $stackPtr);
61 | if ($tokens[$declaredNameIndex]['content'] === $fileName) {
62 | return;
63 | }
64 | $error = '%s name "%s" doesn\'t match filename, expected "%s"';
65 | $data = [
66 | ucfirst($tokens[$stackPtr]['content']),
67 | $tokens[$declaredNameIndex]['content'],
68 | $fileName,
69 | ];
70 | $phpcsFile->addError($error, $stackPtr, 'NoMatch', $data);
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/Spryker/Sniffs/Classes/MethodTypeHintSniff.php:
--------------------------------------------------------------------------------
1 | getTokens();
35 |
36 | $openParenthesisIndex = $phpcsFile->findNext(T_OPEN_PARENTHESIS, $stackPtr + 1);
37 | $closeParenthesisIndex = $tokens[$openParenthesisIndex]['parenthesis_closer'];
38 |
39 | $colonIndex = $phpcsFile->findNext(Tokens::$emptyTokens, $closeParenthesisIndex + 1, null, true);
40 | if (!$colonIndex) {
41 | return;
42 | }
43 |
44 | $startIndex = $phpcsFile->findNext(Tokens::$emptyTokens, $colonIndex + 1, $colonIndex + 3, true);
45 | if (!$startIndex) {
46 | return;
47 | }
48 |
49 | $lastIndex = null;
50 | $j = $startIndex;
51 | $extractedUseStatement = '';
52 | while (true) {
53 | if (!$this->isGivenKind([T_NS_SEPARATOR, T_STRING, T_RETURN_TYPE], $tokens[$j])) {
54 | break;
55 | }
56 |
57 | $lastIndex = $j;
58 | $extractedUseStatement .= $tokens[$j]['content'];
59 | ++$j;
60 | }
61 |
62 | if ($lastIndex === null) {
63 | return;
64 | }
65 |
66 | $extractedClassName = ltrim($extractedUseStatement, '\\');
67 | if ($extractedClassName !== $this->getCurrentClassName($phpcsFile)) {
68 | return;
69 | }
70 |
71 | $fix = $phpcsFile->addFixableError('Own class/interface should be referred to as "self".', $startIndex, 'WrongSelf');
72 | if (!$fix) {
73 | return;
74 | }
75 |
76 | $phpcsFile->fixer->replaceToken($startIndex, 'self');
77 | }
78 |
79 | /**
80 | * @param \PHP_CodeSniffer\Files\File $phpCsFile
81 | *
82 | * @return string
83 | */
84 | protected function getCurrentClassName(File $phpCsFile): string
85 | {
86 | $fullClassName = parent::getClassName($phpCsFile);
87 |
88 | return substr($fullClassName, strrpos($fullClassName, '\\') + 1);
89 | }
90 | }
91 |
--------------------------------------------------------------------------------
/Spryker/Sniffs/Classes/PropertyDefaultValueSniff.php:
--------------------------------------------------------------------------------
1 | findPrevious(T_WHITESPACE, $stackPtr - 1, null, true);
34 | if (!$visibilityIndex) {
35 | return;
36 | }
37 |
38 | $tokens = $phpcsFile->getTokens();
39 | if (!$this->isGivenKind([T_PUBLIC, T_PRIVATE, T_PROTECTED, T_ABSTRACT], $tokens[$visibilityIndex])) {
40 | return;
41 | }
42 |
43 | $semicolonIndex = $phpcsFile->findNext(T_SEMICOLON, $stackPtr + 1);
44 | if (!$semicolonIndex || $semicolonIndex === $stackPtr + 1) {
45 | return;
46 | }
47 |
48 | $defaultValueIndex = $phpcsFile->findPrevious(T_WHITESPACE, $semicolonIndex - 1, $stackPtr + 1, true);
49 | if (!$defaultValueIndex || $tokens[$defaultValueIndex]['code'] !== T_NULL) {
50 | return;
51 | }
52 |
53 | $fix = $phpcsFile->addFixableError('Unnecessary default value for `' . $tokens[$stackPtr]['content'] . '`', $defaultValueIndex, 'Unnecessary');
54 | if (!$fix) {
55 | return;
56 | }
57 |
58 | $phpcsFile->fixer->beginChangeset();
59 | for ($i = $stackPtr + 1; $i < $semicolonIndex; $i++) {
60 | $phpcsFile->fixer->replaceToken($i, '');
61 | }
62 | $phpcsFile->fixer->endChangeset();
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/Spryker/Sniffs/Commenting/AttributesSniff.php:
--------------------------------------------------------------------------------
1 | findNext(Tokens::$emptyTokens, $stackPointer + 1, null, true);
35 | if (!$nextIndex) {
36 | return;
37 | }
38 |
39 | $tokens = $phpCsFile->getTokens();
40 |
41 | if ($tokens[$nextIndex]['code'] === T_NS_SEPARATOR) {
42 | return;
43 | }
44 |
45 | $phpCsFile->addError('FQCN expected for attribute', $nextIndex, 'ExpectedFQCN');
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/Spryker/Sniffs/Commenting/DocBlockConstructorSniff.php:
--------------------------------------------------------------------------------
1 | getTokens();
38 |
39 | $nextIndex = $phpcsFile->findNext(Tokens::$emptyTokens, $stackPtr + 1, null, true);
40 | if ($tokens[$nextIndex]['content'] !== '__construct' && $tokens[$nextIndex]['content'] !== '__destruct') {
41 | return;
42 | }
43 |
44 | $docBlockEndIndex = $this->findRelatedDocBlock($phpcsFile, $stackPtr);
45 | if (!$docBlockEndIndex) {
46 | return;
47 | }
48 |
49 | $tokens = $phpcsFile->getTokens();
50 |
51 | $docBlockStartIndex = $tokens[$docBlockEndIndex]['comment_opener'];
52 |
53 | $firstLineIndex = $phpcsFile->findNext(T_DOC_COMMENT_STRING, $docBlockStartIndex, $docBlockEndIndex);
54 | if (!$firstLineIndex || $tokens[$firstLineIndex]['line'] !== $tokens[$docBlockStartIndex]['line'] + 1) {
55 | return;
56 | }
57 |
58 | if (!preg_match('/^\w+ (constructor|destructor)\.$/i', $tokens[$firstLineIndex]['content'])) {
59 | return;
60 | }
61 |
62 | $fix = $phpcsFile->addFixableError('Doc Block has unneeded header line.', $firstLineIndex, 'UnneededNoise');
63 | if (!$fix) {
64 | return;
65 | }
66 |
67 | $phpcsFile->fixer->beginChangeset();
68 |
69 | $phpcsFile->fixer->replaceToken($firstLineIndex, '');
70 |
71 | $index = $firstLineIndex;
72 | while ($tokens[$index - 1]['line'] === $tokens[$firstLineIndex]['line']) {
73 | $index--;
74 | $phpcsFile->fixer->replaceToken($index, '');
75 | }
76 | $index = $firstLineIndex;
77 | while ($tokens[$index + 1]['line'] === $tokens[$firstLineIndex]['line']) {
78 | $index++;
79 | $phpcsFile->fixer->replaceToken($index, '');
80 | }
81 |
82 | $phpcsFile->fixer->endChangeset();
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/Spryker/Sniffs/Commenting/DocBlockNoEmptySniff.php:
--------------------------------------------------------------------------------
1 | getTokens();
34 |
35 | if (empty($tokens[$stackPtr]['comment_closer'])) {
36 | return;
37 | }
38 |
39 | $endIndex = $tokens[$stackPtr]['comment_closer'];
40 |
41 | $this->assertNonEmptyDocBlock($phpcsFile, $stackPtr, $endIndex);
42 | $this->assertNoEmptyTag($phpcsFile, $stackPtr, $endIndex);
43 | }
44 |
45 | /**
46 | * @param \PHP_CodeSniffer\Files\File $phpcsFile
47 | * @param int $stackPtr
48 | * @param int $endIndex
49 | *
50 | * @return void
51 | */
52 | protected function assertNonEmptyDocBlock(File $phpcsFile, int $stackPtr, int $endIndex): void
53 | {
54 | $nextIndex = $phpcsFile->findNext([T_WHITESPACE, T_DOC_COMMENT_WHITESPACE, T_DOC_COMMENT_STAR], $stackPtr + 1, $endIndex - 1, true);
55 | if ($nextIndex) {
56 | return;
57 | }
58 |
59 | $fix = $phpcsFile->addFixableError('There should be no empty docblocks.', $stackPtr, 'Superfluous');
60 | if ($fix) {
61 | for ($i = $stackPtr; $i <= $endIndex; $i++) {
62 | $phpcsFile->fixer->replaceToken($i, '');
63 | }
64 | }
65 | }
66 |
67 | /**
68 | * @param \PHP_CodeSniffer\Files\File $phpcsFile
69 | * @param int $stackPtr
70 | * @param int $endIndex
71 | *
72 | * @return void
73 | */
74 | protected function assertNoEmptyTag(File $phpcsFile, int $stackPtr, int $endIndex): void
75 | {
76 | $tokens = $phpcsFile->getTokens();
77 |
78 | $index = $stackPtr;
79 | while ($index < $endIndex) {
80 | $nextIndex = $phpcsFile->findNext([T_DOC_COMMENT_STRING], $index + 1, $endIndex);
81 | if (!$nextIndex) {
82 | return;
83 | }
84 | $index = $nextIndex;
85 |
86 | if (empty($tokens[$index]['content']) || $tokens[$index]['content'] !== '@') {
87 | continue;
88 | }
89 |
90 | $fix = $phpcsFile->addFixableError('Empty Doc Block Tag', $index, 'Empty');
91 | if (!$fix) {
92 | continue;
93 | }
94 |
95 | $phpcsFile->fixer->replaceToken($index, '');
96 | }
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/Spryker/Sniffs/Commenting/DocBlockNoInlineAlignmentSniff.php:
--------------------------------------------------------------------------------
1 | getTokens();
35 |
36 | if ($tokens[$stackPtr]['code'] === T_DOC_COMMENT_STRING) {
37 | $this->checkDescription($phpcsFile, $stackPtr);
38 | }
39 | if ($tokens[$stackPtr]['code'] === T_DOC_COMMENT_TAG) {
40 | $this->checkTag($phpcsFile, $stackPtr);
41 | }
42 | }
43 |
44 | /**
45 | * @param \PHP_CodeSniffer\Files\File $phpcsFile
46 | * @param int $stackPtr
47 | *
48 | * @return void
49 | */
50 | protected function checkTag(File $phpcsFile, int $stackPtr): void
51 | {
52 | $tokens = $phpcsFile->getTokens();
53 |
54 | $followingWhitespace = (int)$phpcsFile->findNext(T_DOC_COMMENT_WHITESPACE, $stackPtr + 1, $stackPtr + 2);
55 | if (!$followingWhitespace || $tokens[$followingWhitespace]['line'] !== $tokens[$stackPtr]['line']) {
56 | return;
57 | }
58 |
59 | // Skip for file doc blocks
60 | $namespaceStatement = $this->getNamespaceStatement($phpcsFile);
61 | if (!$namespaceStatement || $stackPtr < $namespaceStatement['start']) {
62 | return;
63 | }
64 |
65 | $content = $tokens[$followingWhitespace]['content'];
66 | if (strpos($content, ' ') === false || $content === ' ') {
67 | return;
68 | }
69 |
70 | $fix = $phpcsFile->addFixableError('There should be no additional whitespace around doc block tag types.', $stackPtr, 'WhitespaceAroundTypes');
71 | if ($fix) {
72 | $phpcsFile->fixer->replaceToken($followingWhitespace, ' ');
73 | }
74 | }
75 |
76 | /**
77 | * @param \PHP_CodeSniffer\Files\File $phpcsFile
78 | * @param int $stackPtr
79 | *
80 | * @return void
81 | */
82 | protected function checkDescription(File $phpcsFile, int $stackPtr): void
83 | {
84 | $tokens = $phpcsFile->getTokens();
85 |
86 | $content = $tokens[$stackPtr]['content'];
87 |
88 | if (!preg_match('/\s\s+/', $content)) {
89 | return;
90 | }
91 |
92 | $fix = $phpcsFile->addFixableError('There should be no inline alignment in doc blocks descriptions.', $stackPtr, 'DocBlockInlineAlignment');
93 | if ($fix) {
94 | $newContent = preg_replace('/\s\s+/', ' ', $content);
95 | $phpcsFile->fixer->replaceToken($stackPtr, $newContent);
96 | }
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/Spryker/Sniffs/Commenting/DocBlockParamNotJustNullSniff.php:
--------------------------------------------------------------------------------
1 | getTokens();
42 |
43 | $docBlockEndIndex = $this->findRelatedDocBlock($phpCsFile, $stackPointer);
44 |
45 | if (!$docBlockEndIndex) {
46 | return;
47 | }
48 |
49 | $methodSignature = $this->getMethodSignature($phpCsFile, $stackPointer);
50 | if (!$methodSignature) {
51 | return;
52 | }
53 |
54 | $docBlockStartIndex = $tokens[$docBlockEndIndex]['comment_opener'];
55 |
56 | $paramCount = 0;
57 | for ($i = $docBlockStartIndex + 1; $i < $docBlockEndIndex; $i++) {
58 | if ($tokens[$i]['type'] !== 'T_DOC_COMMENT_TAG') {
59 | continue;
60 | }
61 | if (!in_array($tokens[$i]['content'], ['@param'], true)) {
62 | continue;
63 | }
64 |
65 | if (empty($methodSignature[$paramCount])) {
66 | continue;
67 | }
68 | $paramCount++;
69 |
70 | $classNameIndex = $i + 2;
71 |
72 | if ($tokens[$classNameIndex]['type'] !== 'T_DOC_COMMENT_STRING') {
73 | // Let another sniffer take care of the missing type
74 | continue;
75 | }
76 |
77 | $content = $tokens[$classNameIndex]['content'];
78 |
79 | $appendix = '';
80 | $spaceIndex = strpos($content, ' ');
81 | if ($spaceIndex) {
82 | $appendix = substr($content, $spaceIndex);
83 | $content = substr($content, 0, $spaceIndex);
84 | }
85 | if (!$content || $content !== 'null') {
86 | continue;
87 | }
88 |
89 | $phpCsFile->addError('"null" as only param type does not make sense', $classNameIndex, 'NotJustNull');
90 | }
91 | }
92 | }
93 |
--------------------------------------------------------------------------------
/Spryker/Sniffs/Commenting/DocBlockPipeSpacingSniff.php:
--------------------------------------------------------------------------------
1 | getTokens();
34 |
35 | $content = $tokens[$stackPtr]['content'];
36 |
37 | $description = '';
38 | $hint = $content;
39 | if (strpos($hint, ' ') !== false) {
40 | [$hint, $description] = explode(' ', $content, 2);
41 | }
42 |
43 | // Bugfix for https://github.com/squizlabs/PHP_CodeSniffer/issues/2613
44 | $trailingWhitespace = '';
45 | if (!$description && $this->isInlineDocBlock($phpcsFile, $stackPtr) && preg_match('#(\s+)$#', $content, $matches)) {
46 | $trailingWhitespace = $matches[1];
47 | }
48 |
49 | if (strpos($hint, '|') === false) {
50 | return;
51 | }
52 |
53 | $pieces = explode('|', $hint);
54 |
55 | $hints = [];
56 | foreach ($pieces as $piece) {
57 | $hints[] = trim($piece);
58 | }
59 |
60 | $desc = ltrim($description);
61 |
62 | while ($desc && mb_substr($desc, 0, 1) === '|') {
63 | $desc = ltrim(mb_substr($desc, 1));
64 |
65 | $pos = mb_strpos($desc, ' ');
66 | if ($pos > 0) {
67 | $hints[] = trim(mb_substr($desc, 0, $pos));
68 | $desc = ltrim(mb_substr($desc, $pos));
69 | } else {
70 | $hints[] = $desc;
71 | $desc = '';
72 | }
73 | }
74 |
75 | if ($desc !== '') {
76 | $desc = ' ' . $desc;
77 | }
78 |
79 | $newContent = implode('|', $hints) . $desc . $trailingWhitespace;
80 |
81 | if ($newContent !== $content) {
82 | $fix = $phpcsFile->addFixableError('There should be no space around pipes in doc blocks.', $stackPtr, 'InvalidSpaceAroundPipes');
83 | if ($fix) {
84 | $phpcsFile->fixer->replaceToken($stackPtr, $newContent);
85 | }
86 | }
87 | }
88 |
89 | /**
90 | * @param \PHP_CodeSniffer\Files\File $phpcsFile
91 | * @param int $stackPtr
92 | *
93 | * @return bool
94 | */
95 | protected function isInlineDocBlock(File $phpcsFile, int $stackPtr): bool
96 | {
97 | $tokens = $phpcsFile->getTokens();
98 |
99 | $closeIndex = $phpcsFile->findNext(T_DOC_COMMENT_CLOSE_TAG, $stackPtr + 1);
100 | if (!$closeIndex) {
101 | return false;
102 | }
103 |
104 | $line = $tokens[$stackPtr]['line'];
105 | $closingLine = $tokens[$closeIndex]['line'];
106 |
107 | return $line === $closingLine;
108 | }
109 | }
110 |
--------------------------------------------------------------------------------
/Spryker/Sniffs/Commenting/DocBlockReturnTagSniff.php:
--------------------------------------------------------------------------------
1 | getTokens();
40 |
41 | if ($tokens[$stackPtr]['content'] !== '@return') {
42 | return;
43 | }
44 |
45 | $nextIndex = $phpcsFile->findNext(T_DOC_COMMENT_STRING, $stackPtr + 1, $stackPtr + 3);
46 | if (!$nextIndex) {
47 | return;
48 | }
49 |
50 | $this->assertDescription($phpcsFile, $nextIndex, $stackPtr);
51 | }
52 |
53 | /**
54 | * @param \PHP_CodeSniffer\Files\File $phpcsFile
55 | * @param int $nextIndex
56 | * @param int $stackPtr
57 | *
58 | * @return void
59 | */
60 | protected function assertDescription(File $phpcsFile, int $nextIndex, int $stackPtr): void
61 | {
62 | $tokens = $phpcsFile->getTokens();
63 |
64 | $content = $tokens[$nextIndex]['content'];
65 | /** @var \PHPStan\PhpDocParser\Ast\PhpDoc\InvalidTagValueNode|\PHPStan\PhpDocParser\Ast\PhpDoc\TypelessParamTagValueNode|\PHPStan\PhpDocParser\Ast\PhpDoc\ReturnTagValueNode $valueNode */
66 | $valueNode = static::getValueNode($tokens[$stackPtr]['content'], $content);
67 | if ($valueNode instanceof InvalidTagValueNode || $valueNode instanceof TypelessParamTagValueNode) {
68 | return;
69 | }
70 |
71 | $returnTypes = $this->valueNodeParts($valueNode);
72 | $typeString = $this->renderUnionTypes($returnTypes);
73 |
74 | if (strpos($content, $typeString) !== 0) {
75 | return;
76 | }
77 |
78 | $description = mb_substr($content, mb_strlen($typeString) + 1);
79 | if (!$description || strpos($description, '$') !== 0) {
80 | return;
81 | }
82 |
83 | $phpcsFile->addError('Description for return annotation must not start with `$`/variable. Use normal sentence instead.', $nextIndex, 'Invalid');
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/Spryker/Sniffs/Commenting/DocBlockStructureSniff.php:
--------------------------------------------------------------------------------
1 | getTokens();
39 |
40 | if ($tokens[$stackPtr]['content'] !== '/**') {
41 | $error = sprintf('Expected `/**`, got `%s`', $tokens[$stackPtr]['content']);
42 | $fix = $phpcsFile->addFixableError($error, $stackPtr, 'InvalidOpening');
43 | if ($fix) {
44 | $phpcsFile->fixer->beginChangeset();
45 | $phpcsFile->fixer->replaceToken($stackPtr, '/**');
46 | $phpcsFile->fixer->endChangeset();
47 | }
48 | }
49 |
50 | $closingTagIndex = $tokens[$stackPtr]['comment_closer'];
51 |
52 | if ($tokens[$closingTagIndex]['content'] !== '*/') {
53 | $error = sprintf('Expected `*/`, got `%s`', $tokens[$closingTagIndex]['content']);
54 | $fix = $phpcsFile->addFixableError($error, $closingTagIndex, 'InvalidClosing');
55 | if ($fix) {
56 | $phpcsFile->fixer->beginChangeset();
57 | $phpcsFile->fixer->replaceToken($closingTagIndex, '*/');
58 | $phpcsFile->fixer->endChangeset();
59 | }
60 | }
61 |
62 | if ($tokens[$closingTagIndex]['line'] === $tokens[$stackPtr]['line']) {
63 | return;
64 | }
65 |
66 | $nextIndex = $phpcsFile->findNext(T_DOC_COMMENT_WHITESPACE, $stackPtr + 1, $closingTagIndex, true);
67 | if (!$nextIndex) {
68 | return;
69 | }
70 |
71 | if ($tokens[$nextIndex]['type'] === 'T_DOC_COMMENT_STAR') {
72 | return;
73 | }
74 |
75 | $fix = $phpcsFile->addFixableError('Doc block beginning invalid.', $stackPtr, 'Invalid');
76 | if (!$fix) {
77 | return;
78 | }
79 |
80 | $phpcsFile->fixer->beginChangeset();
81 |
82 | $level = $tokens[$stackPtr]['level'];
83 |
84 | $index = $nextIndex;
85 | while ($index > $stackPtr + 1) {
86 | $index--;
87 | $phpcsFile->fixer->replaceToken($index, '');
88 | }
89 |
90 | $phpcsFile->fixer->addNewline($stackPtr);
91 | $phpcsFile->fixer->addContent($stackPtr, str_repeat(' ', $level * 4));
92 | $phpcsFile->fixer->addContent($stackPtr, ' * ');
93 |
94 | $phpcsFile->fixer->endChangeset();
95 | }
96 | }
97 |
--------------------------------------------------------------------------------
/Spryker/Sniffs/Commenting/DocBlockTagIterableSniff.php:
--------------------------------------------------------------------------------
1 | . Also nesting, e.g. type>.
17 | */
18 | class DocBlockTagIterableSniff implements Sniff
19 | {
20 | use CommentingTrait;
21 |
22 | /**
23 | * @inheritDoc
24 | */
25 | public function register(): array
26 | {
27 | return [
28 | T_DOC_COMMENT_TAG,
29 | ];
30 | }
31 |
32 | /**
33 | * @inheritDoc
34 | */
35 | public function process(File $phpcsFile, $stackPtr): void
36 | {
37 | $tokens = $phpcsFile->getTokens();
38 |
39 | $content = $tokens[$stackPtr]['content'];
40 |
41 | $tag = $content;
42 | if (strpos($tag, ' ') !== false) {
43 | [$tag, $description] = explode(' ', $content, 2);
44 | }
45 |
46 | if (!preg_match('#^@(?:[a-z]+-)?(?:param|return|var)\b#i', $tag)) {
47 | return;
48 | }
49 |
50 | $possibleTextIndex = $phpcsFile->findNext(T_DOC_COMMENT_STRING, $stackPtr + 1, $stackPtr + 3, false, null, true);
51 | if (!$possibleTextIndex) {
52 | return;
53 | }
54 |
55 | $this->assertType($phpcsFile, $possibleTextIndex, $tag);
56 | }
57 |
58 | /**
59 | * @param \PHP_CodeSniffer\Files\File $phpcsFile
60 | * @param int $stackPtr
61 | * @param string $tag
62 | *
63 | * @return void
64 | */
65 | protected function assertType(File $phpcsFile, int $stackPtr, string $tag): void
66 | {
67 | $tokens = $phpcsFile->getTokens();
68 |
69 | $content = $tokens[$stackPtr]['content'];
70 | if (!$this->containsIterableSyntax([$content])) {
71 | return;
72 | }
73 |
74 | preg_match('#^(\w+)<(.+)>\s*(.*)$#', $content, $matches);
75 | if (!$matches) {
76 | return;
77 | }
78 |
79 | $type = $matches[1];
80 | $definition = $matches[2];
81 | $appendix = $matches[3];
82 |
83 | $correctDefinition = $this->assertDefinition($definition);
84 |
85 | if ($definition === $correctDefinition) {
86 | return;
87 | }
88 |
89 | $message = sprintf('Definition of tag `%s` is not expected `%s`, but `%s`.', $tag, $correctDefinition, $definition);
90 | $fix = $phpcsFile->addFixableError($message, $stackPtr, 'Definition');
91 | if (!$fix) {
92 | return;
93 | }
94 |
95 | $phpcsFile->fixer->beginChangeset();
96 |
97 | $fixedTag = $type . '<' . $correctDefinition . '>';
98 | if ($appendix) {
99 | $fixedTag .= ' ' . trim($appendix);
100 | }
101 |
102 | $phpcsFile->fixer->replaceToken($stackPtr, $fixedTag);
103 |
104 | $phpcsFile->fixer->endChangeset();
105 | }
106 |
107 | /**
108 | * @param string $definition
109 | *
110 | * @return string
111 | */
112 | protected function assertDefinition(string $definition): string
113 | {
114 | return (string)preg_replace_callback('#,([^ ])#', function ($matches) {
115 | return ', ' . $matches[1];
116 | }, $definition);
117 | }
118 | }
119 |
--------------------------------------------------------------------------------
/Spryker/Sniffs/Commenting/DocBlockTagSniff.php:
--------------------------------------------------------------------------------
1 | getTokens();
45 |
46 | $content = $tokens[$stackPtr]['content'];
47 |
48 | $description = '';
49 | $tag = $content;
50 | if (strpos($tag, ' ') !== false) {
51 | [$tag, $description] = explode(' ', $content, 2);
52 | }
53 |
54 | if (!preg_match('#^@[a-z]+.+$#i', $tag)) {
55 | $phpcsFile->addError('Invalid tag `' . $tag . '`', $stackPtr, 'Invalid');
56 |
57 | return;
58 | }
59 |
60 | $this->assertInheritDocCasing($phpcsFile, $stackPtr, $tag, $description);
61 | }
62 |
63 | /**
64 | * @param \PHP_CodeSniffer\Files\File $phpcsFile
65 | * @param int $stackPtr
66 | * @param string $tag
67 | * @param string $description
68 | *
69 | * @return void
70 | */
71 | protected function assertInheritDocCasing(File $phpcsFile, int $stackPtr, string $tag, string $description): void
72 | {
73 | if ($tag === static::INHERIT_DOC_FULL) {
74 | return;
75 | }
76 |
77 | $fixedTag = str_ireplace(static::INHERIT_DOC_FULL_INVALID, static::INHERIT_DOC_FULL, $tag);
78 |
79 | if ($fixedTag === $tag) {
80 | return;
81 | }
82 |
83 | $message = sprintf('Casing of tag `%s` is not expected casing `%s`.', $tag, static::INHERIT_DOC_FULL);
84 | $fix = $phpcsFile->addFixableWarning($message, $stackPtr, 'Casing');
85 | if (!$fix) {
86 | return;
87 | }
88 |
89 | $phpcsFile->fixer->beginChangeset();
90 |
91 | if ($description) {
92 | $fixedTag .= ' ' . $description;
93 | }
94 |
95 | $phpcsFile->fixer->replaceToken($stackPtr, $fixedTag);
96 |
97 | $phpcsFile->fixer->endChangeset();
98 | }
99 | }
100 |
--------------------------------------------------------------------------------
/Spryker/Sniffs/Commenting/DocBlockVarNotJustNullSniff.php:
--------------------------------------------------------------------------------
1 | getTokens();
38 |
39 | $previousIndex = $phpCsFile->findPrevious(Tokens::$emptyTokens, $stackPointer - 1, null, true);
40 | if ($previousIndex && $tokens[$previousIndex]['code'] === T_STATIC) {
41 | $previousIndex = $phpCsFile->findPrevious(Tokens::$emptyTokens, $previousIndex - 1, null, true);
42 | }
43 |
44 | if (!$this->isGivenKind([T_PUBLIC, T_PROTECTED, T_PRIVATE], $tokens[$previousIndex])) {
45 | return;
46 | }
47 |
48 | $docBlockEndIndex = $this->findRelatedDocBlock($phpCsFile, $stackPointer);
49 |
50 | if (!$docBlockEndIndex) {
51 | return;
52 | }
53 |
54 | $docBlockStartIndex = $tokens[$docBlockEndIndex]['comment_opener'];
55 |
56 | $varIndex = null;
57 | for ($i = $docBlockStartIndex + 1; $i < $docBlockEndIndex; $i++) {
58 | if ($tokens[$i]['type'] !== 'T_DOC_COMMENT_TAG') {
59 | continue;
60 | }
61 | if (!in_array($tokens[$i]['content'], ['@var'], true)) {
62 | continue;
63 | }
64 |
65 | $varIndex = $i;
66 | }
67 |
68 | if (!$varIndex) {
69 | return;
70 | }
71 |
72 | $typeIndex = $varIndex + 2;
73 |
74 | $content = $tokens[$typeIndex]['content'];
75 | $spaceIndex = strpos($content, ' ');
76 | if ($spaceIndex) {
77 | $content = substr($content, 0, $spaceIndex);
78 | }
79 |
80 | if (!$content) {
81 | return;
82 | }
83 |
84 | if ($content !== 'null') {
85 | return;
86 | }
87 |
88 | $phpCsFile->addError('Doc Block type `' . $content . '` for annotation @var not enough.', $stackPointer, 'VarTypeIncorrect');
89 | }
90 | }
91 |
--------------------------------------------------------------------------------
/Spryker/Sniffs/ControlStructures/ConditionalExpressionOrderSniff.php:
--------------------------------------------------------------------------------
1 | getTokens();
36 |
37 | $prevIndex = $phpCsFile->findPrevious(Tokens::$emptyTokens, ($stackPointer - 1), null, true);
38 | if (!in_array($tokens[$prevIndex]['code'], [T_TRUE, T_FALSE, T_NULL, T_LNUMBER, T_CONSTANT_ENCAPSED_STRING])) {
39 | return;
40 | }
41 |
42 | $prevIndex = $phpCsFile->findPrevious(Tokens::$emptyTokens, ($prevIndex - 1), null, true);
43 | if (!$prevIndex) {
44 | return;
45 | }
46 | if ($this->isGivenKind(Tokens::$arithmeticTokens, $tokens[$prevIndex])) {
47 | return;
48 | }
49 | if ($this->isGivenKind([T_STRING_CONCAT], $tokens[$prevIndex])) {
50 | return;
51 | }
52 |
53 | $error = 'Usage of Yoda conditions is not allowed. Switch the expression order.';
54 | $prevContent = $tokens[$prevIndex]['content'];
55 |
56 | if (
57 | !$this->isGivenKind(Tokens::$assignmentTokens, $tokens[$prevIndex])
58 | && !$this->isGivenKind(Tokens::$booleanOperators, $tokens[$prevIndex])
59 | && $prevContent !== '('
60 | ) {
61 | // Not fixable
62 | $phpCsFile->addError($error, $stackPointer, 'YodaNotAllowed');
63 |
64 | return;
65 | }
66 |
67 | //TODO
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/Spryker/Sniffs/ControlStructures/ElseIfDeclarationSniff.php:
--------------------------------------------------------------------------------
1 | getTokens();
34 |
35 | $next = $phpcsFile->findNext(T_WHITESPACE, ($stackPtr + 1), null, true);
36 | if ($tokens[$next]['code'] === T_IF) {
37 | $phpcsFile->recordMetric($stackPtr, 'Use of ELSE IF or ELSEIF', 'else if');
38 | $error = 'Usage of `else if` is not allowed, use `elseif` instead';
39 | $fix = $phpcsFile->addFixableError($error, $stackPtr, 'NotAllowed');
40 |
41 | if ($fix === true) {
42 | $phpcsFile->fixer->beginChangeset();
43 | $phpcsFile->fixer->replaceToken($stackPtr, 'elseif');
44 | for ($i = ($stackPtr + 1); $i <= $next; $i++) {
45 | $phpcsFile->fixer->replaceToken($i, '');
46 | }
47 |
48 | $phpcsFile->fixer->endChangeset();
49 | }
50 | }
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/Spryker/Sniffs/Internal/SprykerNoDemoshopSniff.php:
--------------------------------------------------------------------------------
1 | isDemoshopCode($phpcsFile)) {
37 | return;
38 | }
39 |
40 | $file = $phpcsFile->getFilename();
41 | $content = file_get_contents($file);
42 | if (!$content) {
43 | return;
44 | }
45 |
46 | if (!preg_match('/\* @project\b/', $content)) {
47 | return;
48 | }
49 |
50 | $phpcsFile->addError('No internal "project only" code should be merged into Spryker suite/demoshop.', $stackPtr, 'InvalidContent');
51 | }
52 |
53 | /**
54 | * @param \PHP_CodeSniffer\Files\File $phpCsFile
55 | *
56 | * @return bool
57 | */
58 | protected function isDemoshopCode(File $phpCsFile): bool
59 | {
60 | if (static::$isDemoshop !== null) {
61 | return static::$isDemoshop;
62 | }
63 |
64 | $positionSprykerCore = strpos($phpCsFile->getFilename(), '/src/');
65 | if (!$positionSprykerCore) {
66 | return false;
67 | }
68 |
69 | $file = substr($phpCsFile->getFilename(), 0, $positionSprykerCore) . '/composer.json';
70 | if (!is_file($file)) {
71 | static::$isDemoshop = false;
72 |
73 | return static::$isDemoshop;
74 | }
75 |
76 | $content = file_get_contents($file);
77 | if (!$content) {
78 | return false;
79 | }
80 |
81 | static::$isDemoshop = (bool)preg_match('#"name":\s*"(spryker/demoshop|spryker-shop/suite|spryker-shop/suite-b2c|spryker-shop/suite-b2b)"#', $content, $matches);
82 |
83 | return static::$isDemoshop;
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/Spryker/Sniffs/Internal/SprykerPreferStaticOverSelfSniff.php:
--------------------------------------------------------------------------------
1 | isCore($phpCsFile)) {
36 | return;
37 | }
38 |
39 | $this->assertStatic($phpCsFile, $stackPointer);
40 | }
41 |
42 | /**
43 | * @param \PHP_CodeSniffer\Files\File $phpCsFile
44 | * @param int $stackPointer
45 | *
46 | * @return void
47 | */
48 | protected function assertStatic(File $phpCsFile, int $stackPointer): void
49 | {
50 | $tokens = $phpCsFile->getTokens();
51 |
52 | // We skip for interface methods
53 | if (empty($tokens[$stackPointer]['scope_opener']) || empty($tokens[$stackPointer]['scope_closer'])) {
54 | return;
55 | }
56 |
57 | $scopeOpener = $tokens[$stackPointer]['scope_opener'];
58 | $scopeCloser = $tokens[$stackPointer]['scope_closer'];
59 |
60 | for ($i = $scopeOpener; $i < $scopeCloser; $i++) {
61 | // We don't want to detect throws from nested scopes, so we'll just
62 | // skip those.
63 | if (in_array($tokens[$i]['code'], [T_FN, T_CLOSURE], true)) {
64 | $i = $tokens[$i]['scope_closer'];
65 |
66 | continue;
67 | }
68 |
69 | if ($tokens[$i]['code'] !== T_SELF) {
70 | continue;
71 | }
72 |
73 | $nextIndex = $phpCsFile->findNext(Tokens::$emptyTokens, $i + 1, null, true);
74 | if (!$nextIndex || $tokens[$nextIndex]['code'] !== T_DOUBLE_COLON) {
75 | continue;
76 | }
77 |
78 | $fix = $phpCsFile->addFixableError('Please use static:: instead of self::', $i, 'StaticVsSelf');
79 | if (!$fix) {
80 | return;
81 | }
82 |
83 | $phpCsFile->fixer->beginChangeset();
84 | $phpCsFile->fixer->replaceToken($i, 'static');
85 | $phpCsFile->fixer->endChangeset();
86 | }
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/Spryker/Sniffs/MethodAnnotation/ConfigMethodAnnotationSniff.php:
--------------------------------------------------------------------------------
1 | getModule($phpCsFile) . 'Config';
34 | }
35 |
36 | /**
37 | * @param \PHP_CodeSniffer\Files\File $phpCsFile
38 | * @param int $stackPointer
39 | *
40 | * @return bool
41 | */
42 | protected function getSnifferIsApplicable(File $phpCsFile, int $stackPointer): bool
43 | {
44 | if ($this->isProvider($phpCsFile)) {
45 | return true;
46 | }
47 |
48 | if ($this->isCollectionType($phpCsFile, $stackPointer)) {
49 | return true;
50 | }
51 |
52 | if ($this->isFactory($phpCsFile, $stackPointer)) {
53 | return true;
54 | }
55 |
56 | if ($this->isPlugin($phpCsFile, $stackPointer)) {
57 | return true;
58 | }
59 |
60 | if ($this->isType($phpCsFile, $stackPointer)) {
61 | return true;
62 | }
63 |
64 | return false;
65 | }
66 |
67 | /**
68 | * @param \PHP_CodeSniffer\Files\File $phpCsFile
69 | * @param string $namespacePart
70 | *
71 | * @return string
72 | */
73 | protected function getMethodAnnotationFileName(File $phpCsFile, string $namespacePart): string
74 | {
75 | $className = $this->getClassName($phpCsFile);
76 | $classNameParts = explode('\\', $className);
77 | $classNameParts = array_slice($classNameParts, 0, 3);
78 | $classNameParts[0] = $namespacePart;
79 | array_push($classNameParts, $this->getMethodFileAddedName($phpCsFile));
80 |
81 | return '\\' . implode('\\', $classNameParts);
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/Spryker/Sniffs/MethodAnnotation/EntityManagerMethodAnnotationSniff.php:
--------------------------------------------------------------------------------
1 | getModule($phpCsFile) . 'EntityManagerInterface';
34 | }
35 |
36 | /**
37 | * @param \PHP_CodeSniffer\Files\File $phpCsFile
38 | * @param int $stackPointer
39 | *
40 | * @return bool
41 | */
42 | protected function getSnifferIsApplicable(File $phpCsFile, int $stackPointer): bool
43 | {
44 | if ($this->isFacade($phpCsFile, $stackPointer)) {
45 | return true;
46 | }
47 |
48 | if ($this->isFactory($phpCsFile, $stackPointer)) {
49 | return true;
50 | }
51 |
52 | return false;
53 | }
54 |
55 | /**
56 | * @param \PHP_CodeSniffer\Files\File $phpCsFile
57 | * @param string $namespacePart
58 | *
59 | * @return string
60 | */
61 | protected function getMethodAnnotationFileName(File $phpCsFile, string $namespacePart): string
62 | {
63 | $className = $this->getClassName($phpCsFile);
64 | $classNameParts = explode('\\', $className);
65 | $classNameParts = array_slice($classNameParts, 0, 3);
66 | $classNameParts[0] = $namespacePart;
67 | array_push($classNameParts, static::LAYER_PERSISTENCE);
68 | array_push($classNameParts, $this->getMethodFileAddedName($phpCsFile));
69 |
70 | return '\\' . implode('\\', $classNameParts);
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/Spryker/Sniffs/MethodAnnotation/FacadeMethodAnnotationSniff.php:
--------------------------------------------------------------------------------
1 | getModule($phpCsFile) . 'FacadeInterface';
34 | }
35 |
36 | /**
37 | * @param \PHP_CodeSniffer\Files\File $phpCsFile
38 | * @param int $stackPointer
39 | *
40 | * @return bool
41 | */
42 | protected function getSnifferIsApplicable(File $phpCsFile, int $stackPointer): bool
43 | {
44 | if ($this->isController($phpCsFile, $stackPointer)) {
45 | return true;
46 | }
47 |
48 | if ($this->isCollectionType($phpCsFile, $stackPointer)) {
49 | return true;
50 | }
51 |
52 | if ($this->isConsole($phpCsFile, $stackPointer)) {
53 | return true;
54 | }
55 |
56 | if ($this->isCommunicationFactory($phpCsFile, $stackPointer)) {
57 | return true;
58 | }
59 |
60 | if ($this->isPlugin($phpCsFile, $stackPointer)) {
61 | return true;
62 | }
63 |
64 | if ($this->isType($phpCsFile, $stackPointer)) {
65 | return true;
66 | }
67 |
68 | return false;
69 | }
70 |
71 | /**
72 | * @param \PHP_CodeSniffer\Files\File $phpCsFile
73 | * @param string $namespacePart
74 | *
75 | * @return string
76 | */
77 | protected function getMethodAnnotationFileName(File $phpCsFile, string $namespacePart): string
78 | {
79 | $className = $this->getClassName($phpCsFile);
80 | $classNameParts = explode('\\', $className);
81 | $classNameParts = array_slice($classNameParts, 0, 3);
82 | $classNameParts[0] = $namespacePart;
83 | array_push($classNameParts, static::LAYER_BUSINESS);
84 | array_push($classNameParts, $this->getMethodFileAddedName($phpCsFile));
85 |
86 | return '\\' . implode('\\', $classNameParts);
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/Spryker/Sniffs/MethodAnnotation/FactoryMethodAnnotationSniff.php:
--------------------------------------------------------------------------------
1 | getModule($phpCsFile) . $this->getLayer($phpCsFile) . 'Factory';
34 | }
35 |
36 | /**
37 | * @param \PHP_CodeSniffer\Files\File $phpCsFile
38 | * @param int $stackPointer
39 | *
40 | * @return bool
41 | */
42 | protected function getSnifferIsApplicable(File $phpCsFile, int $stackPointer): bool
43 | {
44 | if ($this->isController($phpCsFile, $stackPointer)) {
45 | return true;
46 | }
47 |
48 | if ($this->isCollectionType($phpCsFile, $stackPointer)) {
49 | return true;
50 | }
51 |
52 | if ($this->isConsole($phpCsFile, $stackPointer)) {
53 | return true;
54 | }
55 |
56 | if ($this->isFacade($phpCsFile, $stackPointer)) {
57 | return true;
58 | }
59 |
60 | if ($this->isPlugin($phpCsFile, $stackPointer)) {
61 | return true;
62 | }
63 |
64 | if ($this->isType($phpCsFile, $stackPointer)) {
65 | return true;
66 | }
67 |
68 | if ($this->isQueryContainer($phpCsFile, $stackPointer)) {
69 | return true;
70 | }
71 |
72 | if ($this->isRepository($phpCsFile, $stackPointer)) {
73 | return true;
74 | }
75 |
76 | if ($this->isEntityManager($phpCsFile, $stackPointer)) {
77 | return true;
78 | }
79 |
80 | return false;
81 | }
82 |
83 | /**
84 | * @param \PHP_CodeSniffer\Files\File $phpCsFile
85 | * @param string $namespacePart
86 | *
87 | * @return string
88 | */
89 | protected function getMethodAnnotationFileName(File $phpCsFile, string $namespacePart): string
90 | {
91 | $className = $this->getClassName($phpCsFile);
92 | $classNameParts = explode('\\', $className);
93 | $classNameParts = array_slice($classNameParts, 0, 3);
94 | $classNameParts[0] = $namespacePart;
95 | array_push($classNameParts, $this->getLayer($phpCsFile));
96 | array_push($classNameParts, $this->getMethodFileAddedName($phpCsFile));
97 |
98 | return '\\' . implode('\\', $classNameParts);
99 | }
100 | }
101 |
--------------------------------------------------------------------------------
/Spryker/Sniffs/MethodAnnotation/QueryContainerMethodAnnotationSniff.php:
--------------------------------------------------------------------------------
1 | getModule($phpCsFile) . 'QueryContainerInterface';
34 | }
35 |
36 | /**
37 | * @param \PHP_CodeSniffer\Files\File $phpCsFile
38 | * @param int $stackPointer
39 | *
40 | * @return bool
41 | */
42 | protected function getSnifferIsApplicable(File $phpCsFile, int $stackPointer): bool
43 | {
44 | return false;
45 | }
46 |
47 | /**
48 | * @param \PHP_CodeSniffer\Files\File $phpCsFile
49 | * @param string $namespacePart
50 | *
51 | * @return string
52 | */
53 | protected function getMethodAnnotationFileName(File $phpCsFile, string $namespacePart): string
54 | {
55 | $className = $this->getClassName($phpCsFile);
56 | $classNameParts = explode('\\', $className);
57 | $classNameParts = array_slice($classNameParts, 0, 3);
58 | $classNameParts[0] = $namespacePart;
59 | array_push($classNameParts, static::LAYER_PERSISTENCE);
60 | array_push($classNameParts, $this->getMethodFileAddedName($phpCsFile));
61 |
62 | return '\\' . implode('\\', $classNameParts);
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/Spryker/Sniffs/MethodAnnotation/RepositoryMethodAnnotationSniff.php:
--------------------------------------------------------------------------------
1 | getModule($phpCsFile) . 'RepositoryInterface';
34 | }
35 |
36 | /**
37 | * @param \PHP_CodeSniffer\Files\File $phpCsFile
38 | * @param int $stackPointer
39 | *
40 | * @return bool
41 | */
42 | protected function getSnifferIsApplicable(File $phpCsFile, int $stackPointer): bool
43 | {
44 | if ($this->isController($phpCsFile, $stackPointer)) {
45 | return true;
46 | }
47 |
48 | if ($this->isCollectionType($phpCsFile, $stackPointer)) {
49 | return true;
50 | }
51 |
52 | if ($this->isConsole($phpCsFile, $stackPointer)) {
53 | return true;
54 | }
55 |
56 | if ($this->isFacade($phpCsFile, $stackPointer)) {
57 | return true;
58 | }
59 |
60 | if ($this->isFactory($phpCsFile, $stackPointer)) {
61 | return true;
62 | }
63 |
64 | if ($this->isType($phpCsFile, $stackPointer)) {
65 | return true;
66 | }
67 |
68 | return false;
69 | }
70 |
71 | /**
72 | * @param \PHP_CodeSniffer\Files\File $phpCsFile
73 | * @param string $namespacePart
74 | *
75 | * @return string
76 | */
77 | protected function getMethodAnnotationFileName(File $phpCsFile, string $namespacePart): string
78 | {
79 | $className = $this->getClassName($phpCsFile);
80 | $classNameParts = explode('\\', $className);
81 | $classNameParts = array_slice($classNameParts, 0, 3);
82 | $classNameParts[0] = $namespacePart;
83 | array_push($classNameParts, static::LAYER_PERSISTENCE);
84 | array_push($classNameParts, $this->getMethodFileAddedName($phpCsFile));
85 |
86 | return '\\' . implode('\\', $classNameParts);
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/Spryker/Sniffs/Namespaces/FunctionNamespaceSniff.php:
--------------------------------------------------------------------------------
1 | getTokens();
32 |
33 | $tokenContent = $tokens[$stackPtr]['content'];
34 |
35 | $openingBrace = $phpcsFile->findNext(T_WHITESPACE, ($stackPtr + 1), null, true);
36 | if (!$openingBrace || $tokens[$openingBrace]['type'] !== 'T_OPEN_PARENTHESIS') {
37 | return;
38 | }
39 |
40 | $separatorIndex = $phpcsFile->findPrevious(T_WHITESPACE, ($stackPtr - 1), null, true);
41 | if (!$separatorIndex || $tokens[$separatorIndex]['type'] !== 'T_NS_SEPARATOR') {
42 | return;
43 | }
44 |
45 | // We check that this is a function but not new operator
46 | $newIndex = $phpcsFile->findPrevious([T_WHITESPACE, T_NS_SEPARATOR], ($stackPtr - 1), null, true);
47 | if (!$newIndex || in_array($tokens[$newIndex]['code'], [T_NEW, T_ATTRIBUTE], true)) {
48 | return;
49 | }
50 |
51 | // We skip for non trivial cases
52 | $previous = $phpcsFile->findPrevious(T_WHITESPACE, ($separatorIndex - 1), null, true);
53 | if (!$previous || $tokens[$previous]['type'] === 'T_STRING') {
54 | return;
55 | }
56 |
57 | $error = 'Function name ' . $tokenContent . '() found, should not be \ prefixed.';
58 | $fix = $phpcsFile->addFixableError($error, $stackPtr, 'NamespaceInvalid');
59 | if ($fix) {
60 | $phpcsFile->fixer->replaceToken($separatorIndex, '');
61 | }
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/Spryker/Sniffs/Namespaces/SprykerNamespaceSniff.php:
--------------------------------------------------------------------------------
1 | getNamespaceStatement($phpcsFile);
56 | if (!$namespaceStatement) {
57 | return;
58 | }
59 |
60 | $filename = $fullFilename = $phpcsFile->getFilename();
61 | if ($this->isRoot) {
62 | $filename = $this->normalizeFilename($fullFilename);
63 | }
64 | $start = '/';
65 | if ($fullFilename !== $filename) {
66 | $start = '^';
67 | }
68 |
69 | $pattern = '#' . $start . $this->rootDir . '/(' . $this->namespace . ')/(.+)#';
70 | if ($this->isRoot) {
71 | $pattern = '#' . $start . $this->rootDir . '/(.+)#';
72 | }
73 |
74 | preg_match($pattern, $filename, $matches);
75 | if (!$matches) {
76 | return;
77 | }
78 |
79 | if ($this->isRoot) {
80 | $extractedPath = $this->namespace . '/' . $matches[1];
81 | } else {
82 | $extractedPath = $matches[1] . '/' . $matches[2];
83 | }
84 | $pathWithoutFilename = substr($extractedPath, 0, strrpos($extractedPath, DIRECTORY_SEPARATOR) ?: 0);
85 |
86 | $namespace = $namespaceStatement['namespace'];
87 | $pathToNamespace = str_replace(DIRECTORY_SEPARATOR, '\\', $pathWithoutFilename);
88 | if ($namespace === $pathToNamespace) {
89 | return;
90 | }
91 |
92 | $error = sprintf('Namespace `%s` does not fit to folder structure `%s`', $namespace, $pathToNamespace);
93 | $phpcsFile->addError($error, $namespaceStatement['start'], 'NamespaceFolderMismatch');
94 | }
95 |
96 | /**
97 | * Removes the current working directory (root) if possible.
98 | *
99 | * @param string $getFilename
100 | *
101 | * @return string
102 | */
103 | protected function normalizeFilename(string $getFilename): string
104 | {
105 | return str_replace(getcwd() . DIRECTORY_SEPARATOR, '', $getFilename);
106 | }
107 | }
108 |
--------------------------------------------------------------------------------
/Spryker/Sniffs/Namespaces/SprykerNoCrossNamespaceSniff.php:
--------------------------------------------------------------------------------
1 | >
33 | */
34 | protected const INVALID_PAIRS = [
35 | [
36 | 'from' => self::NAMESPACE_YVES,
37 | 'to' => self::NAMESPACE_ZED,
38 | ],
39 | [
40 | 'from' => self::NAMESPACE_ZED,
41 | 'to' => self::NAMESPACE_YVES,
42 | ],
43 | ];
44 |
45 | /**
46 | * @inheritDoc
47 | */
48 | public function register(): array
49 | {
50 | return [T_CLASS, T_INTERFACE, T_TRAIT];
51 | }
52 |
53 | /**
54 | * @inheritDoc
55 | */
56 | public function process(File $phpcsFile, $stackPtr): void
57 | {
58 | $className = $this->getClassName($phpcsFile);
59 | $namespaces = [];
60 | foreach (static::INVALID_PAIRS as $pair) {
61 | $namespaces[] = $pair['from'];
62 | }
63 | $namespaces = implode('|', $namespaces);
64 |
65 | if (!preg_match('#^\w+\\\\(' . $namespaces . ')\\\\#', $className, $matches)) {
66 | return;
67 | }
68 |
69 | if (strpos($className, 'PyzTest') === 0) {
70 | return;
71 | }
72 |
73 | $useStatements = $this->getUseStatements($phpcsFile);
74 | foreach ($useStatements as $useStatement) {
75 | $this->checkUseStatement($phpcsFile, $useStatement, $matches[1]);
76 | }
77 | }
78 |
79 | /**
80 | * @param \PHP_CodeSniffer\Files\File $phpcsFile
81 | * @param array $useStatement
82 | * @param string $applicationLayer Zed, Yves, ...
83 | *
84 | * @return void
85 | */
86 | protected function checkUseStatement(File $phpcsFile, array $useStatement, string $applicationLayer): void
87 | {
88 | $className = $useStatement['fullName'];
89 |
90 | $pairsToCheck = static::INVALID_PAIRS;
91 | foreach ($pairsToCheck as $pair) {
92 | if ($pair['from'] !== $applicationLayer) {
93 | continue;
94 | }
95 |
96 | if (!preg_match('#^\w+\\\\' . $pair['to'] . '\\\\#', $className, $matches)) {
97 | continue;
98 | }
99 |
100 | $phpcsFile->addError(
101 | sprintf(
102 | 'No %s namespace allowed in %s files.',
103 | $pair['to'],
104 | $pair['from'],
105 | ),
106 | $useStatement['start'],
107 | 'InvalidCrossNamespace',
108 | );
109 | }
110 | }
111 | }
112 |
--------------------------------------------------------------------------------
/Spryker/Sniffs/Namespaces/SprykerNoPyzSniff.php:
--------------------------------------------------------------------------------
1 | isSprykerNamespace($phpcsFile)) {
40 | return;
41 | }
42 |
43 | $useStatements = $this->getUseStatements($phpcsFile);
44 | foreach ($useStatements as $useStatement) {
45 | $namespace = $this->extractNamespace($useStatement['fullName']);
46 | if ($namespace !== static::NAMESPACE_PROJECT) {
47 | continue;
48 | }
49 |
50 | $phpcsFile->addError(sprintf('No %s namespace allowed in core files.', static::NAMESPACE_PROJECT), $useStatement['start'], 'InvalidPyzInSpryker');
51 | }
52 | }
53 |
54 | /**
55 | * @param string $fullClassName
56 | *
57 | * @return string
58 | */
59 | protected function extractNamespace(string $fullClassName): string
60 | {
61 | $namespaces = explode('\\', $fullClassName, 2);
62 |
63 | return $namespaces[0];
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/Spryker/Sniffs/Namespaces/UseWithAliasingSniff.php:
--------------------------------------------------------------------------------
1 | getTokens();
35 |
36 | $content = $tokens[$stackPtr]['content'];
37 | if ($content === 'as') {
38 | return;
39 | }
40 |
41 | if (!empty($tokens[$stackPtr]['conditions']) || !empty($tokens[$stackPtr]['nested_parenthesis'])) {
42 | // Let Squiz.ControlStructures.ForEachLoopDeclaration handle this
43 | return;
44 | }
45 |
46 | $newContent = strtolower($content);
47 |
48 | $fix = $phpcsFile->addFixableError(sprintf('Alias keyword `%s` should be `%s`', $content, $newContent), $stackPtr, 'InvalidAliasKeyword');
49 | if (!$fix) {
50 | return;
51 | }
52 |
53 | $phpcsFile->fixer->replaceToken($stackPtr, $newContent);
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/Spryker/Sniffs/PHP/DisallowTrailingCommaInSingleLineSniff.php:
--------------------------------------------------------------------------------
1 |
22 | */
23 | protected $closingTokens = [
24 | T_CLOSE_PARENTHESIS,
25 | T_CLOSE_SQUARE_BRACKET,
26 | ];
27 |
28 | /**
29 | * @inheritDoc
30 | */
31 | public function register(): array
32 | {
33 | return [
34 | T_COMMA,
35 | ];
36 | }
37 |
38 | /**
39 | * @inheritDoc
40 | */
41 | public function process(File $phpcsFile, $commaIndex): void
42 | {
43 | $tokens = $phpcsFile->getTokens();
44 |
45 | $nextIndex = $phpcsFile->findNext(T_WHITESPACE, ($commaIndex + 1), null, true);
46 | if (!$nextIndex || $tokens[$nextIndex]['line'] !== $tokens[$commaIndex]['line']) {
47 | return;
48 | }
49 |
50 | if (!in_array($tokens[$nextIndex]['code'], $this->closingTokens, true)) {
51 | return;
52 | }
53 |
54 | $fix = $phpcsFile->addFixableError(
55 | 'Trailing comma in single line is disallowed.',
56 | $commaIndex,
57 | 'TrailingCommaDisallowed',
58 | );
59 |
60 | if (!$fix) {
61 | return;
62 | }
63 |
64 | $phpcsFile->fixer->beginChangeset();
65 | $phpcsFile->fixer->replaceToken($commaIndex, '');
66 | $phpcsFile->fixer->endChangeset();
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/Spryker/Sniffs/PHP/ExitSniff.php:
--------------------------------------------------------------------------------
1 |
22 | */
23 | public static $aliases = [
24 | 'die' => 'exit',
25 | ];
26 |
27 | /**
28 | * @inheritDoc
29 | */
30 | public function register(): array
31 | {
32 | return [T_EXIT];
33 | }
34 |
35 | /**
36 | * @inheritDoc
37 | */
38 | public function process(File $phpcsFile, $stackPtr): void
39 | {
40 | $this->checkExitUsage($phpcsFile, $stackPtr);
41 | }
42 |
43 | /**
44 | * @param \PHP_CodeSniffer\Files\File $phpcsFile
45 | * @param int $stackPtr
46 | *
47 | * @return void
48 | */
49 | protected function checkExitUsage(File $phpcsFile, int $stackPtr): void
50 | {
51 | $wrongTokens = [T_FUNCTION, T_OBJECT_OPERATOR, T_NEW, T_DOUBLE_COLON];
52 |
53 | $tokens = $phpcsFile->getTokens();
54 |
55 | $tokenContent = $tokens[$stackPtr]['content'];
56 | $key = strtolower($tokenContent);
57 | if (isset(static::$aliases[$key])) {
58 | $this->fixAlias($phpcsFile, $stackPtr, $key);
59 | }
60 |
61 | $openingBrace = $phpcsFile->findNext(T_WHITESPACE, ($stackPtr + 1), null, true);
62 | if (!$openingBrace || $tokens[$openingBrace]['type'] !== 'T_OPEN_PARENTHESIS') {
63 | return;
64 | }
65 |
66 | if ($tokens[$openingBrace]['parenthesis_closer'] > $openingBrace + 1) {
67 | return;
68 | }
69 |
70 | $error = $key . '() without integer exit code argument is not allowed.';
71 | $phpcsFile->addError($error, $stackPtr, 'Invalid');
72 | }
73 |
74 | /**
75 | * @param \PHP_CodeSniffer\Files\File $phpcsFile
76 | * @param int $stackPtr
77 | * @param string $before
78 | *
79 | * @return void
80 | */
81 | protected function fixAlias(File $phpcsFile, int $stackPtr, string $before): void
82 | {
83 | $after = static::$aliases[$before];
84 | $fix = $phpcsFile->addFixableError($before . '() should be ' . $after . '()', $stackPtr, 'Alias');
85 | if (!$fix) {
86 | return;
87 | }
88 |
89 | $phpcsFile->fixer->replaceToken($stackPtr, $after);
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/Spryker/Sniffs/PHP/NotEqualSniff.php:
--------------------------------------------------------------------------------
1 | .
15 | */
16 | class NotEqualSniff implements Sniff
17 | {
18 | /**
19 | * @var array
20 | */
21 | public static $matching = [
22 | '<>' => '!=',
23 | ];
24 |
25 | /**
26 | * @inheritDoc
27 | */
28 | public function register(): array
29 | {
30 | return [T_IS_NOT_EQUAL];
31 | }
32 |
33 | /**
34 | * @inheritDoc
35 | */
36 | public function process(File $phpcsFile, $stackPtr): void
37 | {
38 | $tokens = $phpcsFile->getTokens();
39 |
40 | $content = $tokens[$stackPtr]['content'];
41 | $key = strtolower($content);
42 |
43 | if (!isset(static::$matching[$key])) {
44 | return;
45 | }
46 |
47 | $fix = $phpcsFile->addFixableError($content . ' found, expected ' . static::$matching[$key], $stackPtr, 'NotEqualInvalid');
48 | if ($fix) {
49 | $phpcsFile->fixer->replaceToken($stackPtr, static::$matching[$key]);
50 | }
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/Spryker/Sniffs/PHP/PhpSapiConstantSniff.php:
--------------------------------------------------------------------------------
1 | getTokens();
37 |
38 | $wrongTokens = [T_FUNCTION, T_OBJECT_OPERATOR, T_NEW, T_DOUBLE_COLON];
39 |
40 | $tokenContent = $tokens[$stackPtr]['content'];
41 | if (strtolower($tokenContent) !== 'php_sapi_name') {
42 | return;
43 | }
44 |
45 | $previous = (int)$phpcsFile->findPrevious(T_WHITESPACE, ($stackPtr - 1), null, true);
46 | if (!$previous || in_array($tokens[$previous]['code'], $wrongTokens)) {
47 | return;
48 | }
49 |
50 | $openingBrace = (int)$phpcsFile->findNext(T_WHITESPACE, ($stackPtr + 1), null, true);
51 | if (!$openingBrace || $tokens[$openingBrace]['type'] !== 'T_OPEN_PARENTHESIS') {
52 | return;
53 | }
54 |
55 | $closingBrace = (int)$phpcsFile->findNext(T_WHITESPACE, ($openingBrace + 1), null, true);
56 | if (!$closingBrace || $tokens[$closingBrace]['type'] !== 'T_CLOSE_PARENTHESIS') {
57 | return;
58 | }
59 |
60 | $error = $tokenContent . '() found, should be const ' . static::PHP_SAPI . '.';
61 | $fix = $phpcsFile->addFixableError($error, $stackPtr, 'MethodVsConst');
62 | if ($fix) {
63 | $phpcsFile->fixer->replaceToken($stackPtr, static::PHP_SAPI);
64 | for ($i = $openingBrace; $i <= $closingBrace; ++$i) {
65 | $phpcsFile->fixer->replaceToken($i, '');
66 | }
67 | }
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/Spryker/Sniffs/PHP/PreferCastOverFunctionSniff.php:
--------------------------------------------------------------------------------
1 |
20 | */
21 | protected static $matching = [
22 | 'strval' => 'string',
23 | 'intval' => 'int',
24 | 'floatval' => 'float',
25 | 'boolval' => 'bool',
26 | ];
27 |
28 | /**
29 | * @inheritDoc
30 | */
31 | public function register(): array
32 | {
33 | return [T_STRING];
34 | }
35 |
36 | /**
37 | * @inheritDoc
38 | */
39 | public function process(File $phpcsFile, $stackPtr): void
40 | {
41 | $wrongTokens = [T_FUNCTION, T_OBJECT_OPERATOR, T_NEW, T_DOUBLE_COLON];
42 |
43 | $tokens = $phpcsFile->getTokens();
44 |
45 | $tokenContent = $tokens[$stackPtr]['content'];
46 | $key = strtolower($tokenContent);
47 | if (!isset(static::$matching[$key])) {
48 | return;
49 | }
50 |
51 | $previous = (int)$phpcsFile->findPrevious(T_WHITESPACE, ($stackPtr - 1), null, true);
52 | if (!$previous || in_array($tokens[$previous]['code'], $wrongTokens)) {
53 | return;
54 | }
55 |
56 | $openingBraceIndex = (int)$phpcsFile->findNext(T_WHITESPACE, ($stackPtr + 1), null, true);
57 | if (!$openingBraceIndex || $tokens[$openingBraceIndex]['type'] !== 'T_OPEN_PARENTHESIS') {
58 | return;
59 | }
60 |
61 | $closingBraceIndex = $tokens[$openingBraceIndex]['parenthesis_closer'];
62 |
63 | // We must ignore when commas are encountered
64 | if ($this->contains($phpcsFile, 'T_COMMA', $openingBraceIndex + 1, $closingBraceIndex - 1)) {
65 | return;
66 | }
67 |
68 | $error = $tokenContent . '() found, should be ' . static::$matching[$key] . ' cast.';
69 |
70 | $fix = $phpcsFile->addFixableError($error, $stackPtr, 'MethodVsCast');
71 | if ($fix) {
72 | $this->fixContent($phpcsFile, $stackPtr, $key, $openingBraceIndex, $closingBraceIndex);
73 | }
74 | }
75 |
76 | /**
77 | * @param \PHP_CodeSniffer\Files\File $phpcsFile
78 | * @param int $stackPtr
79 | * @param string $key
80 | * @param int $openingBraceIndex
81 | * @param int $closingBraceIndex
82 | *
83 | * @return void
84 | */
85 | protected function fixContent(
86 | File $phpcsFile,
87 | int $stackPtr,
88 | string $key,
89 | int $openingBraceIndex,
90 | int $closingBraceIndex
91 | ): void {
92 | $needsBrackets = $this->needsBrackets($phpcsFile, $openingBraceIndex, $closingBraceIndex);
93 |
94 | $cast = '(' . static::$matching[$key] . ')';
95 |
96 | $phpcsFile->fixer->replaceToken($stackPtr, $cast);
97 | if (!$needsBrackets) {
98 | $phpcsFile->fixer->replaceToken($openingBraceIndex, '');
99 | $phpcsFile->fixer->replaceToken($closingBraceIndex, '');
100 | }
101 | }
102 | }
103 |
--------------------------------------------------------------------------------
/Spryker/Sniffs/PHP/RemoveFunctionAliasSniff.php:
--------------------------------------------------------------------------------
1 |
22 | */
23 | public static $matching = [
24 | 'is_integer' => 'is_int',
25 | 'is_long' => 'is_int',
26 | 'is_real' => 'is_float',
27 | 'is_double' => 'is_float',
28 | 'is_writeable' => 'is_writable',
29 | 'join' => 'implode',
30 | 'key_exists' => 'array_key_exists', // Deprecated function
31 | 'sizeof' => 'count',
32 | 'strchr' => 'strstr',
33 | 'ini_alter' => 'ini_set',
34 | 'fputs' => 'fwrite',
35 | 'die' => 'exit',
36 | 'chop' => 'rtrim',
37 | 'print' => 'echo',
38 | ];
39 |
40 | /**
41 | * @inheritDoc
42 | */
43 | public function register(): array
44 | {
45 | return [T_STRING];
46 | }
47 |
48 | /**
49 | * @inheritDoc
50 | */
51 | public function process(File $phpcsFile, $stackPtr): void
52 | {
53 | $this->checkFixableAliases($phpcsFile, $stackPtr);
54 | }
55 |
56 | /**
57 | * @param \PHP_CodeSniffer\Files\File $phpcsFile
58 | * @param int $stackPtr
59 | *
60 | * @return void
61 | */
62 | protected function checkFixableAliases(File $phpcsFile, int $stackPtr): void
63 | {
64 | $wrongTokens = [T_FUNCTION, T_OBJECT_OPERATOR, T_NEW, T_DOUBLE_COLON];
65 |
66 | $tokens = $phpcsFile->getTokens();
67 |
68 | $tokenContent = $tokens[$stackPtr]['content'];
69 | $key = strtolower($tokenContent);
70 | if (!isset(static::$matching[$key])) {
71 | return;
72 | }
73 |
74 | $previous = $phpcsFile->findPrevious(T_WHITESPACE, ($stackPtr - 1), null, true);
75 | if (!$previous || in_array($tokens[$previous]['code'], $wrongTokens)) {
76 | return;
77 | }
78 |
79 | $openingBrace = $phpcsFile->findNext(T_WHITESPACE, ($stackPtr + 1), null, true);
80 | if (!$openingBrace || $tokens[$openingBrace]['type'] !== 'T_OPEN_PARENTHESIS') {
81 | return;
82 | }
83 |
84 | $error = 'Function name ' . $tokenContent . '() found, should be ' . static::$matching[$key] . '().';
85 | $fix = $phpcsFile->addFixableError($error, $stackPtr, 'LongInvalid');
86 | if ($fix) {
87 | $phpcsFile->fixer->replaceToken($stackPtr, static::$matching[$key]);
88 | }
89 | }
90 | }
91 |
--------------------------------------------------------------------------------
/Spryker/Sniffs/PHP/ShortCastSniff.php:
--------------------------------------------------------------------------------
1 |
20 | */
21 | public static $matching = [
22 | '(boolean)' => '(bool)',
23 | '(integer)' => '(int)',
24 | ];
25 |
26 | /**
27 | * @inheritDoc
28 | */
29 | public function register(): array
30 | {
31 | return [T_BOOL_CAST, T_INT_CAST, T_BOOLEAN_NOT];
32 | }
33 |
34 | /**
35 | * @inheritDoc
36 | */
37 | public function process(File $phpcsFile, $stackPtr): void
38 | {
39 | $tokens = $phpcsFile->getTokens();
40 |
41 | if ($tokens[$stackPtr]['content'] === '!') {
42 | $prevIndex = $phpcsFile->findPrevious(T_WHITESPACE, ($stackPtr - 1), null, true);
43 | if (!$prevIndex || $tokens[$prevIndex]['content'] !== '!') {
44 | return;
45 | }
46 |
47 | $fix = $phpcsFile->addFixableError('`!!` cast not allowed, use `(bool)`', $stackPtr, 'DoubleNotInvalid');
48 | if ($fix) {
49 | $phpcsFile->fixer->replaceToken($prevIndex, '');
50 | $phpcsFile->fixer->replaceToken($stackPtr, '(bool)');
51 | }
52 |
53 | return;
54 | }
55 |
56 | $content = $tokens[$stackPtr]['content'];
57 | $key = strtolower($content);
58 |
59 | if (!isset(static::$matching[$key])) {
60 | return;
61 | }
62 |
63 | $fix = $phpcsFile->addFixableError($content . ' found, expected ' . static::$matching[$key], $stackPtr, 'LongInvalid');
64 | if ($fix) {
65 | $phpcsFile->fixer->replaceToken($stackPtr, static::$matching[$key]);
66 | }
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/Spryker/Sniffs/PHP/SingleQuoteSniff.php:
--------------------------------------------------------------------------------
1 |
7 | * Dariusz Rumiński
8 | *
9 | * This source file is subject to the MIT license that is bundled
10 | * with this source code in the file LICENSE.
11 | */
12 |
13 | /**
14 | * MIT License
15 | * For full license information, please view the LICENSE file that was distributed with this source code.
16 | */
17 |
18 | namespace Spryker\Sniffs\PHP;
19 |
20 | use PHP_CodeSniffer\Files\File;
21 | use PHP_CodeSniffer\Util\Tokens;
22 | use Spryker\Sniffs\AbstractSniffs\AbstractSprykerSniff;
23 |
24 | /**
25 | * Converts double quotes to single quotes for simple strings.
26 | *
27 | * @author Gregor Harlan
28 | * @author Mark Scherer
29 | */
30 | class SingleQuoteSniff extends AbstractSprykerSniff
31 | {
32 | /**
33 | * @inheritDoc
34 | */
35 | public function register(): array
36 | {
37 | return [T_CONSTANT_ENCAPSED_STRING];
38 | }
39 |
40 | /**
41 | * @inheritDoc
42 | */
43 | public function process(File $phpcsFile, $stackPtr): void
44 | {
45 | $tokens = $phpcsFile->getTokens();
46 |
47 | // Skip for complex multiline
48 | $prevIndex = $phpcsFile->findPrevious(Tokens::$emptyTokens, $stackPtr - 1, null, true);
49 | if ($prevIndex && $tokens[$prevIndex]['code'] === T_CONSTANT_ENCAPSED_STRING) {
50 | return;
51 | }
52 |
53 | $content = $tokens[$stackPtr]['content'];
54 | if (
55 | $content[0] === '"'
56 | && strpos($content, "'") === false
57 | && strpos($content, "\n") === false
58 | // regex: odd number of backslashes, not followed by double quote or dollar
59 | && !preg_match('/(?addFixableError(
62 | 'Use single instead of double quotes for simple strings.',
63 | $stackPtr,
64 | 'UseSingleQuote',
65 | );
66 | if ($fix) {
67 | $content = substr($content, 1, -1);
68 | $content = str_replace(['\\"', '\\$'], ['"', '$'], $content);
69 | $phpcsFile->fixer->replaceToken($stackPtr, '\'' . $content . '\'');
70 | }
71 | }
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/Spryker/Sniffs/WhiteSpace/CommaSpacingSniff.php:
--------------------------------------------------------------------------------
1 | getTokens();
35 |
36 | $next = $phpcsFile->findNext(T_WHITESPACE, ($stackPtr + 1), null, true);
37 | if (!$next) {
38 | return;
39 | }
40 | $this->checkNext($phpcsFile, $stackPtr, $next);
41 |
42 | $previous = $phpcsFile->findPrevious(T_WHITESPACE, ($stackPtr - 1), null, true);
43 | if (!$previous) {
44 | return;
45 | }
46 |
47 | if ($tokens[$previous]['code'] !== T_WHITESPACE && ($previous !== $stackPtr - 1)) {
48 | if ($tokens[$previous]['code'] === T_COMMA) {
49 | return;
50 | }
51 |
52 | $error = 'Space before comma, expected none, though';
53 | $fix = $phpcsFile->addFixableError($error, $next, 'InvalidCommaBefore');
54 | if ($fix) {
55 | $phpcsFile->fixer->replaceToken($previous + 1, '');
56 | }
57 | }
58 | }
59 |
60 | /**
61 | * @param \PHP_CodeSniffer\Files\File $phpcsFile
62 | * @param int $stackPtr
63 | * @param int $next
64 | *
65 | * @return void
66 | */
67 | public function checkNext(File $phpcsFile, int $stackPtr, int $next): void
68 | {
69 | $tokens = $phpcsFile->getTokens();
70 |
71 | // Closing inline array should not have a comma before
72 | if ($tokens[$next]['code'] === T_CLOSE_SHORT_ARRAY && $tokens[$next]['line'] === $tokens[$stackPtr]['line']) {
73 | $error = 'Invalid comma before closing inline array end `]`.';
74 | $fix = $phpcsFile->addFixableError($error, $next, 'InvalidCommaInline');
75 | if ($fix) {
76 | $phpcsFile->fixer->replaceToken($stackPtr, '');
77 | }
78 |
79 | return;
80 | }
81 |
82 | if ($tokens[$next]['code'] !== T_WHITESPACE && ($next !== $stackPtr + 2)) {
83 | // Last character in a line is ok.
84 | if ($tokens[$next]['line'] !== $tokens[$stackPtr]['line']) {
85 | return;
86 | }
87 |
88 | // Closing inline array is also ignored
89 | if (in_array($tokens[$next]['code'], [T_CLOSE_SHORT_ARRAY, T_CLOSE_PARENTHESIS], true)) {
90 | return;
91 | }
92 |
93 | $error = 'Missing space after comma';
94 | $fix = $phpcsFile->addFixableError($error, $next, 'MissingCommaAfter');
95 | if ($fix) {
96 | $phpcsFile->fixer->addContent($stackPtr, ' ');
97 | }
98 | }
99 | }
100 | }
101 |
--------------------------------------------------------------------------------
/Spryker/Sniffs/WhiteSpace/DocBlockSpacingSniff.php:
--------------------------------------------------------------------------------
1 | getTokens();
35 |
36 | $line = $tokens[$stackPtr]['line'];
37 | $beginningOfLine = $stackPtr;
38 | while (!empty($tokens[$beginningOfLine - 1]) && $tokens[$beginningOfLine - 1]['line'] === $line) {
39 | $beginningOfLine--;
40 | }
41 | $previousIndex = $phpcsFile->findPrevious(T_WHITESPACE, ($beginningOfLine - 1), null, true);
42 |
43 | if (!$previousIndex || $tokens[$previousIndex]['code'] !== T_DOC_COMMENT_CLOSE_TAG) {
44 | return;
45 | }
46 |
47 | if ($tokens[$previousIndex]['line'] >= $line - 1) {
48 | return;
49 | }
50 |
51 | $error = 'Additional newline detected between doc block and code';
52 | $fix = $phpcsFile->addFixableError($error, $previousIndex, 'InvalidSpacing');
53 | if (!$fix) {
54 | return;
55 | }
56 |
57 | $phpcsFile->fixer->beginChangeset();
58 | $index = $previousIndex + 1;
59 |
60 | while ($index < $beginningOfLine - 1) {
61 | $phpcsFile->fixer->replaceToken($index, '');
62 | $index++;
63 | }
64 |
65 | $phpcsFile->fixer->endChangeset();
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/Spryker/Sniffs/WhiteSpace/EmptyLinesSniff.php:
--------------------------------------------------------------------------------
1 |
23 | */
24 | public $supportedTokenizers = [
25 | 'PHP',
26 | 'JS',
27 | 'CSS',
28 | ];
29 |
30 | /**
31 | * @inheritDoc
32 | */
33 | public function register(): array
34 | {
35 | return [T_WHITESPACE];
36 | }
37 |
38 | /**
39 | * @inheritDoc
40 | */
41 | public function process(File $phpcsFile, $stackPtr): void
42 | {
43 | $this->assertMaximumOneEmptyLineBetweenContent($phpcsFile, $stackPtr);
44 | }
45 |
46 | /**
47 | * @param \PHP_CodeSniffer\Files\File $phpcsFile
48 | * @param int $stackPtr
49 | *
50 | * @return void
51 | */
52 | protected function assertMaximumOneEmptyLineBetweenContent(File $phpcsFile, int $stackPtr): void
53 | {
54 | $tokens = $phpcsFile->getTokens();
55 |
56 | if (
57 | $tokens[$stackPtr]['content'] === $phpcsFile->eolChar
58 | && isset($tokens[($stackPtr + 1)])
59 | && $tokens[($stackPtr + 1)]['content'] === $phpcsFile->eolChar
60 | && isset($tokens[($stackPtr + 2)])
61 | && $tokens[($stackPtr + 2)]['content'] === $phpcsFile->eolChar
62 | ) {
63 | $error = 'Found more than a single empty line between content';
64 | $fix = $phpcsFile->addFixableError($error, ($stackPtr + 2), 'EmptyLines');
65 | if ($fix) {
66 | $phpcsFile->fixer->replaceToken($stackPtr + 2, '');
67 | }
68 | }
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/Spryker/Sniffs/WhiteSpace/ImplicitCastSpacingSniff.php:
--------------------------------------------------------------------------------
1 | getTokens();
33 |
34 | if ($tokens[$stackPtr]['code'] === T_INC || $tokens[$stackPtr]['code'] === T_DEC) {
35 | $this->processIncDec($phpcsFile, $stackPtr);
36 |
37 | return;
38 | }
39 |
40 | $nextIndex = $phpcsFile->findNext(T_WHITESPACE, ($stackPtr + 1), null, true);
41 |
42 | if ($nextIndex - $stackPtr === 1) {
43 | return;
44 | }
45 |
46 | $fix = $phpcsFile->addFixableError('No whitespace should be between ' . $tokens[$stackPtr]['content'] . ' and variable.', $stackPtr, 'WhitespaceBetweenContentVariable');
47 | if ($fix && $phpcsFile->fixer->enabled) {
48 | $phpcsFile->fixer->beginChangeset();
49 | $phpcsFile->fixer->replaceToken($stackPtr + 1, '');
50 | $phpcsFile->fixer->endChangeset();
51 | }
52 | }
53 |
54 | /**
55 | * @param \PHP_CodeSniffer\Files\File $phpcsFile
56 | * @param int $stackPtr
57 | *
58 | * @return void
59 | */
60 | protected function processIncDec(File $phpcsFile, int $stackPtr): void
61 | {
62 | $tokens = $phpcsFile->getTokens();
63 |
64 | $nextIndex = $phpcsFile->findNext(T_WHITESPACE, ($stackPtr + 1), null, true);
65 | if ($tokens[$nextIndex]['code'] === T_VARIABLE) {
66 | if ($nextIndex - $stackPtr === 1) {
67 | return;
68 | }
69 |
70 | $fix = $phpcsFile->addFixableError('No whitespace should be between incrementor and variable.', $stackPtr, 'WhitespaceBeforeVariable');
71 | if ($fix) {
72 | $phpcsFile->fixer->beginChangeset();
73 | $phpcsFile->fixer->replaceToken($stackPtr + 1, '');
74 | $phpcsFile->fixer->endChangeset();
75 | }
76 |
77 | return;
78 | }
79 |
80 | $prevIndex = $phpcsFile->findPrevious(T_WHITESPACE, ($stackPtr - 1), null, true);
81 | if ($tokens[$prevIndex]['code'] === T_VARIABLE) {
82 | if ($stackPtr - $prevIndex === 1) {
83 | return;
84 | }
85 |
86 | $fix = $phpcsFile->addFixableError('No whitespace should be between variable and incrementor.', $stackPtr, 'WhitespaceAfterVariable');
87 | if ($fix) {
88 | $phpcsFile->fixer->beginChangeset();
89 | $phpcsFile->fixer->replaceToken($stackPtr - 1, '');
90 | $phpcsFile->fixer->endChangeset();
91 | }
92 |
93 | return;
94 | }
95 | }
96 | }
97 |
--------------------------------------------------------------------------------
/Spryker/Sniffs/WhiteSpace/MemberVarSpacingSniff.php:
--------------------------------------------------------------------------------
1 | getTokens();
27 |
28 | $endIndex = $phpcsFile->findNext(T_SEMICOLON, $stackPtr + 1);
29 | if (!$endIndex) {
30 | return;
31 | }
32 | $nextIndex = $phpcsFile->findNext(T_WHITESPACE, $endIndex + 1, null, true);
33 | if (!$nextIndex) {
34 | return;
35 | }
36 |
37 | if ($tokens[$nextIndex]['line'] - $tokens[$endIndex]['line'] === 2) {
38 | return;
39 | }
40 |
41 | // If next token is end of class, we also skip
42 | if ($tokens[$nextIndex]['code'] === T_CLOSE_CURLY_BRACKET) {
43 | return;
44 | }
45 |
46 | $found = $tokens[$nextIndex]['line'] - $tokens[$endIndex]['line'] - 1;
47 | $error = 'Expected 1 blank line after member var; %s found';
48 | $data = [$found];
49 |
50 | $fix = $phpcsFile->addFixableError($error, $stackPtr, 'Incorrect', $data);
51 | if (!$fix) {
52 | return;
53 | }
54 |
55 | if ($tokens[$nextIndex]['line'] - $tokens[$endIndex]['line'] < 2) {
56 | $phpcsFile->fixer->beginChangeset();
57 | $phpcsFile->fixer->addNewline($endIndex);
58 | $phpcsFile->fixer->endChangeset();
59 |
60 | return;
61 | }
62 |
63 | $phpcsFile->fixer->replaceToken($endIndex + 1, '');
64 | }
65 |
66 | /**
67 | * @inheritDoc
68 | */
69 | protected function processVariable(File $phpcsFile, $stackPtr)
70 | {
71 | // We don't care about normal variables.
72 | }
73 |
74 | /**
75 | * @inheritDoc
76 | */
77 | protected function processVariableInString(File $phpcsFile, $stackPtr)
78 | {
79 | // We don't care about normal variables.
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/Spryker/Sniffs/WhiteSpace/NamespaceSpacingSniff.php:
--------------------------------------------------------------------------------
1 | getTokens();
35 |
36 | $beforeIndex = $phpcsFile->findPrevious(T_WHITESPACE, ($stackPtr - 1), null, true);
37 | if (!$beforeIndex) {
38 | return;
39 | }
40 | $beforeLine = $tokens[$beforeIndex]['line'];
41 |
42 | if ($beforeLine === $tokens[$stackPtr]['line'] - 2) {
43 | return;
44 | }
45 |
46 | $error = 'There must be one blank line before the namespace declaration';
47 | $fix = $phpcsFile->addFixableError($error, $stackPtr, 'BlankLineBefore');
48 | if (!$fix) {
49 | return;
50 | }
51 |
52 | if ($beforeLine < $tokens[$stackPtr]['line'] - 2) {
53 | $phpcsFile->fixer->beginChangeset();
54 | $phpcsFile->fixer->replaceToken($stackPtr - 1, '');
55 | $phpcsFile->fixer->endChangeset();
56 |
57 | return;
58 | }
59 |
60 | $phpcsFile->fixer->beginChangeset();
61 | $phpcsFile->fixer->addNewline($beforeIndex);
62 | $phpcsFile->fixer->endChangeset();
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/Spryker/Sniffs/WhiteSpace/ObjectAttributeSpacingSniff.php:
--------------------------------------------------------------------------------
1 | getTokens();
35 |
36 | // Make sure there is no space before.
37 | $previousToken = $phpcsFile->findPrevious(T_WHITESPACE, ($stackPtr - 1), null, true);
38 |
39 | if ($stackPtr - $previousToken !== 1 && $tokens[$previousToken]['line'] === $tokens[$stackPtr]['line']) {
40 | $error = 'Expected no space before object operator `' . $tokens[$stackPtr]['content'] . '`';
41 | $fix = $phpcsFile->addFixableError($error, $stackPtr - 1, 'TooMany');
42 | if ($fix) {
43 | $phpcsFile->fixer->replaceToken($stackPtr - 1, '');
44 | }
45 | }
46 |
47 | // Make sure there is no space after.
48 | $nextToken = $phpcsFile->findNext(T_WHITESPACE, ($stackPtr + 1), null, true);
49 |
50 | if ($nextToken - $stackPtr !== 1 && $tokens[$nextToken]['line'] === $tokens[$stackPtr]['line']) {
51 | $error = 'Expected no space after object operator `' . $tokens[$stackPtr]['content'] . '`';
52 | $fix = $phpcsFile->addFixableError($error, $stackPtr + 1, 'TooMany');
53 | if ($fix) {
54 | $phpcsFile->fixer->replaceToken($stackPtr + 1, '');
55 | }
56 | }
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/Spryker/Sniffs/WhiteSpace/TernarySpacingSniff.php:
--------------------------------------------------------------------------------
1 |
23 | */
24 | public $supportedTokenizers = [
25 | 'PHP',
26 | ];
27 |
28 | /**
29 | * @inheritDoc
30 | */
31 | public function register(): array
32 | {
33 | return [
34 | T_INLINE_THEN,
35 | ];
36 | }
37 |
38 | /**
39 | * @inheritDoc
40 | */
41 | public function process(File $phpcsFile, $stackPtr): void
42 | {
43 | $tokens = $phpcsFile->getTokens();
44 |
45 | $nextIndex = $phpcsFile->findNext(T_WHITESPACE, $stackPtr + 1, null, true);
46 | if (!$nextIndex || $nextIndex - 1 === $stackPtr || $tokens[$nextIndex]['code'] !== T_INLINE_ELSE) {
47 | return;
48 | }
49 |
50 | if ($tokens[$nextIndex - 1]['code'] !== T_WHITESPACE) {
51 | return;
52 | }
53 |
54 | $fix = $phpcsFile->addFixableError('Additional whitespace found between short ternary', $stackPtr, 'InvalidWhitespace');
55 | if (!$fix) {
56 | return;
57 | }
58 |
59 | $phpcsFile->fixer->beginChangeset();
60 | $phpcsFile->fixer->replaceToken($nextIndex - 1, '');
61 | $phpcsFile->fixer->endChangeset();
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/Spryker/Tools/SniffsAndTests.php:
--------------------------------------------------------------------------------
1 |
19 | */
20 | protected static $orgs = [
21 | 'Spryker',
22 | 'SprykerStrict',
23 | //'GlueStreamSpecific',
24 | ];
25 |
26 | /**
27 | * @param string $path Path
28 | *
29 | * @return array>
30 | */
31 | public function untested(string $path): array
32 | {
33 | $path = rtrim($path, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
34 |
35 | $sniffs = [];
36 |
37 | foreach (static::$orgs as $org) {
38 | $directoryIterator = new RecursiveDirectoryIterator($path . $org);
39 | $recursiveIterator = new RecursiveIteratorIterator($directoryIterator);
40 | $regexIterator = new RegexIterator($recursiveIterator, '#^.+/(\w+)/Sniffs/(\w+)/(\w+)Sniff\.php$#', RecursiveRegexIterator::GET_MATCH);
41 |
42 | foreach ($regexIterator as $match) {
43 | $org = $match[1];
44 | $type = $match[2];
45 | $name = $match[3];
46 | $testFile = $path . 'tests' . DIRECTORY_SEPARATOR . $org . 'Sniffs' . DIRECTORY_SEPARATOR . $type . DIRECTORY_SEPARATOR . $name . 'SniffTest.php';
47 | $hasTest = file_exists($testFile);
48 | if ($hasTest) {
49 | continue;
50 | }
51 |
52 | $key = $org . '.' . $type . '.' . $name;
53 | $sniffs[$key] = [
54 | 'hasTest' => $hasTest,
55 | ];
56 | }
57 | }
58 |
59 | return $sniffs;
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/Spryker/Traits/BasicsTrait.php:
--------------------------------------------------------------------------------
1 | |string|int $search
17 | * @param array $token
18 | *
19 | * @return bool
20 | */
21 | protected function isGivenKind($search, array $token): bool
22 | {
23 | $kind = (array)$search;
24 |
25 | if (in_array($token['code'], $kind, true)) {
26 | return true;
27 | }
28 | if (in_array($token['type'], $kind, true)) {
29 | return true;
30 | }
31 |
32 | return false;
33 | }
34 |
35 | /**
36 | * @param \PHP_CodeSniffer\Files\File $phpcsFile
37 | *
38 | * @return array>
39 | */
40 | protected function getNamespaceStatement(File $phpcsFile): array
41 | {
42 | $tokens = $phpcsFile->getTokens();
43 |
44 | $namespaceIndex = $phpcsFile->findNext(T_NAMESPACE, 0);
45 | if (!$namespaceIndex) {
46 | return [];
47 | }
48 |
49 | $endIndex = $phpcsFile->findNext([T_SEMICOLON, T_OPEN_CURLY_BRACKET], $namespaceIndex + 1);
50 | if (!$endIndex) {
51 | return [];
52 | }
53 |
54 | $namespace = '';
55 | $namespaceStartIndex = $phpcsFile->findNext(Tokens::$emptyTokens, $namespaceIndex + 1, null, true);
56 | $namespaceEndIndex = $phpcsFile->findPrevious(Tokens::$emptyTokens, $endIndex - 1, null, true);
57 | for ($i = $namespaceStartIndex; $i <= $namespaceEndIndex; $i++) {
58 | $namespace .= $tokens[$i]['content'];
59 | }
60 |
61 | return [
62 | 'start' => $namespaceIndex,
63 | 'namespace' => $namespace,
64 | 'end' => $endIndex,
65 | ];
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/Spryker/Traits/NamespaceTrait.php:
--------------------------------------------------------------------------------
1 | getTokens();
28 |
29 | // Ignore USE keywords inside closures.
30 | $next = $phpcsFile->findNext(T_WHITESPACE, ($stackPtr + 1), null, true);
31 | if ($tokens[$next]['code'] === T_OPEN_PARENTHESIS) {
32 | return true;
33 | }
34 |
35 | // Ignore USE keywords for traits.
36 | if ($phpcsFile->hasCondition($stackPtr, [T_CLASS, T_TRAIT]) === true) {
37 | return true;
38 | }
39 |
40 | return false;
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/Spryker/Traits/SignatureTrait.php:
--------------------------------------------------------------------------------
1 | >
22 | */
23 | protected function getMethodSignature(File $phpCsFile, int $stackPtr): array
24 | {
25 | $parameters = $phpCsFile->getMethodParameters($stackPtr);
26 | $tokens = $phpCsFile->getTokens();
27 |
28 | $arguments = [];
29 | foreach ($parameters as $parameter) {
30 | $defaultIndex = $default = null;
31 |
32 | $possibleEqualIndex = $phpCsFile->findNext([T_EQUAL], $parameter['token'] + 1, $parameter['token'] + 3);
33 | if ($possibleEqualIndex) {
34 | $whitelist = [T_CONSTANT_ENCAPSED_STRING, T_TRUE, T_FALSE, T_NULL, T_OPEN_SHORT_ARRAY, T_LNUMBER, T_DNUMBER];
35 | $possibleDefaultValue = $phpCsFile->findNext($whitelist, $possibleEqualIndex + 1, $possibleEqualIndex + 3);
36 | if ($possibleDefaultValue) {
37 | $defaultIndex = $possibleDefaultValue;
38 | $default = null;
39 | if ($tokens[$defaultIndex]['code'] === T_CONSTANT_ENCAPSED_STRING) {
40 | $default = 'string';
41 | } elseif ($tokens[$defaultIndex]['code'] === T_OPEN_SHORT_ARRAY) {
42 | $default = 'array';
43 | } elseif ($tokens[$defaultIndex]['code'] === T_FALSE || $tokens[$defaultIndex]['code'] === T_TRUE) {
44 | $default = 'bool';
45 | } elseif ($tokens[$defaultIndex]['code'] === T_LNUMBER) {
46 | $default = 'int';
47 | } elseif ($tokens[$defaultIndex]['code'] === T_DNUMBER) {
48 | $default = 'float';
49 | } elseif ($tokens[$defaultIndex]['code'] === T_NULL) {
50 | $default = 'null';
51 | }
52 | }
53 | }
54 |
55 | $typehint = $parameter['type_hint'];
56 | if (substr($typehint, 0, 1) === '?') {
57 | $typehint = substr($typehint, 1);
58 | }
59 |
60 | $arguments[] = [
61 | 'variableIndex' => $parameter['token'],
62 | 'variable' => $parameter['name'],
63 | 'typehint' => $typehint,
64 | 'typehintFull' => $parameter['type_hint'],
65 | 'nullable' => $parameter['nullable_type'],
66 | 'defaultIndex' => $defaultIndex,
67 | 'default' => $default,
68 | ];
69 | }
70 |
71 | return $arguments;
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/Spryker/Traits/UseStatementsTrait.php:
--------------------------------------------------------------------------------
1 | >
19 | */
20 | protected function getUseStatements(File $phpcsFile): array
21 | {
22 | $tokens = $phpcsFile->getTokens();
23 |
24 | $statements = [];
25 | foreach ($tokens as $index => $token) {
26 | if ($token['code'] !== T_USE || $token['level'] > 0) {
27 | continue;
28 | }
29 |
30 | $useStatementStartIndex = $phpcsFile->findNext(Tokens::$emptyTokens, $index + 1, null, true);
31 |
32 | // Ignore function () use ($foo) {}
33 | if ($tokens[$useStatementStartIndex]['content'] === '(') {
34 | continue;
35 | }
36 |
37 | $semicolonIndex = $phpcsFile->findNext(T_SEMICOLON, $useStatementStartIndex + 1);
38 | $useStatementEndIndex = $phpcsFile->findPrevious(Tokens::$emptyTokens, $semicolonIndex - 1, null, true);
39 |
40 | $statement = '';
41 | for ($i = $useStatementStartIndex; $i <= $useStatementEndIndex; $i++) {
42 | $statement .= $tokens[$i]['content'];
43 | }
44 |
45 | // Another sniff takes care of that, we just ignore then.
46 | if ($this->isMultipleUseStatement($statement)) {
47 | continue;
48 | }
49 |
50 | $statementParts = preg_split('/\s+as\s+/i', $statement) ?: [];
51 |
52 | if (count($statementParts) === 1) {
53 | $fullName = $statement;
54 | $statementParts = explode('\\', $fullName);
55 | $shortName = end($statementParts);
56 | $alias = null;
57 | } else {
58 | $fullName = $statementParts[0];
59 | $alias = $statementParts[1];
60 | $statementParts = explode('\\', $fullName);
61 | $shortName = end($statementParts);
62 | }
63 |
64 | $shortName = trim($shortName);
65 | $fullName = trim($fullName);
66 | $key = $alias ?: $shortName;
67 |
68 | $statements[$key] = [
69 | 'alias' => $alias,
70 | 'end' => $semicolonIndex,
71 | 'statement' => $statement,
72 | 'fullName' => ltrim($fullName, '\\'),
73 | 'shortName' => $shortName,
74 | 'start' => $index,
75 | ];
76 | }
77 |
78 | return $statements;
79 | }
80 |
81 | /**
82 | * @param string $statementContent
83 | *
84 | * @return bool
85 | */
86 | protected function isMultipleUseStatement(string $statementContent): bool
87 | {
88 | if (strpos($statementContent, ',') !== false) {
89 | return true;
90 | }
91 |
92 | return false;
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/SprykerStrict/Sniffs/TypeHints/ParameterTypeHintSniff.php:
--------------------------------------------------------------------------------
1 | isSprykerBridgeConstructor($phpcsFile, $pointer)) {
24 | return;
25 | }
26 |
27 | parent::process($phpcsFile, $pointer);
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/SprykerStrict/Sniffs/TypeHints/PropertyTypeHintSniff.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | SprykerStrict Coding Standard.
5 |
6 | All sniffs in ./Sniffs will be auto loaded
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/bin/tokenize:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | canonicalize() {
4 | NAME="$1"
5 | if [ -f "$NAME" ]
6 | then
7 | DIR=$(dirname -- "$NAME")
8 | NAME=$(cd -P "$DIR" > /dev/null && pwd -P)/$(basename -- "$NAME")
9 | fi
10 | while [ -h "$NAME" ]; do
11 | DIR=$(dirname -- "$NAME")
12 | SYM=$(readlink "$NAME")
13 | NAME=$(cd "$DIR" > /dev/null && cd $(dirname -- "$SYM") > /dev/null && pwd)/$(basename -- "$SYM")
14 | done
15 | echo "$NAME"
16 | }
17 |
18 | CONSOLE=$(dirname -- "$(canonicalize "$0")")
19 | APP=$(dirname "$CONSOLE")
20 |
21 | if [ $(basename $0) != 'tokenize' ]
22 | then
23 | exec php "$CONSOLE"/tokenize.php $(basename $0) "$@"
24 | else
25 | exec php "$CONSOLE"/tokenize.php "$@"
26 | fi
27 |
28 | exit 0
29 |
--------------------------------------------------------------------------------
/bin/tokenize.bat:
--------------------------------------------------------------------------------
1 | @echo off
2 |
3 | SET app=%0
4 | SET lib=%~dp0
5 |
6 | php "%lib%tokenize.php" %*
7 |
8 | echo.
9 |
10 | exit /B %ERRORLEVEL%
11 |
--------------------------------------------------------------------------------
/bin/tokenize.php:
--------------------------------------------------------------------------------
1 | #!/usr/bin/php -q
2 | tokenize();
26 | echo 0;
27 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "spryker/code-sniffer",
3 | "description": "Spryker Code Sniffer Standards",
4 | "type": "phpcodesniffer-standard",
5 | "license": "MIT",
6 | "keywords": [
7 | "framework",
8 | "codesniffer",
9 | "phpcs",
10 | "static analysis",
11 | "standards"
12 | ],
13 | "homepage": "https://spryker.com",
14 | "authors": [
15 | {
16 | "name": "Spryker",
17 | "homepage": "https://spryker.com"
18 | }
19 | ],
20 | "require": {
21 | "php": ">=8.1",
22 | "phpstan/phpdoc-parser": "^1.33.0",
23 | "slevomat/coding-standard": "^7.2.0 || ^8.0.1",
24 | "squizlabs/php_codesniffer": "^3.6.2"
25 | },
26 | "require-dev": {
27 | "phpstan/phpstan": "^1.0.0",
28 | "phpunit/phpunit": "^9.5"
29 | },
30 | "autoload": {
31 | "psr-4": {
32 | "Spryker\\": "Spryker/",
33 | "SprykerStrict\\": "SprykerStrict/"
34 | }
35 | },
36 | "autoload-dev": {
37 | "psr-4": {
38 | "Spryker\\Test\\": "tests/"
39 | },
40 | "files": [
41 | "vendor/squizlabs/php_codesniffer/autoload.php"
42 | ]
43 | },
44 | "scripts": {
45 | "docs": "php docs/generate.php",
46 | "docs-listing": "phpcs -e --standard=SprykerStrict/ruleset.xml",
47 | "add-standard": "phpcs --config-set installed_paths $(pwd)",
48 | "increase-severity": "sed -i.bak 's/0<\\/severity>//' Spryker/ruleset.xml",
49 | "reset-ruleset": [
50 | "sed -i.bak 's//0<\\/severity>/' Spryker/ruleset.xml",
51 | "rm -f Spryker/ruleset.xml.bak"
52 | ],
53 | "cs-check": "vendor/bin/phpcs --extensions=php",
54 | "cs-fix": "vendor/bin/phpcbf --extensions=php",
55 | "test": "vendor/bin/phpunit",
56 | "stan": "phpstan analyse",
57 | "xml": "tests/xmllint.sh"
58 | },
59 | "bin": [
60 | "bin/tokenize"
61 | ],
62 | "support": {
63 | "source": "https://github.com/spryker/code-sniffer"
64 | },
65 | "config": {
66 | "sort-packages": true,
67 | "process-timeout": 900,
68 | "allow-plugins": {
69 | "dealerdirect/phpcodesniffer-composer-installer": true
70 | }
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/docs/generate.php:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env php
2 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | Spryker/
10 | SprykerStrict/
11 | GlueStreamSpecific/
12 | tests/Spryker/
13 | tests/TestCase.php
14 | docs/
15 | bin/
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 | /Spryker/tests/files/
28 |
29 |
30 |
--------------------------------------------------------------------------------
/phpstan.neon:
--------------------------------------------------------------------------------
1 | parameters:
2 | level: 8
3 | checkGenericClassInNonGenericObjectType: false
4 | paths:
5 | - Spryker/
6 | - SprykerStrict/
7 | - GlueStreamSpecific/
8 | bootstrapFiles:
9 | - '%rootDir%/../../../tests/bootstrap.php'
10 |
--------------------------------------------------------------------------------
/tests/Spryker/Sniffs/AllSniffTest.php:
--------------------------------------------------------------------------------
1 | testFilePath() . 'All' . DS . 'before.php';
23 | $after = $this->testFilePath() . 'All' . DS . 'after.php';
24 |
25 | // Use --debug to display the errors found
26 | $errors = $this->runFullFixer($before, $after);
27 | $this->assertNotEmpty($errors);
28 |
29 | $this->runFullFixer($before, $after, null, null, true);
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/tests/Spryker/Sniffs/Commenting/DisallowArrayTypeHintSyntaxSniffTest.php:
--------------------------------------------------------------------------------
1 | assertSnifferFindsErrors(new DisallowArrayTypeHintSyntaxSniff(), 12);
21 | }
22 |
23 | /**
24 | * @return void
25 | */
26 | public function testDocBlockThrowsFixer(): void
27 | {
28 | $this->assertSnifferCanFixErrors(new DisallowArrayTypeHintSyntaxSniff());
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/tests/Spryker/Sniffs/Commenting/DocBlockConstSniffTest.php:
--------------------------------------------------------------------------------
1 | assertSnifferFindsErrors(new DocBlockConstSniff(), 4);
21 | }
22 |
23 | /**
24 | * @return void
25 | */
26 | public function testDocBlockConstFixer(): void
27 | {
28 | $this->assertSnifferCanFixErrors(new DocBlockConstSniff());
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/tests/Spryker/Sniffs/Commenting/DocBlockParamAllowDefaultValueSniffTest.php:
--------------------------------------------------------------------------------
1 | assertSnifferFindsErrors(new DocBlockParamAllowDefaultValueSniff(), 4);
21 | }
22 |
23 | /**
24 | * @return void
25 | */
26 | public function testDocBlockConstFixer(): void
27 | {
28 | $this->assertSnifferCanFixErrors(new DocBlockParamAllowDefaultValueSniff());
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/tests/Spryker/Sniffs/Commenting/DocBlockParamArraySniffTest.php:
--------------------------------------------------------------------------------
1 | assertSnifferFindsErrors(new DocBlockParamArraySniff(), 2);
21 | }
22 |
23 | /**
24 | * @return void
25 | */
26 | public function testDocBlockConstFixer(): void
27 | {
28 | $this->assertSnifferCanFixErrors(new DocBlockParamArraySniff());
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/tests/Spryker/Sniffs/Commenting/DocBlockReturnNullSniffTest.php:
--------------------------------------------------------------------------------
1 | assertSnifferFindsErrors(new DocBlockReturnNullSniff(), 1);
21 | }
22 |
23 | /**
24 | * @return void
25 | */
26 | public function testDocBlockConstFixer(): void
27 | {
28 | $this->assertSnifferCanFixErrors(new DocBlockReturnNullSniff());
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/tests/Spryker/Sniffs/Commenting/DocBlockReturnNullableTypeSniffTest.php:
--------------------------------------------------------------------------------
1 | assertSnifferFindsErrors(new DocBlockReturnNullableTypeSniff(), 3);
21 | }
22 |
23 | /**
24 | * @return void
25 | */
26 | public function testDocBlockConstFixer(): void
27 | {
28 | $this->assertSnifferCanFixErrors(new DocBlockReturnNullableTypeSniff());
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/tests/Spryker/Sniffs/Commenting/DocBlockReturnTagSniffTest.php:
--------------------------------------------------------------------------------
1 | assertSnifferFindsErrors(new DocBlockReturnTagSniff(), 1);
21 | }
22 |
23 | /**
24 | * @return void
25 | */
26 | public function testDocBlockConstFixer(): void
27 | {
28 | $this->assertSnifferCanFixErrors(new DocBlockReturnTagSniff());
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/tests/Spryker/Sniffs/Commenting/DocBlockReturnVoidSniffTest.php:
--------------------------------------------------------------------------------
1 | assertSnifferFindsFixableErrors(new DocBlockReturnVoidSniff(), 3, 3);
21 | }
22 |
23 | /**
24 | * @return void
25 | */
26 | public function testDocBlockReturnVoidFixer(): void
27 | {
28 | $this->assertSnifferCanFixErrors(new DocBlockReturnVoidSniff(), 3);
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/tests/Spryker/Sniffs/Commenting/DocBlockThrowsSniffTest.php:
--------------------------------------------------------------------------------
1 | assertSnifferFindsErrors(new DocBlockThrowsSniff(), 6);
21 | }
22 |
23 | /**
24 | * @return void
25 | */
26 | public function testDocBlockThrowsFixer(): void
27 | {
28 | $this->assertSnifferCanFixErrors(new DocBlockThrowsSniff(), 6);
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/tests/Spryker/Sniffs/Commenting/DocBlockVarSniffTest.php:
--------------------------------------------------------------------------------
1 | assertSnifferFindsErrors(new DocBlockVarSniff(), 1);
21 | }
22 |
23 | /**
24 | * @return void
25 | */
26 | public function testDocBlockConstFixer(): void
27 | {
28 | $this->assertSnifferCanFixErrors(new DocBlockVarSniff());
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/tests/Spryker/Sniffs/Commenting/FullyQualifiedClassNameInDocBlockSniffTest.php:
--------------------------------------------------------------------------------
1 | assertSnifferFindsErrors(new FullyQualifiedClassNameInDocBlockSniff(), 11);
21 | }
22 |
23 | /**
24 | * @return void
25 | */
26 | public function testDocBlockConstFixer(): void
27 | {
28 | $this->assertSnifferCanFixErrors(new FullyQualifiedClassNameInDocBlockSniff());
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/tests/Spryker/Sniffs/Commenting/InlineDocBlockSniffTest.php:
--------------------------------------------------------------------------------
1 | assertSnifferFindsErrors(new InlineDocBlockSniff(), 1);
21 | }
22 |
23 | /**
24 | * @return void
25 | */
26 | public function testDocBlockConstFixer(): void
27 | {
28 | $this->assertSnifferCanFixErrors(new InlineDocBlockSniff());
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/tests/Spryker/Sniffs/Commenting/TypeHintSniffTest.php:
--------------------------------------------------------------------------------
1 | assertSnifferFindsErrors(new TypeHintSniff(), 10);
21 | }
22 |
23 | /**
24 | * @return void
25 | */
26 | public function testDocBlockThrowsFixer(): void
27 | {
28 | $this->assertSnifferCanFixErrors(new TypeHintSniff());
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/tests/Spryker/Sniffs/ControlStructures/DisallowCloakingCheckSniffTest.php:
--------------------------------------------------------------------------------
1 | assertSnifferFindsErrors(new DisallowCloakingCheckSniff(), 10);
21 | }
22 |
23 | /**
24 | * @return void
25 | */
26 | public function testDocBlockThrowsFixer(): void
27 | {
28 | $this->assertSnifferCanFixErrors(new DisallowCloakingCheckSniff());
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/tests/Spryker/Sniffs/Formatting/MethodSignatureParametersLineBreakMethodSniffTest.php:
--------------------------------------------------------------------------------
1 | assertSnifferFindsFixableErrors(new MethodSignatureParametersLineBreakMethodSniff(), 7, 7);
21 | }
22 |
23 | /**
24 | * @return void
25 | */
26 | public function testMethodSignatureParametersLineBreakMethodFixer(): void
27 | {
28 | $this->assertSnifferCanFixErrors(new MethodSignatureParametersLineBreakMethodSniff());
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/tests/Spryker/Sniffs/Internal/SprykerPreferStaticOverSelfSniffTest.php:
--------------------------------------------------------------------------------
1 | assertSnifferFindsErrors(new SprykerPreferStaticOverSelfSniff(), 2);
21 | }
22 |
23 | /**
24 | * @return void
25 | */
26 | public function testDocBlockConstFixer(): void
27 | {
28 | $this->assertSnifferCanFixErrors(new SprykerPreferStaticOverSelfSniff());
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/tests/Spryker/Sniffs/Namespaces/UseStatementSniffTest.php:
--------------------------------------------------------------------------------
1 | assertSnifferFindsErrors(new UseStatementSniff(), 1);
21 | }
22 |
23 | /**
24 | * @return void
25 | */
26 | public function testDocBlockConstFixer(): void
27 | {
28 | $this->assertSnifferCanFixErrors(new UseStatementSniff());
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/tests/Spryker/Sniffs/PHP/DeclareStrictTypesAfterFileDocSniffTest.php:
--------------------------------------------------------------------------------
1 | assertSnifferFindsErrors(new DeclareStrictTypesAfterFileDocSniff(), 2);
21 | }
22 |
23 | /**
24 | * @return void
25 | */
26 | public function testEmptyEnclosingLineFixer(): void
27 | {
28 | $this->assertSnifferCanFixErrors(new DeclareStrictTypesAfterFileDocSniff());
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/tests/Spryker/Sniffs/WhiteSpace/EmptyEnclosingLineSniffTest.php:
--------------------------------------------------------------------------------
1 | assertSnifferFindsErrors(new EmptyEnclosingLineSniff(), 2);
21 | }
22 |
23 | /**
24 | * @return void
25 | */
26 | public function testEmptyEnclosingLineFixer(): void
27 | {
28 | $this->assertSnifferCanFixErrors(new EmptyEnclosingLineSniff());
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/tests/Spryker/Sniffs/WhiteSpace/EmptyLinesSniffTest.php:
--------------------------------------------------------------------------------
1 | assertSnifferFindsErrors(new EmptyLinesSniff(), 6);
21 | }
22 |
23 | /**
24 | * @return void
25 | */
26 | public function testEmptyEnclosingLineFixer(): void
27 | {
28 | $this->assertSnifferCanFixErrors(new EmptyLinesSniff());
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/tests/_data/All/after.php:
--------------------------------------------------------------------------------
1 | $y) {
19 | }
20 | if ($y > $z) {
21 | }
22 | }
23 |
24 | /**
25 | * @return void
26 | */
27 | public function tooMuchWhitespace()
28 | {
29 | if ($x > $y) {
30 | }
31 | if ($y > $z) {
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/tests/_data/All/before.php:
--------------------------------------------------------------------------------
1 | $y) {
10 | }
11 | if ($y> $z) {
12 | }
13 | }
14 |
15 | public function tooMuchWhitespace()
16 | {
17 | if ($x > $y) {
18 | }
19 | if ($y > $z) {
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/tests/_data/DeclareStrictTypesAfterFileDoc/after.php:
--------------------------------------------------------------------------------
1 |
9 | */
10 | protected $prop;
11 |
12 | /**
13 | * @var \ArrayObject Some description.
14 | */
15 | protected $propWithDescription;
16 |
17 | /**
18 | * @param array $var
19 | *
20 | * @return array
21 | */
22 | protected function getSimpleInts(array $var): array
23 | {
24 | return $this->foo();
25 | }
26 |
27 | /**
28 | * @param \ArrayObject $var Some comment.
29 | *
30 | * @return \ArrayObject
31 | */
32 | protected function getSimpleStringCollection($var)
33 | {
34 | return $this->foo();
35 | }
36 |
37 | /**
38 | * @return \ArrayObject|array
39 | */
40 | protected function getArrayObjectOrArray()
41 | {
42 | return $this->foo();
43 | }
44 |
45 | /**
46 | * @return \ArrayObject|array
47 | */
48 | protected function getArrayObjectOfStringsOrArrayOfInts()
49 | {
50 | return $this->foo();
51 | }
52 |
53 | /**
54 | * @return \ArrayObject|null
55 | */
56 | protected function getSimpleStringCollectionOrNull(): ?\ArrayObject
57 | {
58 | return $this->foo();
59 | }
60 |
61 | /**
62 | * @return \Iterator
63 | */
64 | protected function getSimpleIntCollection(): Iterator
65 | {
66 | return $this->foo();
67 | }
68 |
69 | /**
70 | * @return \Iterator>
71 | */
72 | protected function createEventResourceQueryContainerPluginIterator(): Iterator
73 | {
74 | return new EventResourceQueryContainerPluginIterator();
75 | }
76 |
77 | /**
78 | * @return void
79 | */
80 | protected function inlineDocBlock()
81 | {
82 | /** @var \ArrayObject $bar */
83 | $bar = $this->foo();
84 |
85 | /**
86 | * @var \ArrayObject $bar
87 | */
88 | $bar = $this->foo();
89 | }
90 | }
91 |
--------------------------------------------------------------------------------
/tests/_data/DisallowArrayTypeHintSyntax/before.php:
--------------------------------------------------------------------------------
1 | foo();
25 | }
26 |
27 | /**
28 | * @param \ArrayObject|string[] $var Some comment.
29 | *
30 | * @return \ArrayObject|string[]
31 | */
32 | protected function getSimpleStringCollection($var)
33 | {
34 | return $this->foo();
35 | }
36 |
37 | /**
38 | * @return \ArrayObject|array
39 | */
40 | protected function getArrayObjectOrArray()
41 | {
42 | return $this->foo();
43 | }
44 |
45 | /**
46 | * @return \ArrayObject|int[]
47 | */
48 | protected function getArrayObjectOfStringsOrArrayOfInts()
49 | {
50 | return $this->foo();
51 | }
52 |
53 | /**
54 | * @return \ArrayObject|string[]|null
55 | */
56 | protected function getSimpleStringCollectionOrNull(): ?\ArrayObject
57 | {
58 | return $this->foo();
59 | }
60 |
61 | /**
62 | * @return \Iterator|int[]
63 | */
64 | protected function getSimpleIntCollection(): Iterator
65 | {
66 | return $this->foo();
67 | }
68 |
69 | /**
70 | * @return \Iterator|\Generated\Shared\Transfer\EventEntityTransfer[][]
71 | */
72 | protected function createEventResourceQueryContainerPluginIterator(): Iterator
73 | {
74 | return new EventResourceQueryContainerPluginIterator();
75 | }
76 |
77 | /**
78 | * @return void
79 | */
80 | protected function inlineDocBlock()
81 | {
82 | /** @var \ArrayObject|string[] $bar */
83 | $bar = $this->foo();
84 |
85 | /**
86 | * @var \ArrayObject|string[] $bar
87 | */
88 | $bar = $this->foo();
89 | }
90 | }
91 |
--------------------------------------------------------------------------------
/tests/_data/DisallowCloakingCheck/after.php:
--------------------------------------------------------------------------------
1 | ok()) {
17 | }
18 |
19 | if (
20 | $this->foo('x', 'y')
21 | || $this->ok()
22 | ) {
23 | }
24 |
25 | $foo->_if((bool)$filterByCompanyBusinessUnitIds);
26 |
27 | if (!isset($this->prop)) {
28 | }
29 |
30 | $x = (bool)$this->prop;
31 |
32 | return (bool)$x;
33 | }
34 |
35 | public function simplify()
36 | {
37 | if (empty($iso2Code) === false) {}
38 | if (isset($iso2Code) === true) {}
39 | }
40 |
41 | public function complex($successTable)
42 | {
43 | return [
44 | 'renderSuccessTable' => empty($successTable->getData()) !== true,
45 | ];
46 | }
47 |
48 | public function ok()
49 | {
50 | $x = [];
51 | if (!empty($x['y'])) {
52 | }
53 | }
54 |
55 | public function ignoreForNow()
56 | {
57 | $y = 'y';
58 | $x = [];
59 | if (!isset($x->{$y})) {}
60 |
61 | if (!isset($xmlProcess->events)) {}
62 |
63 | if (!isset($this->_joinData->relation)) {}
64 |
65 | if (empty($_SESSION)) {}
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/tests/_data/DisallowCloakingCheck/before.php:
--------------------------------------------------------------------------------
1 | ok())) {
17 | }
18 |
19 | if (
20 | !empty($this->foo('x', 'y'))
21 | || $this->ok()
22 | ) {
23 | }
24 |
25 | $foo->_if(!empty($filterByCompanyBusinessUnitIds));
26 |
27 | if (!isset($this->prop)) {
28 | }
29 |
30 | $x = !empty($this->prop);
31 |
32 | return !empty($x);
33 | }
34 |
35 | public function simplify()
36 | {
37 | if (empty($iso2Code) === false) {}
38 | if (isset($iso2Code) === true) {}
39 | }
40 |
41 | public function complex($successTable)
42 | {
43 | return [
44 | 'renderSuccessTable' => empty($successTable->getData()) !== true,
45 | ];
46 | }
47 |
48 | public function ok()
49 | {
50 | $x = [];
51 | if (!empty($x['y'])) {
52 | }
53 | }
54 |
55 | public function ignoreForNow()
56 | {
57 | $y = 'y';
58 | $x = [];
59 | if (!isset($x->{$y})) {}
60 |
61 | if (!isset($xmlProcess->events)) {}
62 |
63 | if (!isset($this->_joinData->relation)) {}
64 |
65 | if (empty($_SESSION)) {}
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/tests/_data/DocBlockConst/after.php:
--------------------------------------------------------------------------------
1 | |string
34 | */
35 | public const CONST_COMPLEX = 'complex case';
36 |
37 | /**
38 | * @var array
39 | */
40 | public const CONST_COMPLEX_MISS = 'complex case missing string';
41 | }
42 |
--------------------------------------------------------------------------------
/tests/_data/DocBlockConst/before.php:
--------------------------------------------------------------------------------
1 | |string
28 | */
29 | public const CONST_COMPLEX = 'complex case';
30 |
31 | /**
32 | * @var array
33 | */
34 | public const CONST_COMPLEX_MISS = 'complex case missing string';
35 | }
36 |
--------------------------------------------------------------------------------
/tests/_data/DocBlockParamAllowDefaultValue/after.php:
--------------------------------------------------------------------------------
1 | >|null $array
27 | * @return void
28 | */
29 | public function generics(array $array = null): void
30 | {
31 | }
32 |
33 | /**
34 | * @param iterable<\Generated\Shared\Transfer\SalesPaymentTransfer> $x
35 | *
36 | * @return array<\Orm\Zed\Payment\Persistence\SpySalesPayment>
37 | */
38 | public function iterableTest(iterable $x = []): array
39 | {
40 | return $x;
41 | }
42 |
43 | /**
44 | * @param \ArrayObject|iterable $itemTransfers
45 | *
46 | * @return array
47 | */
48 | protected function getCountryIso2Codes(iterable $itemTransfers): array
49 | {
50 | return array_unique($itemTransfers);
51 | }
52 |
53 | /**
54 | * @param class-string<\Propel\Runtime\Map\TableMap> $tableMapClass The name of the table map to add
55 | *
56 | * @return void
57 | */
58 | public function registerTableMapClass(string $tableMapClass): void
59 | {
60 | }
61 |
62 | /**
63 | * @param string|null $value The value to convert.
64 | *
65 | * @return string|null
66 | */
67 | public function toPHP(mixed $value): mixed {
68 | return $value;
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/tests/_data/DocBlockParamAllowDefaultValue/before.php:
--------------------------------------------------------------------------------
1 | > $array
27 | * @return void
28 | */
29 | public function generics(array $array = null): void
30 | {
31 | }
32 |
33 | /**
34 | * @param iterable<\Generated\Shared\Transfer\SalesPaymentTransfer> $x
35 | *
36 | * @return array<\Orm\Zed\Payment\Persistence\SpySalesPayment>
37 | */
38 | public function iterableTest(iterable $x = []): array
39 | {
40 | return $x;
41 | }
42 |
43 | /**
44 | * @param \ArrayObject $itemTransfers
45 | *
46 | * @return array
47 | */
48 | protected function getCountryIso2Codes(iterable $itemTransfers): array
49 | {
50 | return array_unique($itemTransfers);
51 | }
52 |
53 | /**
54 | * @param class-string<\Propel\Runtime\Map\TableMap> $tableMapClass The name of the table map to add
55 | *
56 | * @return void
57 | */
58 | public function registerTableMapClass(string $tableMapClass): void
59 | {
60 | }
61 |
62 | /**
63 | * @param string|null $value The value to convert.
64 | *
65 | * @return string|null
66 | */
67 | public function toPHP(mixed $value): mixed {
68 | return $value;
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/tests/_data/DocBlockParamArray/after.php:
--------------------------------------------------------------------------------
1 | $array
9 | * @param iterable $iterable
10 | * @return void
11 | */
12 | public function fixMe(array $array, iterable $iterable): void
13 | {
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/tests/_data/DocBlockParamArray/before.php:
--------------------------------------------------------------------------------
1 | |array $array
9 | * @param iterable|iterable $iterable
10 | * @return void
11 | */
12 | public function fixMe(array $array, iterable $iterable): void
13 | {
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/tests/_data/DocBlockReturnNull/after.php:
--------------------------------------------------------------------------------
1 | foo()) {
21 | return null;
22 | }
23 |
24 | return new static();
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/tests/_data/DocBlockReturnNull/before.php:
--------------------------------------------------------------------------------
1 | foo()) {
21 | return null;
22 | }
23 |
24 | return new static();
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/tests/_data/DocBlockReturnNullableType/after.php:
--------------------------------------------------------------------------------
1 | >|null
54 | */
55 | public function array(): ?array
56 | {
57 | return [];
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/tests/_data/DocBlockReturnNullableType/before.php:
--------------------------------------------------------------------------------
1 | >
54 | */
55 | public function array(): ?array
56 | {
57 | return [];
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/tests/_data/DocBlockReturnTag/after.php:
--------------------------------------------------------------------------------
1 | |string|null>
9 | */
10 | public function allGood(): array
11 | {
12 | return [
13 | ];
14 | }
15 |
16 | /**
17 | * @return array|string|null> Some comment with $someVar.
18 | */
19 | public function allGoodComment(): array
20 | {
21 | return [
22 | ];
23 | }
24 |
25 | /**
26 | * @return array|string $x
27 | */
28 | public function fixMe(): array
29 | {
30 | return [
31 | ];
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/tests/_data/DocBlockReturnTag/before.php:
--------------------------------------------------------------------------------
1 | |string|null>
9 | */
10 | public function allGood(): array
11 | {
12 | return [
13 | ];
14 | }
15 |
16 | /**
17 | * @return array|string|null> Some comment with $someVar.
18 | */
19 | public function allGoodComment(): array
20 | {
21 | return [
22 | ];
23 | }
24 |
25 | /**
26 | * @return array|string $x
27 | */
28 | public function fixMe(): array
29 | {
30 | return [
31 | ];
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/tests/_data/DocBlockReturnVoid/after.php:
--------------------------------------------------------------------------------
1 | anotherVoidOne();
33 | }
34 |
35 | /**
36 | * @return \Closure
37 | */
38 | public function foo(): Closure
39 | {
40 | /**
41 | * @return void
42 | */
43 | $bar = static function (): void {
44 | };
45 |
46 | return $bar;
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/tests/_data/DocBlockReturnVoid/before.php:
--------------------------------------------------------------------------------
1 | anotherVoidOne();
30 | }
31 |
32 | /**
33 | * @return \Closure
34 | */
35 | public function foo(): Closure
36 | {
37 | /**
38 | * @return void
39 | */
40 | $bar = static function (): void {
41 | };
42 |
43 | return $bar;
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/tests/_data/DocBlockThrows/after.php:
--------------------------------------------------------------------------------
1 | $value === true ? throw new DomainException() : null;
31 |
32 | $bar = static function (): void {
33 | throw new RuntimeException();
34 | };
35 |
36 | throw new LogicException();
37 | }
38 |
39 | /**
40 | * @throws \Foo\Bar\SomeException
41 | * @throws \Foo\Baz\Exception
42 | * @return void
43 | */
44 | public function complex(): void
45 | {
46 | if ($x) {
47 | throw new SomeException();
48 | } else {
49 | throw new SomeAliasedException();
50 | }
51 | }
52 |
53 | /**
54 | * @throws \BadMethodCallException
55 | * @return void
56 | */
57 | public function someException()
58 | {
59 | if ($this->something()) {
60 | throw new \BadMethodCallException();
61 | }
62 | }
63 |
64 | /**
65 | * @throws \League\OAuth2\Server\Exception\OAuthServerException
66 | * @return void
67 | */
68 | public function staticCall(): void
69 | {
70 | throw OAuthServerException::accessDenied('baz');
71 |
72 | new Parser();
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/tests/_data/DocBlockThrows/before.php:
--------------------------------------------------------------------------------
1 | $value === true ? throw new DomainException() : null;
29 |
30 | $bar = static function (): void {
31 | throw new RuntimeException();
32 | };
33 |
34 | throw new LogicException();
35 | }
36 |
37 | /**
38 | * @return void
39 | */
40 | public function complex(): void
41 | {
42 | if ($x) {
43 | throw new SomeException();
44 | } else {
45 | throw new SomeAliasedException();
46 | }
47 | }
48 |
49 | /**
50 | * @return void
51 | */
52 | public function someException()
53 | {
54 | if ($this->something()) {
55 | throw new \BadMethodCallException();
56 | }
57 | }
58 |
59 | /**
60 | * @return void
61 | */
62 | public function staticCall(): void
63 | {
64 | throw OAuthServerException::accessDenied('baz');
65 |
66 | new Parser();
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/tests/_data/DocBlockVar/after.php:
--------------------------------------------------------------------------------
1 |
16 | */
17 | protected $foo = [];
18 |
19 | /**
20 | * Stack of warnings.
21 | *
22 | * @var list
23 | */
24 | protected $warnings = [];
25 |
26 | /**
27 | * The left parts of the join condition
28 | *
29 | * @var list
30 | */
31 | protected $left = [];
32 | }
33 |
--------------------------------------------------------------------------------
/tests/_data/DocBlockVar/before.php:
--------------------------------------------------------------------------------
1 |
16 | */
17 | protected $foo = [];
18 |
19 | /**
20 | * Stack of warnings.
21 | *
22 | * @var list
23 | */
24 | protected $warnings = [];
25 |
26 | /**
27 | * The left parts of the join condition
28 | *
29 | * @var list
30 | */
31 | protected $left = [];
32 | }
33 |
--------------------------------------------------------------------------------
/tests/_data/EmptyEnclosingLine/after.php:
--------------------------------------------------------------------------------
1 | |\BarBaz|null $input X
46 | * @return (\Foo\Bar|BarBaz)[]
47 | */
48 | public function tooComplex($input = null)
49 | {
50 | return $input;
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/tests/_data/FullyQualifiedClassNameInDocBlock/before.php:
--------------------------------------------------------------------------------
1 | |BarBaz|null $input X
46 | * @return (\Foo\Bar|BarBaz)[]
47 | */
48 | public function tooComplex($input = null)
49 | {
50 | return $input;
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/tests/_data/InlineDocBlock/after.php:
--------------------------------------------------------------------------------
1 | > $_indices
14 | */
15 | $_indices = [];
16 |
17 | /*
18 | * This is not a docblock;
19 | * But a multiline comment
20 | */
21 | $foo = $_indices['x'];
22 |
23 | /** @var string|null $bar */
24 | $bar = $_indices['y'];
25 |
26 | /** @var string $foo */
27 | $foo = $_indices['z'];
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/tests/_data/InlineDocBlock/before.php:
--------------------------------------------------------------------------------
1 | > $_indices
14 | */
15 | $_indices = [];
16 |
17 | /*
18 | * This is not a docblock;
19 | * But a multiline comment
20 | */
21 | $foo = $_indices['x'];
22 |
23 | /** @var string|null $bar */
24 | $bar = $_indices['y'];
25 |
26 | /* @var string $foo */
27 | $foo = $_indices['z'];
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/tests/_data/MethodSignatureParametersLineBreakMethod/after.php:
--------------------------------------------------------------------------------
1 | null, // breaks code, needs to be refactored to class prop
28 | ];
29 |
30 | return new static($defaults);
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/tests/_data/SprykerPreferStaticOverSelf/before.php:
--------------------------------------------------------------------------------
1 | null, // breaks code, needs to be refactored to class prop
28 | ];
29 |
30 | return new static($defaults);
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/tests/_data/TypeHint/after.php:
--------------------------------------------------------------------------------
1 | |string|null>|string|null>|string|null
14 | */
15 | protected $arrays;
16 |
17 | /**
18 | * @return string[]|null
19 | */
20 | public function one(): ?array
21 | {
22 | return [];
23 | }
24 |
25 | /**
26 | * @param (string|int)[] $test
27 | *
28 | * @return string[]|int[]
29 | */
30 | public function second(array $test): array
31 | {
32 | return [];
33 | }
34 |
35 | /**
36 | * @param \ArrayObject|int[] $array
37 | *
38 | * @return \ArrayAccess|array $array
39 | */
40 | public function third(array $array): array
41 | {
42 | return [];
43 | }
44 |
45 | /**
46 | * @param \Collection|int[] $array
47 | *
48 | * @return \Collection|array $array
49 | */
50 | public function collection(array $array): array
51 | {
52 | return [];
53 | }
54 |
55 | /**
56 | * @param \Propel\Runtime\Collection\ObjectCollection|iterable<\Orm\Zed\Sales\Persistence\SpySalesShipment> $col
57 | *
58 | * @return \Propel\Runtime\Collection\Collection|\Propel\Runtime\Collection\ObjectCollection<\Propel\Runtime\ActiveRecord\ActiveRecordInterface>
59 | */
60 | protected function complex($col)
61 | {
62 | /** @var \Propel\Runtime\Collection\ObjectCollection<\Orm\Zed\SalesReturn\Persistence\SpySalesReturn> $salesReturnEntityCollection */
63 | $salesReturnEntityCollection = $this->runQuery();
64 |
65 | /** @var \ArrayObject<\Generated\Shared\Transfer\ShipmentGroupTransfer> $shipmentGroupCollection */
66 | $shipmentGroupCollection = $options[static::OPTION_SHIPMENT_GROUPS];
67 |
68 | return $salesReturnEntityCollection->getXyz();
69 | }
70 |
71 | /**
72 | * @param \Propel\Runtime\Collection|array|string|int $x
73 | *
74 | * @return \Propel\Runtime\Collection|\ArrayObject<\Foo>|array|string|int
75 | */
76 | protected function sortMultiple($x)
77 | {
78 | return $x;
79 | }
80 |
81 | /**
82 | * @return \Generator>
83 | */
84 | public function mergeGenerics(): Generator
85 | {
86 | yield $this->x();
87 | }
88 |
89 | /**
90 | * @param \Propel\Runtime\Collection\ObjectCollection<\Orm\Zed\ProductImage\Persistence\SpyProductImageSet> $productImageSetEntities
91 | *
92 | * @return array<\Generated\Shared\Transfer\ProductImageSetTransfer>
93 | */
94 | protected function complexGeneric(ObjectCollection $productImageSetEntities): array
95 | {
96 | return [];
97 | }
98 |
99 | /**
100 | * @param \ArrayObject $options
101 | * @return array
102 | */
103 | public function merge($options): array
104 | {
105 | return [];
106 | }
107 |
108 | /**
109 | * @return array|string|null>|string
110 | */
111 | public function complexUnion(): array
112 | {
113 | return [];
114 | }
115 | }
116 |
--------------------------------------------------------------------------------
/tests/_data/UseStatement/after.php:
--------------------------------------------------------------------------------
1 |