Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor all compilers to work on a DocumentationSet #3492

Merged
merged 3 commits into from
Mar 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions config/stages.yaml
@@ -1,6 +1,7 @@
parameters:
linker.substitutions:
'phpDocumentor\Descriptor\ProjectDescriptor': ['files']
'phpDocumentor\Descriptor\ApiSetDescriptor': ['files']
'phpDocumentor\Descriptor\FileDescriptor':
- 'tags'
- 'classes'
Expand Down
6 changes: 3 additions & 3 deletions src/phpDocumentor/Compiler/CompilerPassInterface.php
Expand Up @@ -13,7 +13,7 @@

namespace phpDocumentor\Compiler;

use phpDocumentor\Descriptor\Interfaces\ProjectInterface;
use phpDocumentor\Descriptor\DocumentationSetDescriptor;

/**
* Represents a single pass / business rule to be executed by the Compiler.
Expand All @@ -34,7 +34,7 @@ public function getDescription(): string;
* This method will execute the business logic associated with a given compiler pass and allow it to manipulate
* or consumer the Object Graph using the ProjectDescriptor object.
*
* @param ProjectInterface $project Representation of the Object Graph that can be manipulated.
* @param DocumentationSetDescriptor $documentationSet Representation of the Object Graph that can be manipulated.
*/
public function __invoke(ProjectInterface $project): ProjectInterface;
public function __invoke(DocumentationSetDescriptor $documentationSet): DocumentationSetDescriptor;
}
14 changes: 7 additions & 7 deletions src/phpDocumentor/Compiler/Linker/Linker.php
Expand Up @@ -18,10 +18,10 @@
use phpDocumentor\Descriptor\Collection;
use phpDocumentor\Descriptor\Descriptor;
use phpDocumentor\Descriptor\DescriptorAbstract;
use phpDocumentor\Descriptor\DocumentationSetDescriptor;
use phpDocumentor\Descriptor\FileDescriptor;
use phpDocumentor\Descriptor\InterfaceDescriptor;
use phpDocumentor\Descriptor\Interfaces\EnumInterface;
use phpDocumentor\Descriptor\Interfaces\ProjectInterface;
use phpDocumentor\Descriptor\NamespaceDescriptor;
use phpDocumentor\Descriptor\TraitDescriptor;
use phpDocumentor\Reflection\Fqsen;
Expand Down Expand Up @@ -81,12 +81,12 @@ public function __construct(array $substitutions, DescriptorRepository $descript
$this->descriptorRepository = $descriptorRepository;
}

public function __invoke(ProjectInterface $project): ProjectInterface
public function __invoke(DocumentationSetDescriptor $documentationSet): DocumentationSetDescriptor
{
$this->descriptorRepository->setObjectAliasesList($project->getIndexes()->get('elements')->getAll());
$this->substitute($project);
$this->descriptorRepository->setObjectAliasesList($documentationSet->getIndexes()->get('elements')->getAll());
$this->substitute($documentationSet);

return $project;
return $documentationSet;
}

/**
Expand Down Expand Up @@ -124,9 +124,9 @@ public function getSubstitutions(): array
* This method will return null if no substitution was possible and all of the above should not update the parent
* item when null is passed.
*
* @param string|Fqsen|Type|Collection<mixed>|array<mixed>|Descriptor|ProjectInterface $item
* @param string|Fqsen|Type|Collection<mixed>|array<mixed>|Descriptor|DocumentationSetDescriptor $item
*
* @return string|ProjectInterface|DescriptorAbstract|Collection<string|DescriptorAbstract>|array<string|DescriptorAbstract>|null
* @return string|DocumentationSetDescriptor|DescriptorAbstract|Collection<string|DescriptorAbstract>|array<string|DescriptorAbstract>|null
*/
public function substitute($item, ?DescriptorAbstract $container = null)
{
Expand Down
8 changes: 4 additions & 4 deletions src/phpDocumentor/Compiler/Pass/Debug.php
Expand Up @@ -14,7 +14,7 @@
namespace phpDocumentor\Compiler\Pass;

use phpDocumentor\Compiler\CompilerPassInterface;
use phpDocumentor\Descriptor\Interfaces\ProjectInterface;
use phpDocumentor\Descriptor\DocumentationSetDescriptor;
use phpDocumentor\Descriptor\ProjectAnalyzer;
use Psr\Log\LoggerInterface;

Expand Down Expand Up @@ -48,11 +48,11 @@ public function getDescription(): string
return 'Analyze results and write report to log';
}

public function __invoke(ProjectInterface $project): ProjectInterface
public function __invoke(DocumentationSetDescriptor $documentationSet): DocumentationSetDescriptor
{
$this->analyzer->analyze($project);
$this->analyzer->analyze($documentationSet);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should only run on apiSet?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The analyzer itself does varying things depending on the type of documentation set

$this->log->debug((string) $this->analyzer);

return $project;
return $documentationSet;
}
}
27 changes: 16 additions & 11 deletions src/phpDocumentor/Compiler/Pass/ElementsIndexBuilder.php
Expand Up @@ -14,12 +14,13 @@
namespace phpDocumentor\Compiler\Pass;

use phpDocumentor\Compiler\CompilerPassInterface;
use phpDocumentor\Descriptor\ApiSetDescriptor;
use phpDocumentor\Descriptor\Collection;
use phpDocumentor\Descriptor\DocumentationSetDescriptor;
use phpDocumentor\Descriptor\Interfaces\ClassInterface;
use phpDocumentor\Descriptor\Interfaces\ElementInterface;
use phpDocumentor\Descriptor\Interfaces\EnumInterface;
use phpDocumentor\Descriptor\Interfaces\InterfaceInterface;
use phpDocumentor\Descriptor\Interfaces\ProjectInterface;
use phpDocumentor\Descriptor\Interfaces\TraitInterface;

use function array_merge;
Expand All @@ -40,19 +41,23 @@ public function getDescription(): string
return 'Build "elements" index';
}

public function __invoke(ProjectInterface $project): ProjectInterface
public function __invoke(DocumentationSetDescriptor $documentationSet): DocumentationSetDescriptor
{
$elementCollection = new Collection();
$project->getIndexes()->set('elements', $elementCollection);
$documentationSet->getIndexes()->set('elements', $elementCollection);

$constantsIndex = $project->getIndexes()->fetch('constants', new Collection());
$functionsIndex = $project->getIndexes()->fetch('functions', new Collection());
$classesIndex = $project->getIndexes()->fetch('classes', new Collection());
$interfacesIndex = $project->getIndexes()->fetch('interfaces', new Collection());
$traitsIndex = $project->getIndexes()->fetch('traits', new Collection());
$enumsIndex = $project->getIndexes()->fetch('enums', new Collection());
if ($documentationSet instanceof ApiSetDescriptor === false) {
return $documentationSet;
}

$constantsIndex = $documentationSet->getIndexes()->fetch('constants', new Collection());
$functionsIndex = $documentationSet->getIndexes()->fetch('functions', new Collection());
$classesIndex = $documentationSet->getIndexes()->fetch('classes', new Collection());
$interfacesIndex = $documentationSet->getIndexes()->fetch('interfaces', new Collection());
$traitsIndex = $documentationSet->getIndexes()->fetch('traits', new Collection());
$enumsIndex = $documentationSet->getIndexes()->fetch('enums', new Collection());

foreach ($project->getFiles() as $file) {
foreach ($documentationSet->getFiles() as $file) {
$this->addElementsToIndexes($file->getConstants()->getAll(), [$constantsIndex, $elementCollection]);
$this->addElementsToIndexes($file->getFunctions()->getAll(), [$functionsIndex, $elementCollection]);

Expand All @@ -77,7 +82,7 @@ public function __invoke(ProjectInterface $project): ProjectInterface
}
}

return $project;
return $documentationSet;
}

/**
Expand Down
39 changes: 17 additions & 22 deletions src/phpDocumentor/Compiler/Pass/GuidesCompiler.php
Expand Up @@ -5,9 +5,9 @@
namespace phpDocumentor\Compiler\Pass;

use phpDocumentor\Compiler\CompilerPassInterface;
use phpDocumentor\Descriptor\DocumentationSetDescriptor;
use phpDocumentor\Descriptor\DocumentDescriptor;
use phpDocumentor\Descriptor\GuideSetDescriptor;
use phpDocumentor\Descriptor\Interfaces\ProjectInterface;
use phpDocumentor\Guides\Compiler\Compiler;
use phpDocumentor\Guides\Metas;

Expand All @@ -29,29 +29,24 @@ public function getDescription(): string
return 'Compiling guides';
}

public function __invoke(ProjectInterface $project): ProjectInterface
public function __invoke(DocumentationSetDescriptor $documentationSet): DocumentationSetDescriptor
{
foreach ($project->getVersions() as $version) {
foreach ($version->getDocumentationSets() as $documentationSet) {
if (!($documentationSet instanceof GuideSetDescriptor)) {
continue;
}

// $this->metas->setMetaEntries([]);
$documents = $this->compiler->run(
array_map(
static fn (DocumentDescriptor $descriptor) => $descriptor->getDocumentNode(),
$documentationSet->getDocuments()->getAll()
)
);
foreach ($documents as $document) {
$documentationSet->getDocuments()->get($document->getFilePath())->setDocumentNode($document);
}

$documentationSet->setMetas(new Metas($this->metas->getAll()));
}
if ($documentationSet instanceof GuideSetDescriptor === false) {
return $documentationSet;
}

return $project;
$documents = $this->compiler->run(
array_map(
static fn (DocumentDescriptor $descriptor) => $descriptor->getDocumentNode(),
$documentationSet->getDocuments()->getAll()
)
);
foreach ($documents as $document) {
$documentationSet->getDocuments()->get($document->getFilePath())->setDocumentNode($document);
}

$documentationSet->setMetas(new Metas($this->metas->getAll()));

return $documentationSet;
}
}
8 changes: 4 additions & 4 deletions src/phpDocumentor/Compiler/Pass/MarkerFromTagsExtractor.php
Expand Up @@ -16,8 +16,8 @@
use phpDocumentor\Compiler\CompilerPassInterface;
use phpDocumentor\Descriptor\Collection;
use phpDocumentor\Descriptor\DescriptorAbstract;
use phpDocumentor\Descriptor\DocumentationSetDescriptor;
use phpDocumentor\Descriptor\FileDescriptor;
use phpDocumentor\Descriptor\Interfaces\ProjectInterface;
use phpDocumentor\Descriptor\TagDescriptor;
use UnexpectedValueException;

Expand All @@ -33,10 +33,10 @@ public function getDescription(): string
return 'Collect all markers embedded in tags';
}

public function __invoke(ProjectInterface $project): ProjectInterface
public function __invoke(DocumentationSetDescriptor $documentationSet): DocumentationSetDescriptor
{
/** @var DescriptorAbstract $element */
foreach ($project->getIndexes()->fetch('elements', new Collection()) as $element) {
foreach ($documentationSet->getIndexes()->fetch('elements', new Collection()) as $element) {
/** @var TagDescriptor[] $todos */
$todos = $element->getTags()->fetch('todo');

Expand All @@ -50,7 +50,7 @@ public function __invoke(ProjectInterface $project): ProjectInterface
}
}

return $project;
return $documentationSet;
}

/**
Expand Down
66 changes: 40 additions & 26 deletions src/phpDocumentor/Compiler/Pass/NamespaceTreeBuilder.php
Expand Up @@ -15,10 +15,11 @@

use InvalidArgumentException;
use phpDocumentor\Compiler\CompilerPassInterface;
use phpDocumentor\Descriptor\ApiSetDescriptor;
use phpDocumentor\Descriptor\Collection;
use phpDocumentor\Descriptor\DocumentationSetDescriptor;
use phpDocumentor\Descriptor\Interfaces\ElementInterface;
use phpDocumentor\Descriptor\Interfaces\NamespaceInterface;
use phpDocumentor\Descriptor\Interfaces\ProjectInterface;
use phpDocumentor\Descriptor\NamespaceDescriptor;
use phpDocumentor\Reflection\Fqsen;
use Webmozart\Assert\Assert;
Expand Down Expand Up @@ -46,30 +47,38 @@ public function getDescription(): string
return 'Build "namespaces" index and add namespaces to "elements"';
}

public function __invoke(ProjectInterface $project): ProjectInterface
public function __invoke(DocumentationSetDescriptor $documentationSet): DocumentationSetDescriptor
{
$project->getIndexes()->fetch('elements', new Collection())->set('~\\', $project->getNamespace());
$project->getIndexes()->fetch('namespaces', new Collection())->set('\\', $project->getNamespace());

foreach ($project->getFiles() as $file) {
$this->addElementsOfTypeToNamespace($project, $file->getConstants()->getAll(), 'constants');
$this->addElementsOfTypeToNamespace($project, $file->getFunctions()->getAll(), 'functions');
$this->addElementsOfTypeToNamespace($project, $file->getClasses()->getAll(), 'classes');
$this->addElementsOfTypeToNamespace($project, $file->getInterfaces()->getAll(), 'interfaces');
$this->addElementsOfTypeToNamespace($project, $file->getTraits()->getAll(), 'traits');
$this->addElementsOfTypeToNamespace($project, $file->getEnums()->getAll(), 'enums');
if ($documentationSet instanceof ApiSetDescriptor === false) {
return $documentationSet;
}

$documentationSet->getIndexes()
->fetch('elements', new Collection())
->set('~\\', $documentationSet->getNamespace());
$documentationSet->getIndexes()
->fetch('namespaces', new Collection())
->set('\\', $documentationSet->getNamespace());

foreach ($documentationSet->getFiles() as $file) {
$this->addElementsOfTypeToNamespace($documentationSet, $file->getConstants()->getAll(), 'constants');
$this->addElementsOfTypeToNamespace($documentationSet, $file->getFunctions()->getAll(), 'functions');
$this->addElementsOfTypeToNamespace($documentationSet, $file->getClasses()->getAll(), 'classes');
$this->addElementsOfTypeToNamespace($documentationSet, $file->getInterfaces()->getAll(), 'interfaces');
$this->addElementsOfTypeToNamespace($documentationSet, $file->getTraits()->getAll(), 'traits');
$this->addElementsOfTypeToNamespace($documentationSet, $file->getEnums()->getAll(), 'enums');
}

/** @var NamespaceInterface $namespace */
foreach ($project->getIndexes()->get('namespaces')->getAll() as $namespace) {
foreach ($documentationSet->getIndexes()->get('namespaces')->getAll() as $namespace) {
if ($namespace->getNamespace() === '') {
continue;
}

$this->addToParentNamespace($project, $namespace);
$this->addToParentNamespace($documentationSet, $namespace);
}

return $project;
return $documentationSet;
}

/**
Expand All @@ -83,16 +92,19 @@ public function __invoke(ProjectInterface $project): ProjectInterface
* This name will be transformed to a getter which must exist. Out of performance considerations will no effort
* be done to verify whether the provided type is valid.
*/
protected function addElementsOfTypeToNamespace(ProjectInterface $project, array $elements, string $type): void
{
protected function addElementsOfTypeToNamespace(
DocumentationSetDescriptor $documentationSet,
array $elements,
string $type
): void {
foreach ($elements as $element) {
$namespaceName = (string) $element->getNamespace();
//TODO: find out why this can happen. Some bug in the assembler?
if ($namespaceName === '') {
$namespaceName = '\\';
}

$namespace = $project->getIndexes()->fetch('namespaces', new Collection())->fetch($namespaceName);
$namespace = $documentationSet->getIndexes()->fetch('namespaces', new Collection())->fetch($namespaceName);

if ($namespace === null) {
$namespace = new NamespaceDescriptor();
Expand All @@ -101,10 +113,10 @@ protected function addElementsOfTypeToNamespace(ProjectInterface $project, array
$namespace->setFullyQualifiedStructuralElementName($fqsen);
$namespaceName = substr((string) $fqsen, 0, -strlen($fqsen->getName()) - 1);
$namespace->setNamespace($namespaceName);
$project->getIndexes()
$documentationSet->getIndexes()
->fetch('namespaces', new Collection())
->set((string) $namespace->getFullyQualifiedStructuralElementName(), $namespace);
$this->addToParentNamespace($project, $namespace);
$this->addToParentNamespace($documentationSet, $namespace);
}

Assert::isInstanceOf($namespace, NamespaceInterface::class);
Expand All @@ -121,14 +133,16 @@ protected function addElementsOfTypeToNamespace(ProjectInterface $project, array
}
}

private function addToParentNamespace(ProjectInterface $project, NamespaceInterface $namespace): void
{
private function addToParentNamespace(
DocumentationSetDescriptor $documentationSet,
NamespaceInterface $namespace
): void {
/** @var NamespaceInterface|null $parent */
$parent = $project->getIndexes()->fetch(
$parent = $documentationSet->getIndexes()->fetch(
'namespaces',
new Collection()
)->fetch((string) $namespace->getNamespace());
$project->getIndexes()->fetch('elements', new Collection())->set(
$documentationSet->getIndexes()->fetch('elements', new Collection())->set(
'~' . (string) $namespace->getFullyQualifiedStructuralElementName(),
$namespace
);
Expand All @@ -141,10 +155,10 @@ private function addToParentNamespace(ProjectInterface $project, NamespaceInterf
$parent->setName($fqsen->getName());
$namespaceName = substr((string) $fqsen, 0, -strlen($parent->getName()) - 1);
$parent->setNamespace($namespaceName === '' ? '\\' : $namespaceName);
$project->getIndexes()
$documentationSet->getIndexes()
->fetch('namespaces', new Collection())
->set((string) $parent->getFullyQualifiedStructuralElementName(), $parent);
$this->addToParentNamespace($project, $parent);
$this->addToParentNamespace($documentationSet, $parent);
}

$namespace->setParent($parent);
Expand Down