diff --git a/.github/workflows/dependabot-auto-merge.yml b/.github/workflows/dependabot-auto-merge.yml
index d0c1fb55..12b371ca 100644
--- a/.github/workflows/dependabot-auto-merge.yml
+++ b/.github/workflows/dependabot-auto-merge.yml
@@ -13,7 +13,7 @@ jobs:
steps:
- name: "Dependabot metadata"
id: "metadata"
- uses: "dependabot/fetch-metadata@v2.4.0"
+ uses: "dependabot/fetch-metadata@v2.5.0"
with:
github-token: "${{ secrets.GITHUB_TOKEN }}"
- name: "Enable auto-merge for Dependabot PRs"
diff --git a/.github/workflows/documentation.yaml b/.github/workflows/documentation.yaml
index 19975936..32ac9bbd 100644
--- a/.github/workflows/documentation.yaml
+++ b/.github/workflows/documentation.yaml
@@ -19,7 +19,7 @@ jobs:
- name: "Deploy"
if: "${{ github.event_name == 'push' && github.ref == 'refs/heads/6.x' }}"
- uses: "actions/upload-artifact@v5"
+ uses: "actions/upload-artifact@v7"
with:
name: "documentation"
path: "build/docs"
diff --git a/composer.lock b/composer.lock
index 5e78026d..eff0f0d0 100644
--- a/composer.lock
+++ b/composer.lock
@@ -8,29 +8,29 @@
"packages": [
{
"name": "doctrine/deprecations",
- "version": "1.1.5",
+ "version": "1.1.6",
"source": {
"type": "git",
"url": "https://github.com/doctrine/deprecations.git",
- "reference": "459c2f5dd3d6a4633d3b5f46ee2b1c40f57d3f38"
+ "reference": "d4fe3e6fd9bb9e72557a19674f44d8ac7db4c6ca"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/doctrine/deprecations/zipball/459c2f5dd3d6a4633d3b5f46ee2b1c40f57d3f38",
- "reference": "459c2f5dd3d6a4633d3b5f46ee2b1c40f57d3f38",
+ "url": "https://api.github.com/repos/doctrine/deprecations/zipball/d4fe3e6fd9bb9e72557a19674f44d8ac7db4c6ca",
+ "reference": "d4fe3e6fd9bb9e72557a19674f44d8ac7db4c6ca",
"shasum": ""
},
"require": {
"php": "^7.1 || ^8.0"
},
"conflict": {
- "phpunit/phpunit": "<=7.5 || >=13"
+ "phpunit/phpunit": "<=7.5 || >=14"
},
"require-dev": {
- "doctrine/coding-standard": "^9 || ^12 || ^13",
- "phpstan/phpstan": "1.4.10 || 2.1.11",
+ "doctrine/coding-standard": "^9 || ^12 || ^14",
+ "phpstan/phpstan": "1.4.10 || 2.1.30",
"phpstan/phpstan-phpunit": "^1.0 || ^2",
- "phpunit/phpunit": "^7.5 || ^8.5 || ^9.6 || ^10.5 || ^11.5 || ^12",
+ "phpunit/phpunit": "^7.5 || ^8.5 || ^9.6 || ^10.5 || ^11.5 || ^12.4 || ^13.0",
"psr/log": "^1 || ^2 || ^3"
},
"suggest": {
@@ -50,22 +50,22 @@
"homepage": "https://www.doctrine-project.org/",
"support": {
"issues": "https://github.com/doctrine/deprecations/issues",
- "source": "https://github.com/doctrine/deprecations/tree/1.1.5"
+ "source": "https://github.com/doctrine/deprecations/tree/1.1.6"
},
- "time": "2025-04-07T20:06:18+00:00"
+ "time": "2026-02-07T07:09:04+00:00"
},
{
"name": "nikic/php-parser",
- "version": "v5.6.2",
+ "version": "v5.7.0",
"source": {
"type": "git",
"url": "https://github.com/nikic/PHP-Parser.git",
- "reference": "3a454ca033b9e06b63282ce19562e892747449bb"
+ "reference": "dca41cd15c2ac9d055ad70dbfd011130757d1f82"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/3a454ca033b9e06b63282ce19562e892747449bb",
- "reference": "3a454ca033b9e06b63282ce19562e892747449bb",
+ "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/dca41cd15c2ac9d055ad70dbfd011130757d1f82",
+ "reference": "dca41cd15c2ac9d055ad70dbfd011130757d1f82",
"shasum": ""
},
"require": {
@@ -108,9 +108,9 @@
],
"support": {
"issues": "https://github.com/nikic/PHP-Parser/issues",
- "source": "https://github.com/nikic/PHP-Parser/tree/v5.6.2"
+ "source": "https://github.com/nikic/PHP-Parser/tree/v5.7.0"
},
- "time": "2025-10-21T19:32:17+00:00"
+ "time": "2025-12-06T11:56:16+00:00"
},
{
"name": "phpdocumentor/reflection-common",
@@ -167,16 +167,16 @@
},
{
"name": "phpdocumentor/reflection-docblock",
- "version": "5.6.4",
+ "version": "5.6.6",
"source": {
"type": "git",
"url": "https://github.com/phpDocumentor/ReflectionDocBlock.git",
- "reference": "90a04bcbf03784066f16038e87e23a0a83cee3c2"
+ "reference": "5cee1d3dfc2d2aa6599834520911d246f656bcb8"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/90a04bcbf03784066f16038e87e23a0a83cee3c2",
- "reference": "90a04bcbf03784066f16038e87e23a0a83cee3c2",
+ "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/5cee1d3dfc2d2aa6599834520911d246f656bcb8",
+ "reference": "5cee1d3dfc2d2aa6599834520911d246f656bcb8",
"shasum": ""
},
"require": {
@@ -186,7 +186,7 @@
"phpdocumentor/reflection-common": "^2.2",
"phpdocumentor/type-resolver": "^1.7",
"phpstan/phpdoc-parser": "^1.7|^2.0",
- "webmozart/assert": "^1.9.1"
+ "webmozart/assert": "^1.9.1 || ^2"
},
"require-dev": {
"mockery/mockery": "~1.3.5 || ~1.6.0",
@@ -225,9 +225,9 @@
"description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.",
"support": {
"issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues",
- "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.6.4"
+ "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.6.6"
},
- "time": "2025-11-17T21:13:10+00:00"
+ "time": "2025-12-22T21:13:58+00:00"
},
{
"name": "phpdocumentor/type-resolver",
@@ -289,16 +289,16 @@
},
{
"name": "phpstan/phpdoc-parser",
- "version": "2.3.0",
+ "version": "2.3.2",
"source": {
"type": "git",
"url": "https://github.com/phpstan/phpdoc-parser.git",
- "reference": "1e0cd5370df5dd2e556a36b9c62f62e555870495"
+ "reference": "a004701b11273a26cd7955a61d67a7f1e525a45a"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/1e0cd5370df5dd2e556a36b9c62f62e555870495",
- "reference": "1e0cd5370df5dd2e556a36b9c62f62e555870495",
+ "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/a004701b11273a26cd7955a61d67a7f1e525a45a",
+ "reference": "a004701b11273a26cd7955a61d67a7f1e525a45a",
"shasum": ""
},
"require": {
@@ -330,9 +330,9 @@
"description": "PHPDoc parser with support for nullable, intersection and generic types",
"support": {
"issues": "https://github.com/phpstan/phpdoc-parser/issues",
- "source": "https://github.com/phpstan/phpdoc-parser/tree/2.3.0"
+ "source": "https://github.com/phpstan/phpdoc-parser/tree/2.3.2"
},
- "time": "2025-08-30T15:50:23+00:00"
+ "time": "2026-01-25T14:56:51+00:00"
},
{
"name": "symfony/polyfill-php80",
@@ -1190,22 +1190,22 @@
},
{
"name": "phpspec/prophecy-phpunit",
- "version": "v2.4.0",
+ "version": "v2.5.0",
"source": {
"type": "git",
"url": "https://github.com/phpspec/prophecy-phpunit.git",
- "reference": "d3c28041d9390c9bca325a08c5b2993ac855bded"
+ "reference": "89f91b01d0640b7820e427e02a007bc6489d8a26"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/phpspec/prophecy-phpunit/zipball/d3c28041d9390c9bca325a08c5b2993ac855bded",
- "reference": "d3c28041d9390c9bca325a08c5b2993ac855bded",
+ "url": "https://api.github.com/repos/phpspec/prophecy-phpunit/zipball/89f91b01d0640b7820e427e02a007bc6489d8a26",
+ "reference": "89f91b01d0640b7820e427e02a007bc6489d8a26",
"shasum": ""
},
"require": {
"php": "^7.3 || ^8",
"phpspec/prophecy": "^1.18",
- "phpunit/phpunit": "^9.1 || ^10.1 || ^11.0 || ^12.0"
+ "phpunit/phpunit": "^9.1 || ^10.1 || ^11.0 || ^12.0 || ^13.0"
},
"require-dev": {
"phpstan/phpstan": "^1.10"
@@ -1239,9 +1239,9 @@
],
"support": {
"issues": "https://github.com/phpspec/prophecy-phpunit/issues",
- "source": "https://github.com/phpspec/prophecy-phpunit/tree/v2.4.0"
+ "source": "https://github.com/phpspec/prophecy-phpunit/tree/v2.5.0"
},
- "time": "2025-05-13T13:52:32+00:00"
+ "time": "2026-02-09T15:40:55+00:00"
},
{
"name": "phpstan/extension-installer",
@@ -1723,16 +1723,16 @@
},
{
"name": "phpunit/phpunit",
- "version": "10.5.58",
+ "version": "10.5.63",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/phpunit.git",
- "reference": "e24fb46da450d8e6a5788670513c1af1424f16ca"
+ "reference": "33198268dad71e926626b618f3ec3966661e4d90"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/e24fb46da450d8e6a5788670513c1af1424f16ca",
- "reference": "e24fb46da450d8e6a5788670513c1af1424f16ca",
+ "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/33198268dad71e926626b618f3ec3966661e4d90",
+ "reference": "33198268dad71e926626b618f3ec3966661e4d90",
"shasum": ""
},
"require": {
@@ -1753,7 +1753,7 @@
"phpunit/php-timer": "^6.0.0",
"sebastian/cli-parser": "^2.0.1",
"sebastian/code-unit": "^2.0.0",
- "sebastian/comparator": "^5.0.4",
+ "sebastian/comparator": "^5.0.5",
"sebastian/diff": "^5.1.1",
"sebastian/environment": "^6.1.0",
"sebastian/exporter": "^5.1.4",
@@ -1804,7 +1804,7 @@
"support": {
"issues": "https://github.com/sebastianbergmann/phpunit/issues",
"security": "https://github.com/sebastianbergmann/phpunit/security/policy",
- "source": "https://github.com/sebastianbergmann/phpunit/tree/10.5.58"
+ "source": "https://github.com/sebastianbergmann/phpunit/tree/10.5.63"
},
"funding": [
{
@@ -1828,7 +1828,7 @@
"type": "tidelift"
}
],
- "time": "2025-09-28T12:04:46+00:00"
+ "time": "2026-01-27T05:48:37+00:00"
},
{
"name": "psalm/phar",
@@ -2094,16 +2094,16 @@
},
{
"name": "sebastian/comparator",
- "version": "5.0.4",
+ "version": "5.0.5",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/comparator.git",
- "reference": "e8e53097718d2b53cfb2aa859b06a41abf58c62e"
+ "reference": "55dfef806eb7dfeb6e7a6935601fef866f8ca48d"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/e8e53097718d2b53cfb2aa859b06a41abf58c62e",
- "reference": "e8e53097718d2b53cfb2aa859b06a41abf58c62e",
+ "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/55dfef806eb7dfeb6e7a6935601fef866f8ca48d",
+ "reference": "55dfef806eb7dfeb6e7a6935601fef866f8ca48d",
"shasum": ""
},
"require": {
@@ -2159,7 +2159,7 @@
"support": {
"issues": "https://github.com/sebastianbergmann/comparator/issues",
"security": "https://github.com/sebastianbergmann/comparator/security/policy",
- "source": "https://github.com/sebastianbergmann/comparator/tree/5.0.4"
+ "source": "https://github.com/sebastianbergmann/comparator/tree/5.0.5"
},
"funding": [
{
@@ -2179,7 +2179,7 @@
"type": "tidelift"
}
],
- "time": "2025-09-07T05:25:07+00:00"
+ "time": "2026-01-24T09:25:16+00:00"
},
{
"name": "sebastian/complexity",
@@ -3023,16 +3023,16 @@
},
{
"name": "theseer/tokenizer",
- "version": "1.3.0",
+ "version": "1.3.1",
"source": {
"type": "git",
"url": "https://github.com/theseer/tokenizer.git",
- "reference": "d74205c497bfbca49f34d4bc4c19c17e22db4ebb"
+ "reference": "b7489ce515e168639d17feec34b8847c326b0b3c"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/theseer/tokenizer/zipball/d74205c497bfbca49f34d4bc4c19c17e22db4ebb",
- "reference": "d74205c497bfbca49f34d4bc4c19c17e22db4ebb",
+ "url": "https://api.github.com/repos/theseer/tokenizer/zipball/b7489ce515e168639d17feec34b8847c326b0b3c",
+ "reference": "b7489ce515e168639d17feec34b8847c326b0b3c",
"shasum": ""
},
"require": {
@@ -3061,7 +3061,7 @@
"description": "A small library for converting tokenized PHP source code into XML and potentially other formats",
"support": {
"issues": "https://github.com/theseer/tokenizer/issues",
- "source": "https://github.com/theseer/tokenizer/tree/1.3.0"
+ "source": "https://github.com/theseer/tokenizer/tree/1.3.1"
},
"funding": [
{
@@ -3069,7 +3069,7 @@
"type": "github"
}
],
- "time": "2025-11-13T13:44:09+00:00"
+ "time": "2025-11-17T20:03:58+00:00"
}
],
"aliases": [],
diff --git a/psalm-baseline.xml b/psalm-baseline.xml
index 9dd1e5bf..4a60c177 100644
--- a/psalm-baseline.xml
+++ b/psalm-baseline.xml
@@ -225,8 +225,5 @@
-
- aliasesToFullyQualifiedNames($namespace)]]>
-
diff --git a/src/phpDocumentor/Reflection/Php/Constant.php b/src/phpDocumentor/Reflection/Php/Constant.php
index 1b334758..736dcdd0 100644
--- a/src/phpDocumentor/Reflection/Php/Constant.php
+++ b/src/phpDocumentor/Reflection/Php/Constant.php
@@ -19,6 +19,7 @@
use phpDocumentor\Reflection\Fqsen;
use phpDocumentor\Reflection\Location;
use phpDocumentor\Reflection\Metadata\MetaDataContainer as MetaDataContainerInterface;
+use phpDocumentor\Reflection\Type;
use function is_string;
use function trigger_error;
@@ -52,6 +53,7 @@ public function __construct(
Location|null $endLocation = null,
Visibility|null $visibility = null,
private readonly bool $final = false,
+ private readonly Type|null $type = null,
) {
$this->location = $location ?: new Location(-1);
$this->endLocation = $endLocation ?: new Location(-1);
@@ -135,4 +137,9 @@ public function isFinal(): bool
{
return $this->final;
}
+
+ public function getType(): Type|null
+ {
+ return $this->type;
+ }
}
diff --git a/src/phpDocumentor/Reflection/Php/Expression/ExpressionPrinter.php b/src/phpDocumentor/Reflection/Php/Expression/ExpressionPrinter.php
index 5fe66ae7..5e9162ec 100644
--- a/src/phpDocumentor/Reflection/Php/Expression/ExpressionPrinter.php
+++ b/src/phpDocumentor/Reflection/Php/Expression/ExpressionPrinter.php
@@ -86,7 +86,10 @@ protected function pExpr_ClassConstFetch(Expr\ClassConstFetch $node): string
{
$renderedName = parent::pObjectProperty($node->name);
- if ($node->class instanceof Name) {
+ if ($node->class instanceof Name\FullyQualified) {
+ $className = parent::pName_FullyQualified($node->class);
+ $className = $this->typeResolver->resolve($className, $this->context);
+ } elseif ($node->class instanceof Name) {
$className = parent::pName($node->class);
$className = $this->typeResolver->resolve($className, $this->context);
} else {
diff --git a/src/phpDocumentor/Reflection/Php/Factory/ClassConstant.php b/src/phpDocumentor/Reflection/Php/Factory/ClassConstant.php
index 7d6ed2b9..e49bd2be 100644
--- a/src/phpDocumentor/Reflection/Php/Factory/ClassConstant.php
+++ b/src/phpDocumentor/Reflection/Php/Factory/ClassConstant.php
@@ -93,6 +93,7 @@ protected function doCreate(
new Location($const->getEndLine()),
$this->buildVisibility($const),
$const->isFinal(),
+ (new Type())->fromPhpParser($const->getType(), $context->getTypeContext()),
);
foreach ($this->reducers as $reducer) {
diff --git a/src/phpDocumentor/Reflection/Php/Factory/ClassConstantIterator.php b/src/phpDocumentor/Reflection/Php/Factory/ClassConstantIterator.php
index 93e1f23c..278d21ae 100644
--- a/src/phpDocumentor/Reflection/Php/Factory/ClassConstantIterator.php
+++ b/src/phpDocumentor/Reflection/Php/Factory/ClassConstantIterator.php
@@ -17,7 +17,10 @@
use Override;
use phpDocumentor\Reflection\Fqsen;
use PhpParser\Comment\Doc;
+use PhpParser\Node\ComplexType;
use PhpParser\Node\Expr;
+use PhpParser\Node\Identifier;
+use PhpParser\Node\Name;
use PhpParser\Node\Stmt\ClassConst;
/**
@@ -123,6 +126,14 @@ public function isFinal(): bool
return $this->classConstants->isFinal();
}
+ /**
+ * Gets the type of the constant.
+ */
+ public function getType(): Identifier|Name|ComplexType|null
+ {
+ return $this->classConstants->type;
+ }
+
/** @link http://php.net/manual/en/iterator.current.php */
#[Override]
public function current(): self
diff --git a/src/phpDocumentor/Reflection/Php/Factory/File.php b/src/phpDocumentor/Reflection/Php/Factory/File.php
index 46fba96d..22b95e7b 100644
--- a/src/phpDocumentor/Reflection/Php/Factory/File.php
+++ b/src/phpDocumentor/Reflection/Php/Factory/File.php
@@ -24,6 +24,7 @@
use phpDocumentor\Reflection\Php\NodesFactory;
use phpDocumentor\Reflection\Php\StrategyContainer;
use phpDocumentor\Reflection\Types\Context;
+use phpDocumentor\Reflection\Types\FileToContext;
use PhpParser\Comment\Doc;
use PhpParser\Node;
use PhpParser\Node\Stmt\Class_ as ClassNode;
@@ -106,7 +107,9 @@ private function createFile(CreateCommand $command): FileElement
$code = $file->getContents();
$nodes = $this->nodesFactory->create($code);
- $docBlock = $this->createFileDocBlock(null, $nodes);
+ $fileToContext = new FileToContext();
+ $typeContext = $fileToContext($nodes);
+ $docBlock = $this->createFileDocBlock($typeContext, $nodes);
$result = new FileElement(
$file->md5(),
@@ -115,7 +118,7 @@ private function createFile(CreateCommand $command): FileElement
$docBlock,
);
- $this->createElements($command->getContext()->push($result), $nodes, $command->getStrategies());
+ $this->createElements($command->getContext()->push($result)->withTypeContext($typeContext), $nodes, $command->getStrategies());
return $result;
}
diff --git a/src/phpDocumentor/Reflection/Types/BaseToContext.php b/src/phpDocumentor/Reflection/Types/BaseToContext.php
new file mode 100644
index 00000000..26b5acbe
--- /dev/null
+++ b/src/phpDocumentor/Reflection/Types/BaseToContext.php
@@ -0,0 +1,59 @@
+
+ */
+ protected static function flattenUsage(array $usages): array
+ {
+ return array_merge([], ...array_merge([], ...array_map(
+ static fn ($use): array => array_map(
+ static function (Node\UseItem|UseUse $useUse) use ($use): array {
+ if ($use instanceof GroupUse) {
+ return [
+ (string) $useUse->getAlias() => $use->prefix->toString() . '\\' . $useUse->name->toString(),
+ ];
+ }
+
+ return [(string) $useUse->getAlias() => $useUse->name->toString()];
+ },
+ $use->uses,
+ ),
+ $usages,
+ )));
+ }
+
+ /**
+ * @param Node[] $nodes
+ *
+ * @return Use_[]|GroupUse[]
+ */
+ protected static function filterUsage(array $nodes): array
+ {
+ return array_filter(
+ $nodes,
+ static fn (Node $node): bool => (
+ $node instanceof Use_
+ || $node instanceof GroupUse
+ ) && in_array($node->type, [Use_::TYPE_UNKNOWN, Use_::TYPE_NORMAL], true),
+ );
+ }
+}
diff --git a/src/phpDocumentor/Reflection/Types/FileToContext.php b/src/phpDocumentor/Reflection/Types/FileToContext.php
new file mode 100644
index 00000000..7a45e7e8
--- /dev/null
+++ b/src/phpDocumentor/Reflection/Types/FileToContext.php
@@ -0,0 +1,19 @@
+name ? $namespace->name->toString() : '',
- $this->aliasesToFullyQualifiedNames($namespace),
- );
- }
-
- /** @return string[] indexed by alias */
- private function aliasesToFullyQualifiedNames(Namespace_ $namespace): array
- {
- // flatten(flatten(map(stuff)))
- return array_merge([], ...array_merge([], ...array_map(
- static fn ($use): array => array_map(
- static function (Node\UseItem|UseUse $useUse) use ($use): array {
- if ($use instanceof GroupUse) {
- return [
- (string) $useUse->getAlias() => $use->prefix->toString() . '\\' . $useUse->name->toString(),
- ];
- }
-
- return [(string) $useUse->getAlias() => $useUse->name->toString()];
- },
- $use->uses,
- ),
- $this->classAlikeUses($namespace),
- )));
- }
-
- /** @return Use_[]|GroupUse[] */
- private function classAlikeUses(Namespace_ $namespace): array
- {
- return array_filter(
- $namespace->stmts,
- static fn (Node $node): bool => (
- $node instanceof Use_
- || $node instanceof GroupUse
- ) && in_array($node->type, [Use_::TYPE_UNKNOWN, Use_::TYPE_NORMAL], true),
+ self::flattenUsage(self::filterUsage($namespace->stmts)),
);
}
}
diff --git a/tests/integration/EnumTest.php b/tests/integration/EnumTest.php
index 03e2c30f..bf3d12e6 100644
--- a/tests/integration/EnumTest.php
+++ b/tests/integration/EnumTest.php
@@ -115,10 +115,9 @@ public function testEnumSupportInMethod(): void
$method->getArguments()[0]->getType()
);
- //This should be fixed in #219
-// self::assertEquals(
-// '\MyNamespace\MyEnum::VALUE1',
-// $method->getArguments()[0]->getDefault()
-// );
+ self::assertEquals(
+ '\MyNamespace\MyEnum::VALUE1',
+ $method->getArguments()[0]->getDefault()
+ );
}
}
diff --git a/tests/integration/ProjectCreationTest.php b/tests/integration/ProjectCreationTest.php
index 7cd1701a..63558a71 100644
--- a/tests/integration/ProjectCreationTest.php
+++ b/tests/integration/ProjectCreationTest.php
@@ -17,6 +17,7 @@
use phpDocumentor\Reflection\DocBlock\Tags\Param;
use phpDocumentor\Reflection\File\LocalFile;
use phpDocumentor\Reflection\Php\Class_;
+use phpDocumentor\Reflection\Php\Expression;
use phpDocumentor\Reflection\Php\Function_;
use phpDocumentor\Reflection\Php\ProjectFactory;
use phpDocumentor\Reflection\Types\Integer;
@@ -250,4 +251,36 @@ public function testMethodReturnType() : void
$this->assertEquals(new String_(), $interface->getMethods()['\Packing::getName()']->getReturnType());
}
+
+ public function testFunctionContantDefaultIsResolved() : void
+ {
+ $fileName = __DIR__ . '/data/GlobalFiles/function_constant_default.php';
+ $project = $this->fixture->create(
+ 'MyProject',
+ [new LocalFile($fileName)]
+ );
+
+ $this->assertArrayHasKey($fileName, $project->getFiles());
+ $functions = $project->getFiles()[$fileName]->getFunctions();
+
+ self::assertEquals(
+ new Expression(
+ '{{ PHPDOCa2f2ed4f8ebc2cbb4c21a29dc40ab61d }}',
+ [
+ '{{ PHPDOCa2f2ed4f8ebc2cbb4c21a29dc40ab61d }}' => new Fqsen('\Acme\Plugin::class'),
+ ],
+ ),
+ $functions['\foo()']->getArguments()[0]->getDefault(false)
+ );
+
+ self::assertEquals(
+ new Expression(
+ '{{ PHPDOCa8cfde6331bd59eb2ac96f8911c4b666 }}',
+ [
+ '{{ PHPDOCa8cfde6331bd59eb2ac96f8911c4b666 }}' => new Object_(),
+ ],
+ ),
+ $functions['\bar()']->getArguments()[0]->getDefault(false)
+ );
+ }
}
diff --git a/tests/integration/TypedConstantTest.php b/tests/integration/TypedConstantTest.php
new file mode 100644
index 00000000..f4575749
--- /dev/null
+++ b/tests/integration/TypedConstantTest.php
@@ -0,0 +1,34 @@
+create('My project', [new LocalFile($file)]);
+
+ $class = $project->getFiles()[$file]->getClasses()['\PHP83\TypedConstants'];
+ $constants = $class->getConstants();
+
+ $this->assertEquals(new String_(), $constants['\PHP83\TypedConstants::NAME']->getType());
+ $this->assertEquals(new Integer(), $constants['\PHP83\TypedConstants::COUNT']->getType());
+ $this->assertEquals(new Compound([new String_(), new Integer()]), $constants['\PHP83\TypedConstants::UNION']->getType());
+ $this->assertEquals(new Nullable(new String_()), $constants['\PHP83\TypedConstants::NULLABLE']->getType());
+ $this->assertNull($constants['\PHP83\TypedConstants::UNTYPED']->getType());
+ }
+}
diff --git a/tests/integration/data/GlobalFiles/function_constant_default.php b/tests/integration/data/GlobalFiles/function_constant_default.php
new file mode 100644
index 00000000..685a0d03
--- /dev/null
+++ b/tests/integration/data/GlobalFiles/function_constant_default.php
@@ -0,0 +1,7 @@
+fixture->getVisibility());
}
+ public function testGetTypeReturnsNullByDefault(): void
+ {
+ self::assertNull($this->fixture->getType());
+ }
+
+ public function testGetTypeReturnsTypeWhenProvided(): void
+ {
+ $type = new String_();
+ $fixture = new Constant(
+ $this->fqsen,
+ $this->docBlock,
+ new Expression($this->value),
+ null,
+ null,
+ null,
+ false,
+ $type,
+ );
+
+ self::assertSame($type, $fixture->getType());
+ }
+
public function testLineAndColumnNumberIsReturnedWhenALocationIsProvided(): void
{
$fixture = new Constant($this->fqsen, $this->docBlock, null, new Location(100, 20), new Location(101, 20));
diff --git a/tests/unit/phpDocumentor/Reflection/Php/Factory/ClassConstantIteratorTest.php b/tests/unit/phpDocumentor/Reflection/Php/Factory/ClassConstantIteratorTest.php
index 61f5cf7c..e83c4d7f 100644
--- a/tests/unit/phpDocumentor/Reflection/Php/Factory/ClassConstantIteratorTest.php
+++ b/tests/unit/phpDocumentor/Reflection/Php/Factory/ClassConstantIteratorTest.php
@@ -19,6 +19,8 @@
use PhpParser\Comment\Doc;
use PhpParser\Node\Const_;
use PhpParser\Node\Expr\Variable;
+use PhpParser\Node\Identifier;
+use PhpParser\Node\Scalar\String_;
use PhpParser\Node\Stmt\ClassConst;
use PHPUnit\Framework\Attributes\CoversClass;
@@ -78,6 +80,31 @@ public function testGetDocCommentPropFirst(): void
$this->assertEquals('test', $fixture->getDocComment()->getText());
}
+ public function testGetTypeReturnsNullWhenUntyped(): void
+ {
+ $const = new Const_('\Space\MyClass::MY_CONST1', new String_('a'));
+ $const->setAttribute('fqsen', new Fqsen((string) $const->name));
+
+ $classConstantNode = new ClassConst([$const]);
+
+ $fixture = new ClassConstantIterator($classConstantNode);
+
+ $this->assertNull($fixture->getType());
+ }
+
+ public function testGetTypeReturnsTypeWhenTyped(): void
+ {
+ $const = new Const_('\Space\MyClass::MY_CONST1', new String_('a'));
+ $const->setAttribute('fqsen', new Fqsen((string) $const->name));
+
+ $classConstantNode = new ClassConst([$const], 0, [], [], new Identifier('string'));
+
+ $fixture = new ClassConstantIterator($classConstantNode);
+
+ $this->assertInstanceOf(Identifier::class, $fixture->getType());
+ $this->assertEquals('string', $fixture->getType()->toString());
+ }
+
public function testGetDocComment(): void
{
$const = m::mock(Const_::class);
diff --git a/tests/unit/phpDocumentor/Reflection/Php/Factory/ClassConstantTest.php b/tests/unit/phpDocumentor/Reflection/Php/Factory/ClassConstantTest.php
index dec052dc..b0388675 100644
--- a/tests/unit/phpDocumentor/Reflection/Php/Factory/ClassConstantTest.php
+++ b/tests/unit/phpDocumentor/Reflection/Php/Factory/ClassConstantTest.php
@@ -24,8 +24,10 @@
use phpDocumentor\Reflection\Php\ProjectFactoryStrategies;
use phpDocumentor\Reflection\Php\Trait_ as TraitElement;
use phpDocumentor\Reflection\Types\Null_;
+use phpDocumentor\Reflection\Types\String_ as StringType;
use PhpParser\Comment\Doc;
use PhpParser\Node\Const_;
+use PhpParser\Node\Identifier;
use PhpParser\Node\Scalar\String_;
use PhpParser\Node\Stmt\Class_ as ClassNode;
use PhpParser\Node\Stmt\ClassConst;
@@ -138,6 +140,29 @@ public function testCreateForEnum(): void
self::assertInstanceOf(ConstantDescriptor::class, current($result->getConstants()));
}
+ public function testCreateWithTypedConstant(): void
+ {
+ $const = new Const_('\Space\MyClass::MY_CONST1', new String_('a'));
+ $const->setAttribute('fqsen', new Fqsen((string) $const->name));
+ $constantStub = new ClassConst([$const], ClassNode::MODIFIER_PUBLIC, [], [], new Identifier('string'));
+
+ $class = $this->performCreate($constantStub);
+
+ $constant = current($class->getConstants());
+ $this->assertInstanceOf(ConstantDescriptor::class, $constant);
+ $this->assertEquals(new StringType(), $constant->getType());
+ }
+
+ public function testCreateWithUntypedConstantHasNullType(): void
+ {
+ $constantStub = $this->buildConstantIteratorStub();
+
+ $class = $this->performCreate($constantStub);
+
+ $constant = current($class->getConstants());
+ $this->assertNull($constant->getType());
+ }
+
public function testCreateWithDocBlock(): void
{
$doc = new Doc('text');
diff --git a/tests/unit/phpDocumentor/Reflection/Php/Factory/FileTest.php b/tests/unit/phpDocumentor/Reflection/Php/Factory/FileTest.php
index 7e7fdd94..aa0299bb 100644
--- a/tests/unit/phpDocumentor/Reflection/Php/Factory/FileTest.php
+++ b/tests/unit/phpDocumentor/Reflection/Php/Factory/FileTest.php
@@ -106,7 +106,7 @@ public function testMiddlewareIsChecked(): void
public function testFileGetsCommentFromFirstNode(Node $node, DocBlockDescriptor $docblock): void
{
$this->nodesFactoryMock->create(file_get_contents(__FILE__))->willReturn([$node]);
- $this->docBlockFactory->create('Text', null)->willReturn($docblock);
+ $this->docBlockFactory->create('Text', Argument::any())->willReturn($docblock);
$strategies = $this->prophesize(StrategyContainer::class);
$strategies->findMatching(Argument::type(ContextStack::class), $node)->willReturn(