[Feature] support PHP 8.5 first-class callable as default value for parameters and properties#569
Merged
Conversation
…eters and properties Proxy generation now preserves FCC default expressions (e.g. `function foo($cb = strlen(...))`) via raw AST nodes instead of calling getDefaultValue(), which crashes or returns null in parser-reflection for Closure defaults. - ValueGenerator: add fromExprNode() factory for pre-built AST Expr nodes - PropertyGenerator: add setDefaultExpressionNode() for Expr-based defaults - ParameterGenerator: use getNode()->default when parser-reflection available - AbstractInterceptedPropertyGenerator: use getNode()->default for property defaults Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Member
Author
|
Depends on goaop/parser-reflection#193 |
Contributor
There was a problem hiding this comment.
Pull request overview
This PR updates the proxy-generation pipeline to preserve PHP 8.5+ first-class callable (FCC) default expressions for parameters and (promoted/intercepted) properties by carrying raw PhpParser AST Expr nodes through generation, instead of relying on Reflection*::getDefaultValue().
Changes:
- Add
ValueGenerator::fromExprNode()to support defaults represented as pre-built AST expressions. - Extend
PropertyGeneratorwithsetDefaultExpressionNode()and emit expression defaults directly when present. - Update
ParameterGenerator::fromReflection()andAbstractInterceptedPropertyGenerator::createBasePropertyGenerator()to prefergetNode()->default(parser-reflection) and throw a clear exception when aClosuredefault can’t be represented without AST access. - Document the feature in
CHANGELOG.md.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| src/Proxy/Part/AbstractInterceptedPropertyGenerator.php | Switch intercepted property default handling to prefer AST defaults when available. |
| src/Proxy/Generator/ValueGenerator.php | Add an AST-node-backed construction path for defaults that can’t be represented as scalars. |
| src/Proxy/Generator/PropertyGenerator.php | Allow property defaults to be set via a raw Expr node and emitted verbatim. |
| src/Proxy/Generator/ParameterGenerator.php | Prefer parameter AST defaults when available; add explicit failure for Closure defaults without AST access. |
| CHANGELOG.md | Add changelog entry documenting PHP 8.5+ FCC default value support. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Remove unused Closure/LogicException imports from both source files - Add ValueGeneratorTest::testFromExprNode for fromExprNode() factory - Add PropertyGeneratorTest::testSetDefaultExpressionNode for Expr defaults - Add ParameterGeneratorTest tests for AST-first default path and FCC defaults - Add PHP 8.5-gated FCC stub file for parser-reflection FCC parameter test Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
function foo($cb = strlen(...))) via raw AST nodesValueGenerator— addedfromExprNode()factory for pre-built ASTExprnodes that can't be represented as PHP scalarsPropertyGenerator— addedsetDefaultExpressionNode()forExpr-based property defaultsParameterGenerator::fromReflection()— usesgetNode()->defaultdirectly when parser-reflection is available, avoiding parser-reflection bugs wheregetDefaultValue()crashes (uninitialized typed property) or returnsnullfor Closure defaultsAbstractInterceptedPropertyGenerator::createBasePropertyGenerator()— same AST-first approach for intercepted propertiesWhy AST-first?
When parser-reflection is loaded, the raw AST default node is the authoritative source — it works uniformly for scalars, arrays, and FCC expressions. Calling
getDefaultValue()can crash parser-reflection (ReflectionParameter::$defaultValueis uninitialized for FCC) or silently returnnull(ReflectionProperty::$defaultValuedefaults tonull). By readinggetNode()->defaultdirectly, we bypass these issues entirely.Test plan
method_exists($param, 'getNode')(parser-reflection only)🤖 Generated with Claude Code