Skip to content

Commit 5d59d11

Browse files
committed
Merge branch '1.12.x' into 2.0.x
2 parents a883c66 + ce3ffbd commit 5d59d11

File tree

89 files changed

+903
-80
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

89 files changed

+903
-80
lines changed

resources/functionMap.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12606,7 +12606,7 @@
1260612606
'timezone_version_get' => ['string'],
1260712607
'tmpfile' => ['__benevolent<resource|false>'],
1260812608
'token_get_all' => ['list<string|array{0:int,1:string,2:int}>', 'source'=>'string', 'flags='=>'int'],
12609-
'token_name' => ['non-empty-string', 'type'=>'int'],
12609+
'token_name' => ['non-falsy-string', 'type'=>'int'],
1261012610
'TokyoTyrant::__construct' => ['void', 'host='=>'string', 'port='=>'int', 'options='=>'array'],
1261112611
'TokyoTyrant::add' => ['int|float', 'key'=>'string', 'increment'=>'float', 'type='=>'int'],
1261212612
'TokyoTyrant::connect' => ['TokyoTyrant', 'host'=>'string', 'port='=>'int', 'options='=>'array'],

resources/functionMap_php80delta.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@
9595
'PhpToken::tokenize' => ['list<PhpToken>', 'code'=>'string', 'flags='=>'int'],
9696
'PhpToken::is' => ['bool', 'kind'=>'string|int|string[]|int[]'],
9797
'PhpToken::isIgnorable' => ['bool'],
98-
'PhpToken::getTokenName' => ['string'],
98+
'PhpToken::getTokenName' => ['non-falsy-string'],
9999
'preg_match_all' => ['0|positive-int|false', 'pattern'=>'string', 'subject'=>'string', '&w_subpatterns='=>'array', 'flags='=>'int', 'offset='=>'int'],
100100
'proc_get_status' => ['array{command: string, pid: int, running: bool, signaled: bool, stopped: bool, exitcode: int, termsig: int, stopsig: int}', 'process'=>'resource'],
101101
'set_error_handler' => ['?callable', 'callback'=>'null|callable(int,string,string,int):bool', 'error_types='=>'int'],

src/Analyser/MutatingScope.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2536,6 +2536,7 @@ private function createFirstClassCallable(
25362536
$templateTags[$templateType->getName()] = new TemplateTag(
25372537
$templateType->getName(),
25382538
$templateType->getBound(),
2539+
$templateType->getDefault(),
25392540
$templateType->getVariance(),
25402541
);
25412542
}
@@ -5547,7 +5548,7 @@ private function exactInstantiation(New_ $node, string $className): ?Type
55475548
if ($type instanceof TemplateType && !$type->isArgument()) {
55485549
$newType = $resolvedTemplateTypeMap->getType($type->getName());
55495550
if ($newType === null || $newType instanceof ErrorType) {
5550-
return $type->getBound();
5551+
return $type->getDefault() ?? $type->getBound();
55515552
}
55525553

55535554
return TemplateTypeHelper::generalizeInferredTemplateType($type, $newType);

src/Dependency/DependencyResolver.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -525,6 +525,17 @@ private function addClassToDependencies(string $className, array &$dependenciesR
525525
}
526526
$dependenciesReflections[] = $this->reflectionProvider->getClass($referencedClass);
527527
}
528+
529+
$default = $templateTag->getDefault();
530+
if ($default === null) {
531+
continue;
532+
}
533+
foreach ($default->getReferencedClasses() as $referencedClass) {
534+
if (!$this->reflectionProvider->hasClass($referencedClass)) {
535+
continue;
536+
}
537+
$dependenciesReflections[] = $this->reflectionProvider->getClass($referencedClass);
538+
}
528539
}
529540

530541
foreach ($classReflection->getPropertyTags() as $propertyTag) {

src/Parser/ArrowFunctionArgVisitor.php

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,28 @@ final class ArrowFunctionArgVisitor extends NodeVisitorAbstract
1313

1414
public function enterNode(Node $node): ?Node
1515
{
16-
if ($node instanceof Node\Expr\FuncCall && $node->name instanceof Node\Expr\ArrowFunction && !$node->isFirstClassCallable()) {
17-
$args = $node->getArgs();
16+
if (!$node instanceof Node\Expr\FuncCall) {
17+
return null;
18+
}
19+
20+
if ($node->isFirstClassCallable()) {
21+
return null;
22+
}
1823

19-
if (count($args) > 0) {
20-
$node->name->setAttribute(self::ATTRIBUTE_NAME, $args);
21-
}
24+
if ($node->name instanceof Node\Expr\Assign && $node->name->expr instanceof Node\Expr\ArrowFunction) {
25+
$arrow = $node->name->expr;
26+
} elseif ($node->name instanceof Node\Expr\ArrowFunction) {
27+
$arrow = $node->name;
28+
} else {
29+
return null;
2230
}
31+
32+
$args = $node->getArgs();
33+
34+
if (count($args) > 0) {
35+
$arrow->setAttribute(self::ATTRIBUTE_NAME, $args);
36+
}
37+
2338
return null;
2439
}
2540

src/Parser/ClosureArgVisitor.php

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,28 @@ final class ClosureArgVisitor extends NodeVisitorAbstract
1313

1414
public function enterNode(Node $node): ?Node
1515
{
16-
if ($node instanceof Node\Expr\FuncCall && $node->name instanceof Node\Expr\Closure && !$node->isFirstClassCallable()) {
17-
$args = $node->getArgs();
16+
if (!$node instanceof Node\Expr\FuncCall) {
17+
return null;
18+
}
19+
20+
if ($node->isFirstClassCallable()) {
21+
return null;
22+
}
1823

19-
if (count($args) > 0) {
20-
$node->name->setAttribute(self::ATTRIBUTE_NAME, $args);
21-
}
24+
if ($node->name instanceof Node\Expr\Assign && $node->name->expr instanceof Node\Expr\Closure) {
25+
$closure = $node->name->expr;
26+
} elseif ($node->name instanceof Node\Expr\Closure) {
27+
$closure = $node->name;
28+
} else {
29+
return null;
2230
}
31+
32+
$args = $node->getArgs();
33+
34+
if (count($args) > 0) {
35+
$closure->setAttribute(self::ATTRIBUTE_NAME, $args);
36+
}
37+
2338
return null;
2439
}
2540

src/PhpDoc/PhpDocNodeResolver.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,9 @@ public function resolveMethodTags(PhpDocNode $phpDocNode, NameScope $nameScope):
173173
$templateType->bound !== null
174174
? $this->typeNodeResolver->resolve($templateType->bound, $nameScope)
175175
: new MixedType(),
176+
$templateType->default !== null
177+
? $this->typeNodeResolver->resolve($templateType->default, $nameScope)
178+
: null,
176179
TemplateTypeVariance::createInvariant(),
177180
);
178181
}
@@ -324,9 +327,12 @@ public function resolveTemplateTags(PhpDocNode $phpDocNode, NameScope $nameScope
324327
}
325328
}
326329

330+
$nameScopeWithoutCurrent = $nameScope->unsetTemplateType($valueNode->name);
331+
327332
$resolved[$valueNode->name] = new TemplateTag(
328333
$valueNode->name,
329-
$valueNode->bound !== null ? $this->typeNodeResolver->resolve($valueNode->bound, $nameScope->unsetTemplateType($valueNode->name)) : new MixedType(true),
334+
$valueNode->bound !== null ? $this->typeNodeResolver->resolve($valueNode->bound, $nameScopeWithoutCurrent) : new MixedType(true),
335+
$valueNode->default !== null ? $this->typeNodeResolver->resolve($valueNode->default, $nameScopeWithoutCurrent) : null,
330336
$variance,
331337
);
332338
$resolvedPrefix[$valueNode->name] = $prefix;

src/PhpDoc/Tag/TemplateTag.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ final class TemplateTag
1414
/**
1515
* @param non-empty-string $name
1616
*/
17-
public function __construct(private string $name, private Type $bound, private TemplateTypeVariance $variance)
17+
public function __construct(private string $name, private Type $bound, private ?Type $default, private TemplateTypeVariance $variance)
1818
{
1919
}
2020

@@ -31,6 +31,11 @@ public function getBound(): Type
3131
return $this->bound;
3232
}
3333

34+
public function getDefault(): ?Type
35+
{
36+
return $this->default;
37+
}
38+
3439
public function getVariance(): TemplateTypeVariance
3540
{
3641
return $this->variance;

src/PhpDoc/TypeNodeResolver.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -792,6 +792,15 @@ static function (string $variance): TemplateTypeVariance {
792792

793793
$classReflection = $this->getReflectionProvider()->getClass($mainTypeClassName);
794794
if ($classReflection->isGeneric()) {
795+
$templateTypes = array_values($classReflection->getTemplateTypeMap()->getTypes());
796+
for ($i = count($genericTypes), $templateTypesCount = count($templateTypes); $i < $templateTypesCount; $i++) {
797+
$templateType = $templateTypes[$i];
798+
if (!$templateType instanceof TemplateType || $templateType->getDefault() === null) {
799+
continue;
800+
}
801+
$genericTypes[] = $templateType->getDefault();
802+
}
803+
795804
if (in_array($mainTypeClassName, [
796805
Traversable::class,
797806
IteratorAggregate::class,
@@ -910,6 +919,9 @@ private function resolveCallableTypeNode(CallableTypeNode $typeNode, NameScope $
910919
$templateType->bound !== null
911920
? $this->resolve($templateType->bound, $nameScope)
912921
: new MixedType(),
922+
$templateType->default !== null
923+
? $this->resolve($templateType->default, $nameScope)
924+
: null,
913925
TemplateTypeVariance::createInvariant(),
914926
);
915927
}

src/Reflection/ClassReflection.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1432,7 +1432,7 @@ public function typeMapFromList(array $types): TemplateTypeMap
14321432
$map = [];
14331433
$i = 0;
14341434
foreach ($resolvedPhpDoc->getTemplateTags() as $tag) {
1435-
$map[$tag->getName()] = $types[$i] ?? $tag->getBound();
1435+
$map[$tag->getName()] = $types[$i] ?? $tag->getDefault() ?? $tag->getBound();
14361436
$i++;
14371437
}
14381438

@@ -1469,7 +1469,7 @@ public function typeMapToList(TemplateTypeMap $typeMap): array
14691469

14701470
$list = [];
14711471
foreach ($resolvedPhpDoc->getTemplateTags() as $tag) {
1472-
$list[] = $typeMap->getType($tag->getName()) ?? $tag->getBound();
1472+
$list[] = $typeMap->getType($tag->getName()) ?? $tag->getDefault() ?? $tag->getBound();
14731473
}
14741474

14751475
return $list;

0 commit comments

Comments
 (0)