| phpstan-rules | by dg | added Nette\Schema\Expect::array() return type narrowing | | | |
| phpstan-rules | by dg | old Nette class names kept as aliases are reflected as the classes they stand for | | | |
| phpstan-rules | by dg | RethrowAbortExceptionRule: don't report a dedicated catch (AbortException) A catch that explicitly names AbortException (or a subtype) is a deliberate swallow, e.g. Presenter::run() ending the lifecycle. Only broad catches (\Throwable, \Exception) that swallow it incidentally are reported now. | | | |
| phpstan-rules | by dg | added RemoveFailingReturnTypeExtension extension to remove |false from native functions and methods | | | |
| phpstan-rules | by dg | added Registry::getMapper(), getAsset() and Mapper::getAsset() return type narrowing | | | |
| phpstan-rules | by dg | report invalid regex patterns in Nette\Utils\Strings calls New ValidRegularExpressionRule (the first custom rule in the project) checks constant patterns passed to Strings::match/matchAll/split/replace and reports compilation errors via RegexpException under identifier nette.strings.regexpPattern. Enabled by default. Adds TypeAssert::assertErrors() for testing rules (assertNoErrors now delegates to it). | | | |
| phpstan-rules | by dg | added arrow function void ignore for passing fn() => to Closure(): void parameters | | | |
| phpstan-rules | by dg | guard dynamic return type extensions against first-class callables Extensions called getArgs() unconditionally on the entry node. For a first-class callable such as json_encode(...) or $form[x]->m(...), PHPStan getArgs() asserts !isFirstClassCallable(), so any covered function/method/static method used in first-class-callable syntax crashed the whole analysis with an internal error. Bail out (return null) when the call node is a first-class callable, before touching getArgs(). Mirrors the standard guard in core PHPStan extensions. | | | |
| phpstan-rules | by dg | add StringsRegexHelper for the Nette\Utils\Strings regex extensions Shared helper that centralizes the translation of Nette's boolean parameters into a PREG flag mask, the RegexArrayShapeMatcher calls (matchShape/matchAllShape, instance) and stateless argument resolution (resolveFlag/findArg, static). The Strings regex extensions added in the following commits build on it. | | | |
| phpstan-rules | by dg | CI: DressCode checks with the dependencies installed Without vendor/ it knows nothing of the classes of the libraries, so a call of a deprecated method passes unnoticed. | | | |
| phpstan-rules | by dg | support for PHP 8.6 | | | |
| phpstan-rules | by dg | added Arrays::invoke() and invokeMethod() return type narrowing | | | |
| phpstan-rules | by dg | cs: only compiler-optimized functions in use-function imports | | | |
| phpstan-rules | by dg | TypeAssert: opcache is switched off before analysis A type test could see *ERROR* in place of a perfectly declared type, and whether it did depended on which other tests happened to run beside it. In nette/http, TypesTest failed under php-cgi on Windows only when run in parallel with a test that touched FileUpload: getImageSize() declared as ?array{int, int} came out as *ERROR*. Alone, with -j 1, under the CLI or with opcache disabled it passed. The cause lies in how PHPStan finds the source of a class. For a class outside the analysed paths, its AutoloadSourceLocator calls the autoloader under FileReadTrapStreamWrapper, a stream wrapper that intercepts the include, records the path and returns empty content, so the file is never executed. Opcache defeats the trap: a script it already has in the cache is served without the file being opened, the wrapper never sees the read and the file really runs. Its class gets defined natively in the middle of the analysis, and any trait or parent it needs is in turn loaded under the trap, which fails (here "Trait Nette\SmartObject not found"), so the reflection breaks and the type becomes *ERROR*. Why it looked random: the CLI usually has opcache off (opcache.enable_cli), while php-cgi has it on by the php.ini. On Windows the opcache memory is shared by the php-cgi processes that run at the same time, so a script is already cached in the test that analyses it exactly when a parallel test has loaded it first. Calling opcache_compile_file() on the file before assertTypes() reproduces it deterministically in a single process. Opcache can be switched off at runtime (only off, never on), and once off the scripts are compiled from the files again, so the trap works. It is done in createContainer(), the common entry of every assertion, before anything is analysed. | | | |
| phpstan-rules | by dg | uses dresscode | | | |
| phpstan-rules | by dg | suppress false argument.type on Callback::toReflection() Its @param callable is intentionally strict, but the method escalates the validity check to a ReflectionException at runtime, so a value that cannot be statically proven callable (e.g. a [class-string, method] tuple) is valid by design. New IgnoreErrorExtension matched narrowly to that single method. | | | |
| phpstan-rules | by dg | init | | | |
| phpstan-rules | by dg | derive exact array shape from regex in Strings::match/matchAll StringsReturnTypeExtension now uses phpstan's RegexArrayShapeMatcher to infer the precise shape (capture groups, named/optional groups, offsets) for constant patterns, translating Nette's boolean parameters into a PREG flag mask. Non-constant patterns and the lazy matchAll() Generator fall back to the previous generic shape; split() is unchanged. | | | |
| phpstan-rules | by dg | compatibility with PHPStan 2.2.6 RemoveFailingReturnTypeExtension: DynamicReturnTypeExtensionRegistry is injected directly, the provider layer was removed from PHPStan. Tests: PHPStan reverted decimal-int-string inference for regex groups back to numeric-string. StringsRegexHelper: matchAllShape() passes wasMatched=maybe; matchAll() may return an empty list, and PHPStan now infers non-empty-list for yes. | | | |
| phpstan-rules | by dg | fixed static analysis with PHPStan 2.3 | | | |
| phpstan-rules | by dg | added Container::getComponent() and $container['…'] return type narrowing Also resolves nested access - chained ($container['a']['b']) and Nette's dash notation ($container['a-b']) - via createComponent<Name>() factories. | | | |
| phpstan-rules | by dg | ExpectArrayReturnTypeExtension answers the plain array element instead of Type Since nette/schema 1.4 an Expect::array() without a shape is an ArrayType, not a plain Type, so the extension asks Expect::array() for the class the same way the Expect::type() one does; up to 1.3 the answer stays Type. | | | |
| phpstan-rules | by dg | added suppression for Form event-handler callback assignments | | | |
| phpstan-rules | by dg | added .phpt file extension | | | |
| phpstan-rules | by dg | RemoveFailingReturnTypeExtension: preg_* narrowing only for constant patterns | | | |
| phpstan-rules | by dg | narrow match subject string after Strings::match/matchAll New StringsMatchTypeSpecifyingExtension narrows the subject of a successful Strings::match()/matchAll() call inside a truthy context, e.g. `if (Strings::match($s, '#\d+#'))` makes $s a non-empty-string. Delegates to RegexArrayShapeMatcher::matchSubjectExpr(). | | | |
| phpstan-rules | by dg | added Html::getXxx(), setXxx(), addXxx() magic method resolution | | | |
| phpstan-rules | by dg | added AGENTS.md & DOCS | | | |
| phpstan-rules | by dg | RemoveFailingReturnTypeExtension: strip |false from glob() Claude-Session: https://claude.ai/code/session_01YAusXLYHRUMofgyF5LHxqN | | | |
| phpstan-rules | by dg | interface @property tag support (type resolution + property.notFound suppression) PHPStan core ignores @property/@property-read tags on interfaces: the allowsDynamicProperties() gate skips annotation-based properties there, so e.g. $asset->url on Nette\Assets\Asset reports property.notFound and a custom PropertiesClassReflectionExtension is never consulted. InterfacePropertyTagTypeExtension (ExpressionTypeResolverExtension) gives such reads the annotated type (narrowed expression types and native properties win), InterfacePropertyTagIgnoreExtension suppresses the false property.notFound. Writes are intentionally left unsupported. Claude-Session: https://claude.ai/code/session_01YAusXLYHRUMofgyF5LHxqN | | | |
| phpstan-rules | by dg | nette/database row type narrowing (table/related/ref/insert) Narrows return types based on a configurable table-to-entity-class mapping (nette.database.mapping.tables), which is not yet part of the nette/database distribution. Kept as the topmost commit so the whole feature can be excluded or rebased independently. Includes: - TableRowTypeResolver shared resolver - Explorer::table() -> Selection<EntityRow> - ActiveRow::related() -> GroupedSelection<EntityRow> - ActiveRow::ref() -> ?EntityRow - Selection::insert() -> mapped EntityRow | | | |
| phpstan-rules | by dg | cs | | | |