Open
Description
Our team has noticed that closures (inline functions) are not being linted consistently. Here are two examples:
<?php
declare(strict_types=1);
// phpcs:disable SlevomatCodingStandard.ControlStructures.DisallowEmpty.DisallowedEmpty
namespace App\Concerns;
use App\Services\Amazon\DynamoDBService;
use BaseCondition;
use Illuminate\Database\Query\Builder;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\DB;
trait HasMappings
{
protected function buildMappingsOptions(Collection $attributes): array
{
return $attributes
->mapWithKeys(function ($group, $key) {
// ...
})
->values()
->toArray();
}
}
In this example it is only linting for the missing return type hint, but not the parameter type hint.
Interestingly, the following example breaks the linting for the return type hint as well:
protected function buildMappingsOptions(Collection $attributes): array
{
return $attributes
->groupBy('group')
->mapWithKeys(function ($group, $key) {
$choices = $group
->map(function ($item) {
return [
'value' => $item->map_id,
// 'label' => $item->name,
'label' => "{$item->group} → {$item->name}",
];
})
->toArray();
return [
$key => [
'label' => $key,
'choices' => $choices,
],
];
})
->values()
->toArray();
}
In this example we would expect the linter to lint on both the outer and all nested closures.
<?php
declare(strict_types=1);
use Illuminate\Database\Migrations\Migration;
use Illuminate\Support\Facades\Schema;
return new class extends Migration {
public function up(): void
{
Schema::dropIfExists('migrations');
Schema::create('migrations', function ($table) {
// ...
});
}
};
In this example it is linting the missing return type hint, but not the missing parameter type hint.
ruleset.xml:
<?xml version="1.0"?>
<ruleset name="Insight">
<description>Custom code standard for Insight.</description>
<config
name="installed_paths"
value="../../slevomat/coding-standard"
/>
<!-- Settings -->
<arg name="tab-width" value="4" />
<!-- Excluded File Types -->
<exclude-pattern>*/*.css</exclude-pattern>
<exclude-pattern>*/*.js</exclude-pattern>
<exclude-pattern>*/*.xml</exclude-pattern>
<exclude-pattern>*/cache/*</exclude-pattern>
<exclude-pattern>*/docker/*</exclude-pattern>
<exclude-pattern>*/public/*</exclude-pattern>
<exclude-pattern>*/reference/*</exclude-pattern>
<exclude-pattern>*/storage/debugbar/*</exclude-pattern>
<exclude-pattern>*/storage/framework/*</exclude-pattern>
<exclude-pattern>*/storage/logs/*</exclude-pattern>
<exclude-pattern>*/vendor/*</exclude-pattern>
<exclude-pattern>bootstrap/autoload.php</exclude-pattern>
<exclude-pattern>bootstrap/cache/*</exclude-pattern>
<rule ref="Generic.WhiteSpace.DisallowTabIndent" />
<rule ref="PSR1.Classes.ClassDeclaration" />
<rule ref="PSR1.Files.SideEffects" />
<rule ref="PSR1.Methods.CamelCapsMethodName" />
<rule ref="PSR2.Classes.ClassDeclaration">
<properties>
<property name="indent" value="4" />
</properties>
</rule>
<rule ref="PSR2.Classes.PropertyDeclaration" />
<rule ref="PSR2.ControlStructures.ElseIfDeclaration" />
<rule ref="PSR2.ControlStructures.SwitchDeclaration">
<properties>
<property name="indent" value="4" />
</properties>
</rule>
<rule ref="PSR2.Files.ClosingTag" />
<rule ref="PSR2.Files.EndFileNewline" />
<rule ref="PSR2.Methods.FunctionClosingBrace" />
<rule ref="PSR2.Methods.MethodDeclaration" />
<rule ref="PSR12.Classes.AnonClassDeclaration">
<properties>
<property name="indent" value="4" />
</properties>
</rule>
<rule ref="PSR12.Classes.ClosingBrace" />
<rule ref="PSR12.ControlStructures.BooleanOperatorPlacement">
<properties>
<property name="allowOnly" value="first" />
</properties>
</rule>
<rule ref="PSR12.ControlStructures.ControlStructureSpacing">
<properties>
<property name="indent" value="4" />
</properties>
</rule>
<rule ref="PSR12.Files.DeclareStatement" />
<rule ref="PSR12.Files.FileHeader" />
<rule ref="PSR12.Files.ImportStatement" />
<rule ref="PSR12.Files.OpenTag" />
<rule ref="PSR12.Functions.NullableTypeDeclaration" />
<rule ref="PSR12.Functions.ReturnTypeDeclaration" />
<rule ref="PSR12.Keywords.ShortFormTypeKeywords" />
<rule ref="PSR12.Namespaces.CompoundNamespaceDepth">
<properties>
<property name="maxDepth" value="1" />
</properties>
</rule>
<rule ref="PSR12.Operators.OperatorSpacing">
<properties>
<property name="ignoreNewlines" value="false" />
<property name="ignoreSpacingBeforeAssignments" value="false" />
</properties>
</rule>
<rule ref="PSR12.Properties.ConstantVisibility" />
<rule ref="PSR12.Traits.UseDeclaration" />
<rule ref="Generic.Formatting.SpaceAfterNot">
<properties>
<property name="ignoreNewlines" value="false" />
</properties>
</rule>
<rule ref="SlevomatCodingStandard.Arrays.ArrayAccess" />
<rule ref="SlevomatCodingStandard.Arrays.MultiLineArrayEndBracketPlacement" />
<rule ref="SlevomatCodingStandard.Arrays.SingleLineArrayWhitespace">
<properties>
<property name="spacesAroundBrackets" type="integer" value="0" />
<property name="enableEmptyArrayCheck" type="boolean" value="true" />
</properties>
</rule>
<rule ref="SlevomatCodingStandard.Arrays.TrailingArrayComma" />
<rule ref="SlevomatCodingStandard.Attributes.AttributeAndTargetSpacing">
<properties>
<property name="allowOnSameLine" type="boolean" value="false" />
<property name="linesCount" type="integer" value="0" />
</properties>
</rule>
<rule ref="SlevomatCodingStandard.Attributes.AttributesOrder">
<properties>
<property name="orderAlphabetically" type="boolean" value="true" />
</properties>
</rule>
<rule ref="SlevomatCodingStandard.Attributes.DisallowAttributesJoining" />
<rule ref="SlevomatCodingStandard.Attributes.DisallowMultipleAttributesPerLine" />
<rule ref="SlevomatCodingStandard.Attributes.RequireAttributeAfterDocComment" />
<rule ref="SlevomatCodingStandard.Classes.BackedEnumTypeSpacing">
<properties>
<property name="spacesCountBeforeColon" type="integer" value="0" />
<property name="spacesCountBeforeType" type="integer" value="1" />
</properties>
</rule>
<rule ref="SlevomatCodingStandard.Classes.ClassLength" />
<rule ref="SlevomatCodingStandard.Classes.ConstantSpacing">
<properties>
<property name="minLinesCountBeforeWithComment" type="integer" value="0" />
<property name="maxLinesCountBeforeWithComment" type="integer" value="0" />
<property name="minLinesCountBeforeWithoutComment" type="integer" value="0" />
<property name="maxLinesCountBeforeWithoutComment" type="integer" value="0" />
</properties>
</rule>
<rule ref="SlevomatCodingStandard.Classes.ClassConstantVisibility">
<properties>
<property name="fixable" type="boolean" value="true" />
</properties>
</rule>
<rule ref="SlevomatCodingStandard.Classes.ClassMemberSpacing">
<properties>
<property name="linesCountBetweenMembers" type="integer" value="1" />
</properties>
</rule>
<rule ref="SlevomatCodingStandard.Classes.DisallowMultiConstantDefinition" />
<rule ref="SlevomatCodingStandard.Classes.DisallowMultiPropertyDefinition" />
<rule ref="SlevomatCodingStandard.Classes.DisallowStringExpressionPropertyFetch" />
<rule ref="SlevomatCodingStandard.Classes.EmptyLinesAroundClassBraces">
<properties>
<property name="linesCountAfterOpeningBrace" type="integer" value="0" />
<property name="linesCountBeforeClosingBrace" type="integer" value="0" />
</properties>
</rule>
<rule ref="SlevomatCodingStandard.Classes.EnumCaseSpacing">
<properties>
<property name="minLinesCountBeforeWithComment" type="integer" value="0" />
<property name="maxLinesCountBeforeWithComment" type="integer" value="0" />
<property name="minLinesCountBeforeWithoutComment" type="integer" value="0" />
<property name="maxLinesCountBeforeWithoutComment" type="integer" value="0" />
</properties>
</rule>
<rule ref="SlevomatCodingStandard.Classes.MethodSpacing">
<properties>
<property name="minLinesCount" type="integer" value="1" />
<property name="maxLinesCount" type="integer" value="1" />
</properties>
</rule>
<rule ref="SlevomatCodingStandard.Classes.ModernClassNameReference" />
<rule ref="SlevomatCodingStandard.Classes.ParentCallSpacing">
<properties>
<property name="linesCountBefore" type="integer" value="1" />
<property name="linesCountBeforeFirst" type="integer" value="0" />
<property name="linesCountAfter" type="integer" value="1" />
<property name="linesCountAfterLast" type="integer" value="0" />
</properties>
</rule>
<rule ref="SlevomatCodingStandard.Classes.PropertyDeclaration">
<properties>
<property name="checkPromoted" type="boolean" value="true" />
<property name="enableMultipleSpacesBetweenModifiersCheck" type="boolean" value="true" />
</properties>
</rule>
<rule ref="SlevomatCodingStandard.Classes.PropertySpacing">
<properties>
<property name="minLinesCountBeforeWithComment" type="integer" value="0" />
<property name="maxLinesCountBeforeWithComment" type="integer" value="0" />
<property name="minLinesCountBeforeWithoutComment" type="integer" value="0" />
<property name="maxLinesCountBeforeWithoutComment" type="integer" value="0" />
</properties>
</rule>
<rule ref="SlevomatCodingStandard.Classes.RequireConstructorPropertyPromotion" />
<rule ref="SlevomatCodingStandard.Classes.RequireMultiLineMethodSignature">
<properties>
<property name="minLineLength" type="integer" value="100" />
</properties>
</rule>
<rule ref="SlevomatCodingStandard.Classes.RequireSelfReference" />
<rule ref="SlevomatCodingStandard.Classes.RequireSingleLineMethodSignature">
<properties>
<property name="maxLineLength" type="integer" value="100" />
</properties>
</rule>
<rule ref="SlevomatCodingStandard.Classes.SuperfluousAbstractClassNaming" />
<rule ref="SlevomatCodingStandard.Classes.SuperfluousInterfaceNaming" />
<rule ref="SlevomatCodingStandard.Classes.SuperfluousExceptionNaming" />
<rule ref="SlevomatCodingStandard.Classes.SuperfluousErrorNaming" />
<rule ref="SlevomatCodingStandard.Classes.SuperfluousTraitNaming" />
<rule ref="SlevomatCodingStandard.Classes.TraitUseDeclaration" />
<rule ref="SlevomatCodingStandard.Classes.TraitUseSpacing">
<properties>
<property name="linesCountBeforeFirstUse" type="integer" value="1" />
<property name="linesCountBeforeFirstUseWhenFirstInClass" type="integer" value="0" />
<property name="linesCountBetweenUses" type="integer" value="0" />
<property name="linesCountAfterLastUse" type="integer" value="1" />
<property name="linesCountAfterLastUseWhenLastInClass" type="integer" value="0" />
</properties>
</rule>
<rule ref="SlevomatCodingStandard.Classes.UselessLateStaticBinding" />
<rule ref="SlevomatCodingStandard.Commenting.EmptyComment" />
<rule ref="SlevomatCodingStandard.Commenting.InlineDocCommentDeclaration" />
<rule ref="SlevomatCodingStandard.Commenting.UselessFunctionDocComment" />
<rule ref="SlevomatCodingStandard.Commenting.UselessInheritDocComment" />
<rule ref="SlevomatCodingStandard.Complexity.Cognitive">
<properties>
<property name="maxComplexity" type="int" value="6" />
<property name="warningThreshold" type="int" value="6" />
<property name="errorThreshold" type="int" value="6" />
</properties>
</rule>
<rule ref="SlevomatCodingStandard.ControlStructures.AssignmentInCondition" />
<rule ref="SlevomatCodingStandard.ControlStructures.BlockControlStructureSpacing">
<properties>
<property name="linesCountBefore" type="integer" value="1" />
<property name="linesCountBeforeFirst" type="integer" value="0" />
<property name="linesCountAfter" type="integer" value="1" />
<property name="linesCountAfterLast" type="integer" value="0" />
</properties>
</rule>
<rule ref="SlevomatCodingStandard.ControlStructures.EarlyExit">
<properties>
<property name="ignoreStandaloneIfInScope" type="boolean" value="false" />
<property name="ignoreOneLineTrailingIf" type="boolean" value="false" />
<property name="ignoreTrailingIfWithOneInstruction" type="boolean" value="false" />
</properties>
</rule>
<rule ref="SlevomatCodingStandard.ControlStructures.DisallowContinueWithoutIntegerOperandInSwitch" />
<rule ref="SlevomatCodingStandard.ControlStructures.DisallowEmpty" />
<rule ref="SlevomatCodingStandard.ControlStructures.DisallowTrailingMultiLineTernaryOperator" />
<rule ref="SlevomatCodingStandard.ControlStructures.JumpStatementsSpacing">
<properties>
<property name="allowSingleLineYieldStacking" type="boolean" value="false" />
<property name="linesCountAfter" type="integer" value="1" />
<property name="linesCountAfterLast" type="integer" value="0" />
<property name="linesCountAfterWhenLastInCaseOrDefault" type="integer" value="0" />
<property name="linesCountAfterWhenLastInLastCaseOrDefault" type="integer" value="0" />
<property name="linesCountBefore" type="integer" value="1" />
<property name="linesCountBeforeFirst" type="integer" value="0" />
<property name="linesCountBeforeWhenFirstInCaseOrDefault" type="integer" value="0" />
<property name="jumpStatements" type="array">
<element value="goto" />
<element value="continue" />
<element value="return" />
<element value="throw" />
<element value="yield" />
<element value="yield_from" />
</property>
</properties>
</rule>
<rule ref="SlevomatCodingStandard.ControlStructures.RequireMultiLineCondition">
<properties>
<property name="minLineLength" type="integer" value="0" />
<property name="booleanOperatorOnPreviousLine" type="boolean" value="false" />
<property name="alwaysSplitAllConditionParts" type="boolean" value="true" />
</properties>
</rule>
<rule ref="SlevomatCodingStandard.ControlStructures.RequireMultiLineTernaryOperator" />
<rule ref="SlevomatCodingStandard.ControlStructures.RequireNullCoalesceEqualOperator" />
<rule ref="SlevomatCodingStandard.ControlStructures.RequireNullCoalesceOperator" />
<rule ref="SlevomatCodingStandard.ControlStructures.RequireNullSafeObjectOperator">
<properties>
<property name="enable" type="boolean" value="true" />
</properties>
</rule>
<rule ref="SlevomatCodingStandard.ControlStructures.RequireSingleLineCondition">
<properties>
<property name="maxLineLength" type="integer" value="1" />
<property name="alwaysForSimpleConditions" type="boolean" value="true" />
</properties>
</rule>
<rule ref="SlevomatCodingStandard.ControlStructures.RequireShortTernaryOperator" />
<rule ref="SlevomatCodingStandard.ControlStructures.RequireTernaryOperator" />
<rule ref="SlevomatCodingStandard.ControlStructures.DisallowYodaComparison" />
<rule ref="SlevomatCodingStandard.ControlStructures.UselessIfConditionWithReturn" />
<rule ref="SlevomatCodingStandard.ControlStructures.UselessTernaryOperator" />
<rule ref="SlevomatCodingStandard.Exceptions.DeadCatch" />
<rule ref="SlevomatCodingStandard.Exceptions.ReferenceThrowableOnly" />
<rule ref="SlevomatCodingStandard.Exceptions.RequireNonCapturingCatch" />
<rule ref="SlevomatCodingStandard.Files.FileLength">
<properties>
<property name="includeComments" type="boolean" value="false" />
<property name="includeWhitespace" type="boolean" value="false" />
<property name="maxLinesLength" type="integer" value="500" />
</properties>
<exclude-pattern>*/tests/*</exclude-pattern>
</rule>
<rule ref="SlevomatCodingStandard.Files.LineLength">
<properties>
<property name="lineLengthLimit" type="integer" value="100" />
<property name="ignoreImports" type="boolean" value="true" />
</properties>
</rule>
<rule ref="SlevomatCodingStandard.Files.TypeNameMatchesFileName">
<properties>
<property name="rootNamespaces" type="array">
<element key="app" value="App" />
<element key="modules" value="Modules" />
<element key="database/factories" value="Database\Factories" />
<element key="database/seeders" value="Database\Seeders" />
<element key="tests" value="Tests" />
</property>
</properties>
</rule>
<rule ref="SlevomatCodingStandard.Functions.DisallowEmptyFunction" />
<rule ref="SlevomatCodingStandard.Functions.FunctionLength">
<properties>
<property name="includeComments" type="boolean" value="false" />
<property name="includeWhitespace" type="boolean" value="false" />
<property name="maxLinesLength" type="integer" value="25" />
</properties>
</rule>
<rule ref="SlevomatCodingStandard.Functions.RequireMultiLineCall">
<properties>
<property name="minLineLength" type="integer" value="101" />
</properties>
</rule>
<rule ref="SlevomatCodingStandard.Functions.RequireSingleLineCall">
<properties>
<property name="ignoreWithComplexParameter" type="boolean" value="true" />
<property name="maxLineLength" type="integer" value="100" />
</properties>
</rule>
<rule ref="SlevomatCodingStandard.Functions.RequireTrailingCommaInCall" />
<rule ref="SlevomatCodingStandard.Functions.RequireTrailingCommaInClosureUse" />
<rule ref="SlevomatCodingStandard.Functions.RequireTrailingCommaInDeclaration" />
<rule ref="SlevomatCodingStandard.Functions.UnusedInheritedVariablePassedToClosure" />
<rule ref="SlevomatCodingStandard.Functions.UnusedParameter" />
<rule ref="SlevomatCodingStandard.Functions.UselessParameterDefaultValue" />
<rule ref="SlevomatCodingStandard.Namespaces.AlphabeticallySortedUses" />
<rule ref="SlevomatCodingStandard.Namespaces.DisallowGroupUse" />
<rule ref="SlevomatCodingStandard.Namespaces.MultipleUsesPerLine" />
<rule ref="SlevomatCodingStandard.Namespaces.NamespaceDeclaration" />
<rule ref="SlevomatCodingStandard.Namespaces.NamespaceSpacing">
<properties>
<property name="linesCountBeforeNamespace" type="integer" value="1" />
<property name="linesCountAfterNamespace" type="integer" value="1" />
</properties>
</rule>
<rule ref="SlevomatCodingStandard.Namespaces.RequireOneNamespaceInFile" />
<rule ref="SlevomatCodingStandard.Namespaces.UseFromSameNamespace" />
<rule ref="SlevomatCodingStandard.Namespaces.UseDoesNotStartWithBackslash" />
<rule ref="SlevomatCodingStandard.Namespaces.UseSpacing">
<properties>
<property name="linesCountBeforeFirstUse" type="integer" value="1" />
<property name="linesCountBetweenUseTypes" type="integer" value="1" />
<property name="linesCountAfterLastUse" type="integer" value="1" />
</properties>
</rule>
<rule ref="SlevomatCodingStandard.Namespaces.UselessAlias" />
<rule ref="SlevomatCodingStandard.Namespaces.UnusedUses" />
<rule ref="SlevomatCodingStandard.Numbers.RequireNumericLiteralSeparator">
<properties>
<property name="minDigitsBeforeDecimalPoint" type="integer" value="4" />
<property name="minDigitsAfterDecimalPoint" type="integer" value="4" />
<property name="ignoreOctalNumbers" type="boolean" value="true" />
</properties>
</rule>
<rule ref="SlevomatCodingStandard.Operators.DisallowEqualOperators" />
<rule ref="SlevomatCodingStandard.Operators.RequireCombinedAssignmentOperator" />
<rule ref="SlevomatCodingStandard.Operators.RequireOnlyStandaloneIncrementAndDecrementOperators" />
<rule ref="SlevomatCodingStandard.Operators.SpreadOperatorSpacing">
<properties>
<property name="spacesCountAfterOperator" type="integer" value="0" />
</properties>
</rule>
<rule ref="SlevomatCodingStandard.PHP.DisallowDirectMagicInvokeCall" />
<rule ref="SlevomatCodingStandard.PHP.OptimizedFunctionsWithoutUnpacking" />
<rule ref="SlevomatCodingStandard.PHP.ReferenceSpacing">
<properties>
<property name="spacesCountAfterReference" type="integer" value="0" />
</properties>
</rule>
<rule ref="SlevomatCodingStandard.PHP.ShortList" />
<rule ref="SlevomatCodingStandard.PHP.TypeCast" />
<rule ref="SlevomatCodingStandard.PHP.UselessParentheses">
<properties>
<property name="ignoreComplexTernaryConditions" type="boolean" value="false" />
</properties>
</rule>
<rule ref="SlevomatCodingStandard.PHP.UselessSemicolon" />
<rule ref="SlevomatCodingStandard.Strings.DisallowVariableParsing">
<properties>
<property name="disallowDollarCurlySyntax" type="boolean" value="true" />
<property name="disallowCurlyDollarSyntax" type="boolean" value="false" />
<property name="disallowSimpleSyntax" type="boolean" value="true" />
</properties>
</rule>
<rule ref="SlevomatCodingStandard.TypeHints.DeclareStrictTypes">
<properties>
<property name="declareOnFirstLine" type="boolean" value="false" />
<property name="linesCountAfterDeclare" type="integer" value="1" />
<property name="spacesCountAroundEqualsSign" type="integer" value="0" />
</properties>
</rule>
<rule ref="SlevomatCodingStandard.TypeHints.NullableTypeForNullDefaultValue" />
<rule ref="SlevomatCodingStandard.TypeHints.ParameterTypeHint">
<exclude name="SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingTraversableTypeHintSpecification" />
</rule>
<rule ref="SlevomatCodingStandard.TypeHints.ParameterTypeHintSpacing" />
<rule ref="SlevomatCodingStandard.TypeHints.PropertyTypeHint">
<exclude name="SlevomatCodingStandard.TypeHints.PropertyTypeHint.MissingTraversableTypeHintSpecification" />
</rule>
<rule ref="SlevomatCodingStandard.TypeHints.ReturnTypeHint">
<exclude name="SlevomatCodingStandard.TypeHints.ReturnTypeHint.MissingTraversableTypeHintSpecification" />
</rule>
<rule ref="SlevomatCodingStandard.TypeHints.ReturnTypeHintSpacing">
<properties>
<property name="spacesCountBeforeColon" type="int" value="0" />
</properties>
</rule>
<rule ref="SlevomatCodingStandard.TypeHints.DNFTypeHintFormat">
<properties>
<property name="enable" type="boolean" value="true" />
<property name="withSpacesAroundOperators" type="string" value="no" />
<property name="withSpacesInsideParentheses" type="string" value="no" />
<property name="nullPosition" type="string" value="last" />
</properties>
</rule>
<rule ref="SlevomatCodingStandard.TypeHints.UselessConstantTypeHint" />
<rule ref="SlevomatCodingStandard.Variables.DisallowSuperGlobalVariable" />
<rule ref="SlevomatCodingStandard.Variables.DisallowVariableVariable" />
<rule ref="SlevomatCodingStandard.Variables.DuplicateAssignmentToVariable" />
<rule ref="SlevomatCodingStandard.Variables.UnusedVariable">
<properties>
<property name="ignoreUnusedValuesWhenOnlyKeysAreUsedInForeach" type="boolean" value="false" />
</properties>
</rule>
<rule ref="SlevomatCodingStandard.Variables.UselessVariable" />
<rule ref="SlevomatCodingStandard.Whitespaces.DuplicateSpaces">
<properties>
<property name="ignoreSpacesBeforeAssignment" type="boolean" value="false" />
<property name="ignoreSpacesInAnnotation" type="boolean" value="false" />
<property name="ignoreSpacesInComment" type="boolean" value="false" />
<property name="ignoreSpacesInParameters" type="boolean" value="false" />
<property name="ignoreSpacesInMatch" type="boolean" value="false" />
</properties>
</rule>
</ruleset>
It appears to us that this could be a tokenization issue with the linters. Any thoughts? Thank you for your help!
Metadata
Metadata
Assignees
Labels
No labels