Tools

Repository Author Commit message Committed SHA  
 
phpstan-rules by dg added Nette\Schema\Expect::array() return type narrowing
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 support for PHP 8.6
phpstan-rules by dg added Arrays::invoke() and invokeMethod() return type narrowing
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 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 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 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 added Tester\Assert type narrowing for assertion methods (null, notNull, true, false, same, type, …)
phpstan-rules by dg RemoveFailingReturnTypeExtension: preserved |false for UTF-8 validation patterns like //u
phpstan-rules by dg readonly properties
phpstan-rules by dg added ExpectTypeReturnTypeExtension for Expect::type()

Expect::type() declares Type (Type|AnyOf since schema 2.0), while the element
it returns depends on the expression: 'int' is a NumberType with min() and
max(), 'int|string' an AnyOf. The extension resolves a constant expression by
asking Expect::type() itself, so it needs no knowledge of the expression
language and its answer follows whatever the installed nette/schema builds; a
non-constant expression, or one the installed version refuses, keeps the
declared type.

phpstan-rules by dg warn when catch swallows Nette\Application\AbortException

New RethrowAbortExceptionRule flags the common presenter bug where a broad
catch (\Throwable)/catch (\Exception) swallows an AbortException thrown by
redirect()/forward()/terminate(), silently breaking the redirect. It fires
only when the try block can actually throw AbortException (detected via
method getThrowType()) and the first matching catch does not rethrow.
Carving out a catch (AbortException) { throw; } before the broad catch
silences it. Enabled by default.

phpstan-rules by dg added boilerplate
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 cs

Last synchronization: 2026-09-26 00:03:04