Skip to content

Feature/claude phpstan level10 php85#156

Merged
lisachenko merged 15 commits intomasterfrom
feature/claude-phpstan-level10-php85
Mar 30, 2026
Merged

Feature/claude phpstan level10 php85#156
lisachenko merged 15 commits intomasterfrom
feature/claude-phpstan-level10-php85

Conversation

@lisachenko
Copy link
Copy Markdown
Member

@lisachenko lisachenko commented Mar 28, 2026

This PR appears to modernize the library for stricter static analysis (PHPStan level 10) and newer PHP versions by tightening types, refining AST handling, and adding CI workflows/config for PHPStan.

Changes:

  • Add PHPStan configuration/workflow and bump dev dependencies (PHPStan, Rector).
  • Refine reflection/AST resolver typing and safety checks (attributes, types, node evaluation, line/file attributes).
  • Update CI PHP matrix and introduce PHP 8.4/8.4-hook-related adjustments (e.g., re-declared hooked readonly properties, more final classes).

lisachenko and others added 10 commits March 28, 2026 14:55
- Fix type mismatches in NodeExpressionResolver, TypeExpressionResolver,
  ReflectionClassLikeTrait, and ReflectionFunctionLikeTrait
- Remove unused constructor parameter from TypeExpressionResolver
- Fix ClassLike property access with proper instanceof narrowing in ReflectionClass
- Fix array key types and dead code in ReflectionClassLikeTrait
- Add ignoreErrors for unset.possiblyHookedProperty in final classes
  ReflectionFunction and ReflectionMethod (false positive: final classes
  cannot have subclasses with hooks)
- Replace array_reduce with foreach to fix callable type inference

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add missing PHPDoc type annotations for generic types and iterable value
types across all source files:
- Add @extends ReflectionClass<object> and ReflectionAttribute<object>
- Type all array<K, V> properties and return types
- Add ReflectionClass<object> generics to method return types

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Fix actual type errors surfaced at level 7:
- Fix PathResolver::realpath() return type to reflect recursive return
- Add instanceof guards before accessing Arg::$value and Const_::$value
- Fix ReflectionAttribute::getTypeNode() union type check
- Add false-check around fetchReflectionClass() calls in NodeExpressionResolver
- Fix constants property key type (int|string instead of string)
- Add @return class-string and non-empty-string overrides for getName/getShortName
- Fix getNamespaceName() method.notFound by guarding against ReflectionAttribute

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Fix null-safety and type-safety issues:
- Add null guards for ReflectionEngine::$locator before use
- Fix NodeTraverser::traverse() call with null-safe ?? []
- Add null checks before TypeExpressionResolver::process() calls
- Add null check for Identifier::toString() in findClassLikeNodeByClassName
- Fix offsetAccess.notFound in PathResolver by guarding string|null
- Add null guards around method_exists() calls in NodeExpressionResolver
- Fix $constOrEnumCaseNode null assignment in ReflectionClassConstant

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Fix mixed-type propagation from PhpParser Node::getAttribute() calls:
- Use hasAttribute() + explicit casts for getStartLine/getEndLine/getFileName
- Add instanceof Name guards before calling toString() on getAttribute() results
- Fix array key types by guarding with is_string()/is_int() checks
- Fix StaticVariablesCollector context type to match NodeExpressionResolver
- Fix sprintf with mixed value in ReflectionClassConstant
- Fix TypeExpressionResolver return types with explicit typed returns

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Fix remaining mixed-type and type-safety issues at level 10:
- Add abstract getNodeForAttributes() to AttributeResolverTrait for typed node access
- Fix CallableLocator return type with explicit string|false narrowing
- Fix ReflectionClassConstant::gettype() usage with proper array key narrowing
- Fix NodeExpressionResolver getAttribute() mixed results with type guards
- Fix ReflectionFileNamespace getAttribute() calls with proper int|false returns
- Fix ReflectionUnionType array_search with proper array type
- Filter Stringable objects in ReflectionClassLikeTrait::__toString() buildString

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Native PHP reflection resolves 'self' to the declaring class FQCN and
'parent' to the parent class FQCN in type hints. The parser-based
TypeExpressionResolver was returning the literals 'self'/'parent'.

- Add optional $selfClassName/$parentClassName to TypeExpressionResolver
- Add getDeclaringClassNameForTypes()/getParentClassNameForTypes() hook
  methods to ReflectionFunctionLikeTrait (default null for functions)
- Override both hooks in ReflectionMethod with the declaring class names
- Pass declaring class context when constructing TypeExpressionResolver
  in ReflectionParameter, ReflectionProperty, ReflectionClassConstant
- Keep 'static' unresolved (preserved as-is by native PHP reflection)

Fixes all 4 previously failing PHPUnit tests.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR appears to modernize the library for stricter static analysis (PHPStan level 10) and newer PHP versions by tightening types, refining AST handling, and adding CI workflows/config for PHPStan.

Changes:

  • Add PHPStan configuration/workflow and bump dev dependencies (PHPStan, Rector).
  • Refine reflection/AST resolver typing and safety checks (attributes, types, node evaluation, line/file attributes).
  • Update CI PHP matrix and introduce PHP 8.4/8.4-hook-related adjustments (e.g., re-declared hooked readonly properties, more final classes).

Reviewed changes

Copilot reviewed 26 out of 26 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
src/Traits/ReflectionFunctionLikeTrait.php Adds type-resolution hooks for self/parent and refactors some attribute/line handling.
src/Traits/ReflectionClassLikeTrait.php Tightens types, refactors collection logic, and changes class name handling (now includes autoload/alias behavior).
src/Traits/AttributeResolverTrait.php Refactors attribute-node selection and adds attribute-name “resolution” logic.
src/Resolver/TypeExpressionResolver.php Changes constructor contract and alters name resolution behavior for self/parent.
src/Resolver/NodeExpressionResolver.php Adds many type guards and refines constant/expression resolution behavior.
src/ReflectionUnionType.php Adjusts internal ordering logic in __toString().
src/ReflectionProperty.php Makes class final, updates type resolution, adds attribute-node accessor, and changes setValue() behavior.
src/ReflectionParameter.php Makes class final, updates constructor/type resolution, and adds attribute-node accessor.
src/ReflectionMethod.php Makes class final, adds enum-magic-method handling and attribute-node accessor, refactors node access.
src/ReflectionFunction.php Makes class final, adds attribute-node accessor, refactors __toString() parameter formatting.
src/ReflectionFileNamespace.php Adds stricter typing/guards around node attributes and constant parsing.
src/ReflectionFile.php Makes path resolution more defensive and tightens strict-mode parsing.
src/ReflectionEngine.php Adds initialization guard for locator and hardens file parsing/IO behavior.
src/ReflectionClassConstant.php Makes class final, tightens type resolution, adds attribute-node accessor, and hardens constructor assumptions.
src/ReflectionClass.php Makes class final, tightens class name handling, refactors interface/trait collection, adds attribute-node accessor.
src/ReflectionAttribute.php Tightens attribute name typing and hardens attribute node discovery.
src/NodeVisitor/StaticVariablesCollector.php Adds stricter typing for context and safer variable-name resolution.
src/NodeVisitor/RootNamespaceNormalizer.php Filters top-level nodes to valid statements before wrapping in a namespace node.
src/Locator/ComposerLocator.php Hardens path resolution return handling.
src/Locator/CallableLocator.php Hardens callable locator return handling.
src/Instrument/PathResolver.php Adds generics-ish PHPDoc but introduces riskier string indexing in relative-path detection.
phpstan.neon Adds PHPStan level 10 config and ignore rules.
composer.json Adds PHPStan and upgrades Rector dependency.
CLAUDE.md Adds repository guidance/architecture notes.
.github/workflows/phpunit.yml Changes PHP version matrix (includes PHP 8.5).
.github/workflows/phpstan.yml Adds a GitHub Actions workflow to run PHPStan.

lisachenko and others added 4 commits March 28, 2026 22:38
- Remove class_alias() from resolveAsClassString() and resolveAttributeClassName()
  (global side-effect; class names from AST are semantically class-strings by
  construction). Add ignoreErrors entries for these two known PHPStan limitations.
- Convert silent continue statements to explicit ReflectionException throws in
  NodeExpressionResolver (variadic placeholders, non-scalar named arg keys,
  non-scalar array keys) and ReflectionFileNamespace (define() with unsupported args).
- Fix PathResolver::realpath() unsafe $path[1] indexing — use regex-based Windows
  drive letter detection (matches PR suggestion).
- Fix ReflectionProperty::setValue() to check isStatic() before validating object arg,
  consistent with native ReflectionProperty behavior.
- Remove always-true PHP_VERSION_ID >= 80400 guards in ReflectionProperty::getModifiers()
  since composer.json now requires PHP >= 8.4.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
PHP 8.5 changed ReflectionNamedType::getName() to return the actual FQCN
for 'self' and 'parent' type hints, whereas PHP 8.4 and earlier return
the keywords as-is. Gate the resolution behind PHP_VERSION_ID >= 80500
so the library mirrors native reflection behavior on all supported versions.

Fixes CI failures on PHP 8.4 builds.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 33 out of 33 changed files in this pull request and generated 4 comments.

Comments suppressed due to low confidence (1)

CLAUDE.md:65

  • CLAUDE.md’s CI section still says phpunit.yml runs on PHP 8.2/8.3/8.4, but the workflow matrix now only includes 8.4 and 8.5. Please update this CI version list to match the workflow so the doc remains accurate.
### CI

GitHub Actions (`.github/workflows/phpunit.yml`) runs PHPUnit on PHP 8.2, 8.3, 8.4 with both lowest and highest dependency versions.

setValue(\$value) with one argument is the canonical PHP 8.4+ way to set
a static property value. The previous implementation silently forwarded
null as the value because \$value defaulted to null.

Also update CLAUDE.md to reflect the actual PHP >=8.4 requirement.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@lisachenko lisachenko merged commit dfe1c16 into master Mar 30, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Development

Successfully merging this pull request may close these issues.

2 participants