diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 336277f..29a5405 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -39,6 +39,7 @@ jobs: chmod +x box.phar ./box.phar compile -vv gpg -u montealegreluis@gmail.com --detach-sign --output phuml.phar.asc phuml.phar + ls -alh phuml* - name: "Upload binaries to distribute phUML via PHIVE" uses: "svenstaro/upload-release-action@v2" @@ -46,3 +47,4 @@ jobs: repo_token: ${{ secrets.GITHUB_TOKEN }} file: phuml.phar* tag: ${{ github.ref }} + file_glob: true diff --git a/.scrutinizer.yml b/.scrutinizer.yml index c20e035..d2bd928 100644 --- a/.scrutinizer.yml +++ b/.scrutinizer.yml @@ -20,5 +20,4 @@ build: tools: external_code_coverage: - timeout: 600 - runs: 3 + timeout: 1200 diff --git a/Makefile b/Makefile index 0f94b53..51f5340 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,6 @@ SHELL = /bin/bash ARGS="" -INFECTION_BADGE_API_KEY="" .PHONY: help help: ## Show help diff --git a/README.md b/README.md index 0c74a41..f40533a 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![CI workflow](https://github.com/montealegreluis/phuml/actions/workflows/ci.yml/badge.svg)](https://github.com/montealegreluis/phuml/actions/workflows/ci.yml) [![Scrutinizer Code Quality][scrutinizer-badge]][scrutinizer] [![Code Coverage][coverage-badge]][coverage] -[![Infection MSI](https://badge.stryker-mutator.io/github.com/montealegreluis/phuml/master)](https://dashboard.stryker-mutator.io/reports/github.com/montealegreluis/phuml/master) +[![Infection MSI](https://badge.stryker-mutator.io/github.com/MontealegreLuis/phuml/master)](https://dashboard.stryker-mutator.io/reports/github.com/MontealegreLuis/phuml/master) [![Latest Stable Version][stable-badge]][packagist] [![Minimum PHP Version](https://img.shields.io/badge/php-%3E%3D%208.0-8892BF.svg?style=flat-square)](https://php.net/) diff --git a/docs/installation.md b/docs/installation.md index 8aaa61b..c1d7a1b 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -1,5 +1,5 @@ --- -currentMenu: index +currentMenu: installation --- # Installation diff --git a/index.md b/index.md index 02620c8..1df89cc 100644 --- a/index.md +++ b/index.md @@ -3,7 +3,7 @@ ![CI workflow](https://github.com/montealegreluis/phuml/actions/workflows/ci.yml/badge.svg) [![Scrutinizer Code Quality][scrutinizer-badge]][scrutinizer] [![Code Coverage][coverage-badge]][coverage] -[![Infection MSI](https://badge.stryker-mutator.io/github.com/montealegreluis/phuml/master)](https://dashboard.stryker-mutator.io/reports/github.com/montealegreluis/phuml/master) +[![Infection MSI](https://badge.stryker-mutator.io/github.com/MontealegreLuis/phuml/master)](https://dashboard.stryker-mutator.io/reports/github.com/MontealegreLuis/phuml/master) [![Latest Stable Version][stable-badge]][packagist] [![Minimum PHP Version](https://img.shields.io/badge/php-%3E%3D%208.0-8892BF.svg?style=flat-square)](https://php.net/) diff --git a/src/Code/Name.php b/src/Code/Name.php index 7f59306..368b708 100644 --- a/src/Code/Name.php +++ b/src/Code/Name.php @@ -21,6 +21,11 @@ public function __construct(string $name) $this->parts = explode('\\', trim($name)); } + public function first(): string + { + return $this->parts[0]; + } + public function fullName(): string { return implode('\\', $this->parts); @@ -40,4 +45,10 @@ public function __toString(): string { return $this->parts[count($this->parts) - 1]; } + + public function packageName(): string + { + $package = array_slice($this->parts, 0, -1); + return implode('\\', $package); + } } diff --git a/src/Code/UseStatement.php b/src/Code/UseStatement.php index c4c2fc1..0ac4aeb 100644 --- a/src/Code/UseStatement.php +++ b/src/Code/UseStatement.php @@ -18,6 +18,11 @@ public function endsWith(Name $name): bool return str_ends_with(haystack: (string) $this->name, needle: $name->removeArraySuffix()); } + public function includes(Name $name): bool + { + return str_ends_with(haystack: (string) $this->name, needle: $name->first()); + } + public function isAliasedAs(Name $name): bool { return $this->alias !== null && (string) $this->alias === $name->removeArraySuffix(); @@ -25,6 +30,11 @@ public function isAliasedAs(Name $name): bool public function fullyQualifiedName(Name $name): string { - return $name->isArray() ? $this->name->fullName() . '[]' : $this->name->fullName(); + return $name->isArray() ? "{$this->name->fullName()}[]" : $this->name->fullName(); + } + + public function merge(Name $name): string + { + return "{$this->name->packageName()}\\{$name->fullName()}"; } } diff --git a/src/Code/UseStatements.php b/src/Code/UseStatements.php index 44a525e..4bfd394 100644 --- a/src/Code/UseStatements.php +++ b/src/Code/UseStatements.php @@ -20,6 +20,9 @@ public function fullyQualifiedNameFor(Name $name): string if ($useStatement->endsWith($name)) { return $useStatement->fullyQualifiedName($name); } + if ($useStatement->includes($name)) { + return $useStatement->merge($name); + } if ($useStatement->isAliasedAs($name)) { return $useStatement->fullyQualifiedName($name); } diff --git a/src/Parser/Code/Builders/TagType.php b/src/Parser/Code/Builders/TagType.php index f7240f4..cfbcbba 100644 --- a/src/Parser/Code/Builders/TagType.php +++ b/src/Parser/Code/Builders/TagType.php @@ -30,7 +30,7 @@ public static function named(string $type): TagType } /** @param string[] $types */ - public function __construct(private array $types, private bool $isNullable = false) + private function __construct(private array $types, private bool $isNullable = false) { } diff --git a/src/Parser/Code/Builders/TagTypeFactory.php b/src/Parser/Code/Builders/TagTypeFactory.php index 8945800..5352341 100644 --- a/src/Parser/Code/Builders/TagTypeFactory.php +++ b/src/Parser/Code/Builders/TagTypeFactory.php @@ -14,6 +14,7 @@ use phpDocumentor\Reflection\Type; use phpDocumentor\Reflection\Types\Compound; use phpDocumentor\Reflection\Types\Nullable; +use phpDocumentor\Reflection\Types\Object_; final class TagTypeFactory { @@ -88,7 +89,7 @@ private function resolveType(?Type $type): ?TagType $type === null => null, $type instanceof Nullable => TagType::nullable((string) $type->getActualType()), $type instanceof Compound => TagType::compound(array_map('strval', $type->getIterator()->getArrayCopy())), - default => TagType::named((string) $type) + default => TagType::named((string) ($type instanceof Object_ ? $type->getFqsen() : $type)) }; } } diff --git a/tests/unit/Parser/Code/Builders/TagTypeTest.php b/tests/unit/Parser/Code/Builders/TagTypeTest.php new file mode 100644 index 0000000..6ba1c3c --- /dev/null +++ b/tests/unit/Parser/Code/Builders/TagTypeTest.php @@ -0,0 +1,39 @@ +resolve($useStatements); + + $this->assertEquals(TypeDeclaration::from('PhpParser\Node\Param[]'), $type); + } + + /** @test */ + function it_resolves_fully_qualified_names_from_relative_names_with_multiple_prefix() + { + $useStatements = new UseStatements([new UseStatement(new Name('PhpParser\Node'), null)]); + $tagType = TagType::named('Node\Another\Param[]'); + + $type = $tagType->resolve($useStatements); + + $this->assertEquals(TypeDeclaration::from('PhpParser\Node\Another\Param[]'), $type); + } +}