Skip to content

Commit 113afc2

Browse files
committed
Context aware fqsen resolving on parameters
1 parent d5aea24 commit 113afc2

File tree

4 files changed

+62
-20
lines changed

4 files changed

+62
-20
lines changed

src/phpDocumentor/Reflection/Php/Expression/ExpressionPrinter.php

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,10 @@
1414
namespace phpDocumentor\Reflection\Php\Expression;
1515

1616
use phpDocumentor\Reflection\Fqsen;
17+
use phpDocumentor\Reflection\FqsenResolver;
1718
use phpDocumentor\Reflection\Php\Expression;
1819
use phpDocumentor\Reflection\Type;
20+
use phpDocumentor\Reflection\Types\Context;
1921
use PhpParser\Node\Expr;
2022
use PhpParser\Node\Name;
2123
use PhpParser\PrettyPrinter\Standard;
@@ -24,6 +26,16 @@ final class ExpressionPrinter extends Standard
2426
{
2527
/** @var array<string, Fqsen|Type> */
2628
private array $parts = [];
29+
private Context|null $context = null;
30+
private FqsenResolver $fqsenResolver;
31+
32+
/** {@inheritDoc} */
33+
public function __construct(array $options = [])
34+
{
35+
parent::__construct($options);
36+
37+
$this->fqsenResolver = new FqsenResolver();
38+
}
2739

2840
protected function resetState(): void
2941
{
@@ -32,11 +44,18 @@ protected function resetState(): void
3244
$this->parts = [];
3345
}
3446

47+
public function prettyPrintExpr(Expr $node, Context|null $context = null): string
48+
{
49+
$this->context = $context;
50+
51+
return parent::prettyPrintExpr($node);
52+
}
53+
3554
protected function pName(Name $node): string
3655
{
37-
$renderedName = parent::pName($node);
38-
$placeholder = Expression::generatePlaceholder($renderedName);
39-
$this->parts[$placeholder] = new Fqsen('\\' . $renderedName);
56+
$renderedName = $this->fqsenResolver->resolve(parent::pName($node), $this->context);
57+
$placeholder = Expression::generatePlaceholder((string) $renderedName);
58+
$this->parts[$placeholder] = $renderedName;
4059

4160
return $placeholder;
4261
}
@@ -56,7 +75,7 @@ protected function pExpr_ClassConstFetch(Expr\ClassConstFetch $node): string
5675
{
5776
$renderedName = parent::pObjectProperty($node->name);
5877
$className = $node->class instanceof Name ? parent::pName($node->class) : $this->p($node->class);
59-
$placeholder = Expression::generatePlaceholder($renderedName);
78+
$placeholder = Expression::generatePlaceholder((string) $renderedName);
6079
$this->parts[$placeholder] = new Fqsen(
6180
'\\' . $className . '::' . $renderedName,
6281
);

src/phpDocumentor/Reflection/Php/Factory/PropertyBuilder.php

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
use phpDocumentor\Reflection\Php\PropertyHook;
1717
use phpDocumentor\Reflection\Php\StrategyContainer;
1818
use phpDocumentor\Reflection\Php\Visibility;
19+
use phpDocumentor\Reflection\Types\Context;
1920
use PhpParser\Comment\Doc;
2021
use PhpParser\Modifiers;
2122
use PhpParser\Node;
@@ -163,7 +164,7 @@ public function build(ContextStack $context): PropertyElement
163164
$this->fqsen,
164165
$this->visibility,
165166
$this->docblock !== null ? $this->docBlockFactory->create($this->docblock->getText(), $context->getTypeContext()) : null,
166-
$this->determineDefault(),
167+
$this->determineDefault($context->getTypeContext()),
167168
$this->static,
168169
$this->startLocation,
169170
$this->endLocation,
@@ -346,9 +347,14 @@ private function buildHookVisibility(string $hookName, Visibility $propertyVisib
346347
};
347348
}
348349

349-
private function determineDefault(): Expression|null
350+
private function determineDefault(Context|null $context): Expression|null
350351
{
351-
$expression = $this->default !== null ? $this->valueConverter->prettyPrintExpr($this->default) : null;
352+
if ($this->valueConverter instanceof ExpressionPrinter) {
353+
$expression = $this->default !== null ? $this->valueConverter->prettyPrintExpr($this->default, $context) : null;
354+
} else {
355+
$expression = $this->default !== null ? $this->valueConverter->prettyPrintExpr($this->default) : null;
356+
}
357+
352358
if ($expression === null) {
353359
return null;
354360
}

src/phpDocumentor/Reflection/Php/Factory/Reducer/Parameter.php

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
use phpDocumentor\Reflection\Php\Method;
1515
use phpDocumentor\Reflection\Php\PropertyHook;
1616
use phpDocumentor\Reflection\Php\StrategyContainer;
17+
use phpDocumentor\Reflection\Types\Context;
1718
use PhpParser\Node\Expr\Variable;
1819
use PhpParser\Node\FunctionLike;
1920
use PhpParser\Node\Param;
@@ -50,7 +51,7 @@ public function reduce(
5051
new ArgumentDescriptor(
5152
is_string($param->var->name) ? $param->var->name : $this->valueConverter->prettyPrintExpr($param->var->name),
5253
(new Type())->fromPhpParser($param->type),
53-
$this->determineDefault($param),
54+
$this->determineDefault($param, $context->getTypeContext()),
5455
$param->byRef,
5556
$param->variadic,
5657
),
@@ -60,9 +61,14 @@ public function reduce(
6061
return $carry;
6162
}
6263

63-
private function determineDefault(Param $value): Expression|null
64+
private function determineDefault(Param $value, Context|null $context): Expression|null
6465
{
65-
$expression = $value->default !== null ? $this->valueConverter->prettyPrintExpr($value->default) : null;
66+
if ($this->valueConverter instanceof ExpressionPrinter) {
67+
$expression = $value->default !== null ? $this->valueConverter->prettyPrintExpr($value->default, $context) : null;
68+
} else {
69+
$expression = $value->default !== null ? $this->valueConverter->prettyPrintExpr($value->default) : null;
70+
}
71+
6672
if ($expression === null) {
6773
return null;
6874
}

tests/integration/PHP8/ConstructorPromotionTest.php

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -52,16 +52,27 @@ public function testArgumentsAreReadCorrectly() : void
5252

5353
$constructor = $this->expectedConstructorMethod();
5454
$constructor->addArgument(new Argument('name', new String_(), "'default name'"));
55-
$constructor->addArgument(new Argument('email', new Object_(new Fqsen('\\PHP8\\Email'))));
55+
$constructor->addArgument(
56+
new Argument(
57+
'email',
58+
new Object_(new Fqsen('\\PHP8\\Email')),
59+
new Expression(
60+
'new {{ PHPDOCc27b34d4d91bc4d52190708db8447e09 }}()',
61+
[
62+
'{{ PHPDOCc27b34d4d91bc4d52190708db8447e09 }}' => new Fqsen('\\PHP8\\Email'),
63+
],
64+
)
65+
)
66+
);
5667
$constructor->addArgument(new Argument('birth_date', new Object_(new Fqsen('\\' . DateTimeImmutable::class))));
5768
$constructor->addArgument(
5869
new Argument(
5970
'created_at',
6071
new Object_(new Fqsen('\\' . DateTimeImmutable::class)),
6172
new Expression(
62-
'new {{ PHPDOC6ffacd918e2f70478d2fd33dcb58c4d4 }}(\'now\')',
73+
'new {{ PHPDOCf854926c6ee2b49d3385c30295984295 }}(\'now\')',
6374
[
64-
'{{ PHPDOC6ffacd918e2f70478d2fd33dcb58c4d4 }}' => new Fqsen('\\DateTimeImmutable')
75+
'{{ PHPDOCf854926c6ee2b49d3385c30295984295 }}' => new Fqsen('\\DateTimeImmutable')
6576
]
6677
)
6778
)
@@ -73,7 +84,7 @@ public function testArgumentsAreReadCorrectly() : void
7384
new Expression(
7485
'[{{ PHPDOC19b72d1f430d952a8dfe2384dd4e93dc }}]',
7586
[
76-
'{{ PHPDOC19b72d1f430d952a8dfe2384dd4e93dc }}' => new Fqsen('\PHP8\ConstructorPromotion::DEFAULT_VALUE'),
87+
'{{ PHPDOC19b72d1f430d952a8dfe2384dd4e93dc }}' => new Fqsen('\self::DEFAULT_VALUE'),
7788
],
7889
),
7990
),
@@ -121,7 +132,7 @@ private function expectedConstructorMethod(): Method
121132
false,
122133
false,
123134
new Location(18, 264),
124-
new Location(31, 704)
135+
new Location(31, 718)
125136
);
126137
}
127138

@@ -153,9 +164,9 @@ private function expectedEmailProperty(): Property
153164
new Visibility(Visibility::PROTECTED_),
154165
null,
155166
new Expression(
156-
'new {{PHPDOCce8ae9da5b7cd6c3df2929543a9af92d}}()',
167+
'new {{ PHPDOCc27b34d4d91bc4d52190708db8447e09 }}()',
157168
[
158-
'{{ PHPDOCce8ae9da5b7cd6c3df2929543a9af92d }}' => new Fqsen('\\PHP8\\Email'),
169+
'{{ PHPDOCc27b34d4d91bc4d52190708db8447e09 }}' => new Fqsen('\\PHP8\\Email'),
159170
],
160171
),
161172
false,
@@ -186,9 +197,9 @@ private function expectedCreatedAtProperty(): Property
186197
new Visibility(Visibility::PRIVATE_),
187198
null,
188199
new Expression(
189-
'new {{ PHPDOC6ffacd918e2f70478d2fd33dcb58c4d4 }}(\'now\')',
200+
'new {{ PHPDOCf854926c6ee2b49d3385c30295984295 }}(\'now\')',
190201
[
191-
'{{ PHPDOC6ffacd918e2f70478d2fd33dcb58c4d4 }}' => new Fqsen('\\DateTimeImmutable'),
202+
'{{ PHPDOCf854926c6ee2b49d3385c30295984295 }}' => new Fqsen('\\DateTimeImmutable'),
192203
],
193204
),
194205
false,
@@ -207,7 +218,7 @@ private function expectedUsesConstantsProperty()
207218
new Expression(
208219
'[{{ PHPDOC19b72d1f430d952a8dfe2384dd4e93dc }}]',
209220
[
210-
'{{ PHPDOC19b72d1f430d952a8dfe2384dd4e93dc }}' => new Fqsen('\PHP8\ConstructorPromotion::DEFAULT_VALUE'),
221+
'{{ PHPDOC19b72d1f430d952a8dfe2384dd4e93dc }}' => new Fqsen('\self::DEFAULT_VALUE'),
211222
],
212223
),
213224
false,

0 commit comments

Comments
 (0)