|
1 | 1 | parameters: |
2 | | - level: 5 |
| 2 | + level: 8 |
3 | 3 |
|
4 | 4 | paths: |
5 | 5 | - src |
| 6 | + |
| 7 | + excludePaths: |
| 8 | + - src/Bridges/FormsLatte/FormMacros.php |
| 9 | + - src/compatibility.php |
| 10 | + |
| 11 | + ignoreErrors: |
| 12 | + - # Latte nodes use new static() by design for extensibility |
| 13 | + identifier: new.static |
| 14 | + path: src/Bridges/FormsLatte/Nodes/* |
| 15 | + count: 6 |
| 16 | + |
| 17 | + - # Html properties accept broader types (bool for attribute removal, mixed for flexibility) |
| 18 | + identifier: assign.propertyType |
| 19 | + message: '#^Property Nette\\Utils\\Html::\$\w+ \([^)]+\) does not accept [^.]+\.$#' |
| 20 | + paths: |
| 21 | + - src/Forms/Controls/BaseControl.php |
| 22 | + - src/Forms/Controls/TextBase.php |
| 23 | + - src/Forms/Controls/TextInput.php |
| 24 | + - src/Forms/Form.php |
| 25 | + |
| 26 | + - # Form::$renderer and Form::$httpRequest are late-initialized via setters that |
| 27 | + # accept nullable arguments but the properties are non-nullable for ergonomics. |
| 28 | + identifier: assign.propertyType |
| 29 | + message: '#^Property Nette\\Forms\\Form::\$(renderer|httpRequest) \([^)]+\) does not accept [^.]+\.$#' |
| 30 | + path: src/Forms/Form.php |
| 31 | + count: 2 |
| 32 | + |
| 33 | + - # SubmitButton::getScopeForValidation() walks getParent() which is typed as |
| 34 | + # Container|Control; lookupPath() exists on Container at runtime. |
| 35 | + identifier: method.notFound |
| 36 | + message: '#^Call to an undefined method Nette\\Forms\\Container\|Nette\\Forms\\Control::lookupPath\(\)\.$#' |
| 37 | + path: src/Forms/Controls/SubmitButton.php |
| 38 | + count: 1 |
| 39 | + |
| 40 | + - # Nette\Forms\Control interface is intentionally minimal and missing common methods |
| 41 | + # (getControl, getLabel, getForm, getOption, setOption, getHtmlName, getName, getParent, |
| 42 | + # lookupPath, hasErrors, isRequired, isFilled, isDisabled, addError). In practice all |
| 43 | + # Control instances are BaseControl descendants which provide these methods. |
| 44 | + identifier: method.notFound |
| 45 | + message: '#^Call to an undefined method [\w\\&]*Nette\\Forms\\Control(&[\w\\]+)?::\w+\(\)\.$#' |
| 46 | + paths: |
| 47 | + - src/Bridges/FormsLatte/Runtime.php |
| 48 | + - src/Forms/Blueprint.php |
| 49 | + - src/Forms/Container.php |
| 50 | + - src/Forms/ControlGroup.php |
| 51 | + - src/Forms/Form.php |
| 52 | + - src/Forms/Helpers.php |
| 53 | + - src/Forms/Rendering/DefaultFormRenderer.php |
| 54 | + - src/Forms/Rules.php |
| 55 | + - src/Forms/Validator.php |
| 56 | + |
| 57 | + - # Anonymous BaseControl in Blueprint widens return type to match parent contract, |
| 58 | + # even though it returns only string literals in this case. |
| 59 | + identifier: return.unusedType |
| 60 | + path: src/Forms/Blueprint.php |
| 61 | + count: 2 |
| 62 | + |
| 63 | + - # parent::getControl()/getLabel() returns the wider public contract (Html|string|null), |
| 64 | + # but BaseControl implementation deterministically returns Html, so chaining is safe. |
| 65 | + identifier: method.nonObject |
| 66 | + message: '#^Cannot call method \w+\(\) on Nette\\Utils\\Html\|string(\|null)?\.$#' |
| 67 | + paths: |
| 68 | + - src/Forms/Controls/Checkbox.php |
| 69 | + - src/Forms/Controls/CheckboxList.php |
| 70 | + - src/Forms/Controls/ColorPicker.php |
| 71 | + - src/Forms/Controls/DateTimeControl.php |
| 72 | + - src/Forms/Controls/RadioList.php |
| 73 | + |
| 74 | + - # Same as above - property access on parent::getControl() result. |
| 75 | + identifier: property.nonObject |
| 76 | + message: '#^Cannot access property \$\w+ on Nette\\Utils\\Html\|string\.$#' |
| 77 | + paths: |
| 78 | + - src/Forms/Controls/CheckboxList.php |
| 79 | + - src/Forms/Controls/MultiSelectBox.php |
| 80 | + - src/Forms/Controls/RadioList.php |
| 81 | + - src/Forms/Controls/SelectBox.php |
| 82 | + - src/Forms/Controls/TextBase.php |
| 83 | + |
| 84 | + - # getControl()/getLabelPart() in children narrow the wider public contract back to Html. |
| 85 | + message: '#^Method Nette\\Forms\\Controls\\(TextBase::getControl|Checkbox::getLabelPart)\(\) should return Nette\\Utils\\Html but returns Nette\\Utils\\Html\|string(\|null)?\.$#' |
| 86 | + paths: |
| 87 | + - src/Forms/Controls/TextBase.php |
| 88 | + - src/Forms/Controls/Checkbox.php |
| 89 | + |
| 90 | + - # Generic callable - handlers and validators may have any signature. |
| 91 | + identifier: missingType.callable |
| 92 | + path: src/Forms/Form.php |
| 93 | + count: 1 |
| 94 | + |
| 95 | + - |
| 96 | + identifier: missingType.callable |
| 97 | + path: src/Forms/Rules.php |
| 98 | + count: 1 |
| 99 | + |
| 100 | + - # Parameters $caption / $key keep untyped for BC - adding native types would break |
| 101 | + # existing user overrides of these methods in custom form controls. |
| 102 | + identifier: missingType.parameter |
| 103 | + message: '#^Method Nette\\Forms\\Controls\\\w+::(getLabel|getControl|getControlPart|getLabelPart)\(\) has parameter \$(caption|key) with no type specified\.$#' |
| 104 | + paths: |
| 105 | + - src/Forms/Controls/Button.php |
| 106 | + - src/Forms/Controls/Checkbox.php |
| 107 | + - src/Forms/Controls/CheckboxList.php |
| 108 | + - src/Forms/Controls/HiddenField.php |
| 109 | + - src/Forms/Controls/RadioList.php |
| 110 | + - src/Forms/Controls/SubmitButton.php |
| 111 | + |
| 112 | + - # beforeRender() keeps untyped return for BC - user overrides may not declare void. |
| 113 | + identifier: missingType.return |
| 114 | + path: src/Forms/Form.php |
| 115 | + count: 1 |
| 116 | + |
| 117 | + - # Form::getForm() always returns $this, but parent contract is nullable conditional type. |
| 118 | + # Adding ?static or conditional PHPDoc would break BC for existing user overrides. |
| 119 | + identifier: method.childReturnType |
| 120 | + path: src/Forms/Form.php |
| 121 | + count: 1 |
| 122 | + |
| 123 | + - # $control may be undefined if $controls is empty, but in practice renderPairMulti() |
| 124 | + # is only called with non-empty arrays from renderControls(). |
| 125 | + identifier: variable.undefined |
| 126 | + path: src/Forms/Rendering/DefaultFormRenderer.php |
| 127 | + count: 1 |
| 128 | + |
| 129 | + - # Form controls intentionally narrow setValue() $value from mixed to specific types |
| 130 | + # for better type safety - the contravariance is by design. |
| 131 | + identifier: method.childParameterType |
| 132 | + message: '#^Parameter \#1 \$value \([^)]+\) of method Nette\\Forms\\Controls\\\w+::setValue\(\) should be contravariant with parameter \$value \(mixed\) of method Nette\\Forms\\(Control|Controls\\BaseControl)::setValue\(\)$#' |
| 133 | + |
| 134 | + - # Rules::getCallback() returns callable-array [class, method] without value type. |
| 135 | + message: '#^Method Nette\\Forms\\Rules::getCallback\(\) return type has no value type specified in iterable type array\.$#' |
| 136 | + path: src/Forms/Rules.php |
| 137 | + count: 1 |
| 138 | + |
| 139 | + - # DateTimeControl formatHtmlValue accepts broader types from rule args |
| 140 | + message: '#^Parameter \#1 \$value of method Nette\\Forms\\Controls\\DateTimeControl::formatHtmlValue\(\)#' |
| 141 | + path: src/Forms/Controls/DateTimeControl.php |
| 142 | + count: 1 |
| 143 | + |
| 144 | + - # Recursive internal calls pass ?string from Helpers::getSingleType() (reflection) |
| 145 | + # which may be a class-string OR a built-in type name - PHPStan cannot distinguish. |
| 146 | + # Refactoring to satisfy the template would require BC-breaking signature changes |
| 147 | + # in the public getValues()/getUntrustedValues() API. |
| 148 | + identifier: argument.templateType |
| 149 | + message: '#^Unable to resolve the template type T in call to method Nette\\Forms\\Container::(getValues|getUntrustedValues)\(\)$#' |
| 150 | + paths: |
| 151 | + - src/Forms/Container.php |
| 152 | + - src/Forms/Form.php |
| 153 | + |
| 154 | + - # Same root cause as argument.templateType above - ?string from reflection cannot |
| 155 | + # be narrowed to class-string<T> at static analysis time. |
| 156 | + message: '#^Parameter \#1 \$returnType of method Nette\\Forms\\Container::(getValues|getUntrustedValues)\(\) expects#' |
| 157 | + paths: |
| 158 | + - src/Forms/Container.php |
| 159 | + - src/Forms/Form.php |
| 160 | + |
| 161 | + - # Complex template type T cannot be fully tracked through getValues delegation |
| 162 | + message: '#^Method Nette\\Forms\\Container::getValues\(\) should return#' |
| 163 | + path: src/Forms/Container.php |
| 164 | + count: 1 |
| 165 | + |
| 166 | + - # getComponents() returns iterable; narrowing to Iterator not detected |
| 167 | + message: '#^Method Nette\\Forms\\Container::getControls\(\) should return#' |
| 168 | + path: src/Forms/Container.php |
| 169 | + count: 1 |
| 170 | + |
| 171 | + - |
| 172 | + message: '#^Using nullsafe property access on non\-nullable type Latte\\Compiler\\Nodes\\FragmentNode\. Use \-\> instead\.$#' |
| 173 | + identifier: nullsafe.neverNull |
| 174 | + count: 1 |
| 175 | + path: src/Bridges/FormsLatte/Nodes/FieldNNameNode.php |
| 176 | + |
| 177 | + - |
| 178 | + message: '#^Call to function is_string\(\) with string will always evaluate to true\.$#' |
| 179 | + identifier: function.alreadyNarrowedType |
| 180 | + count: 1 |
| 181 | + path: src/Forms/Controls/ColorPicker.php |
| 182 | + |
| 183 | + - |
| 184 | + message: '#^Strict comparison using \=\=\= between '''' and '''' will always evaluate to true\.$#' |
| 185 | + identifier: identical.alwaysTrue |
| 186 | + count: 1 |
| 187 | + path: src/Forms/Helpers.php |
0 commit comments