Skip to content

Commit

Permalink
refactoring import system to suck a little less
Browse files Browse the repository at this point in the history
  • Loading branch information
dcarbone committed Jan 5, 2025
1 parent 6b77430 commit 0d98ebd
Show file tree
Hide file tree
Showing 28 changed files with 557 additions and 439 deletions.
2 changes: 1 addition & 1 deletion files/constants.php
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@

// Core exceptions
const PHPFHIR_EXCEPTION_CLIENT_ABSTRACT_CLIENT = 'AbstractClientException';
const PHPFHIR_EXCEPTION_CLIENT_NETWORK_ERROR = 'ClientErrorException';
const PHPFHIR_EXCEPTION_CLIENT_ERROR = 'ClientErrorException';
const PHPFHIR_EXCEPTION_CLIENT_UNEXPECTED_RESPONSE_CODE = 'UnexpectedResponseCodeException';

// Core client entities
Expand Down
54 changes: 23 additions & 31 deletions src/Version/Definition/TypeImport.php → src/Builder/Import.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php declare(strict_types=1);

namespace DCarbone\PHPFHIR\Version\Definition;
namespace DCarbone\PHPFHIR\Builder;

/*
* Copyright 2016-2024 Daniel Carbone ([email protected])
Expand All @@ -18,73 +18,65 @@
* limitations under the License.
*/

/**
* Class TypeImport
* @package DCarbone\PHPFHIR\Definition
*/
class TypeImport
class Import
{
/** @var string */
private string $classname;
private string $_classname;
/** @var string */
private string $namespace;
private string $_namespace;
/** @var string */
private string $fqcn;
/** @var bool */
private bool $aliased;
private string $_fqn;
/** @var string */
private string $aliasName;
private string $_aliasName;
/** @var bool */
private bool $requiresImport;
private bool $_requiresImport;

/**
* TypeImport constructor.
* @param string $classname
* @param string $namespace
* @param bool $aliased
* @param string $aliasName
* @param bool $requiresImport
*/
public function __construct(string $classname, string $namespace, bool $aliased, string $aliasName, bool $requiresImport)
public function __construct(string $classname, string $namespace, string $aliasName, bool $requiresImport)
{
$this->classname = $classname;
$this->namespace = $namespace;
$this->fqcn = ('' === $namespace ? $classname : "{$namespace}\\{$classname}");
$this->aliased = $aliased;
$this->aliasName = $aliasName;
$this->requiresImport = $requiresImport;
$this->_classname = $classname;
$this->_namespace = trim($namespace, PHPFHIR_NAMESPACE_SEPARATOR);
$this->_fqn = ('' === $this->_namespace ? $classname : "{$this->_namespace}\\{$classname}");
$this->_aliasName = $aliasName;
$this->_requiresImport = $requiresImport;
}

/**
* @return string
*/
public function getClassname(): string
{
return $this->classname;
return $this->_classname;
}

/**
* @return string
*/
public function getNamespace(): string
{
return $this->namespace;
return $this->_namespace;
}

/**
* @return bool
*/
public function isAliased(): bool
{
return $this->aliased;
return isset($this->_aliasName) && '' !== $this->_aliasName;
}

/**
* @return string
*/
public function getAliasName(): string
{
return $this->aliasName;
return $this->_aliasName;
}

/**
Expand All @@ -104,32 +96,32 @@ public function getImportedName(): string
*/
public function getFullyQualifiedNamespace(bool $leadingSlash): string
{
return $leadingSlash ? "\\{$this->namespace}" : $this->namespace;
return $leadingSlash ? "\\{$this->_namespace}" : $this->_namespace;
}

/**
* @param bool $leadingSlash
* @return string
*/
public function getFullyQualifiedClassname(bool $leadingSlash): string
public function getFullyQualifiedName(bool $leadingSlash): string
{
return $leadingSlash ? "\\{$this->fqcn}" : $this->fqcn;
return $leadingSlash ? "\\{$this->_fqn}" : $this->_fqn;
}

/**
* @return bool
*/
public function isRequiresImport(): bool
public function requiresImport(): bool
{
return $this->requiresImport;
return $this->_requiresImport;
}

/**
* @return string
*/
public function getUseStatement(): string
{
$use = "use {$this->getFullyQualifiedClassname(false)}";
$use = "use {$this->getFullyQualifiedName(false)}";
if ($this->isAliased()) {
$use .= " as {$this->getAliasName()}";
}
Expand Down
193 changes: 193 additions & 0 deletions src/Builder/Imports.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
<?php declare(strict_types=1);

namespace DCarbone\PHPFHIR\Builder;

/*
* Copyright 2016-2024 Daniel Carbone ([email protected])
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

use DCarbone\PHPFHIR\Config;
use DCarbone\PHPFHIR\Enum\TypeKindEnum;
use DCarbone\PHPFHIR\Version\Definition\Type;

class Imports implements \Countable
{
/** @var \DCarbone\PHPFHIR\Config */
private Config $_config;
/** @var string */
private string $_localNamespace;
/** @var string */
private string $_localName;

/** @var \DCarbone\PHPFHIR\Builder\Import[] */
private array $_imports = [];

/** @var int */
private int $_requiredImportCount = 0;

/**
* @param \DCarbone\PHPFHIR\Config $config
* @param string $localNamespace Fully qualified namespace of local entity
* @param string $localName Name of local entity (class, interface, enum, trait, etc.)
*/
public function __construct(Config $config, string $localNamespace, string $localName)
{
$this->_config = $config;
$this->_localNamespace = trim($localNamespace, PHPFHIR_NAMESPACE_SEPARATOR);
$this->_localName = $localName;
}

/**
* @param string $namespace Namespace of referenced entity
* @param string $name Name of referenced entity
* @return \DCarbone\PHPFHIR\Builder\Imports
*/
public function addImport(string $namespace, string $name): self
{
// ensure clean namespace value
$namespace = trim($namespace, PHPFHIR_NAMESPACE_SEPARATOR);

// do not need to import sibling entities.
$requiresImport = ($namespace !== $this->_localNamespace);

if (isset($this->_imports[$name])) {
// if we have already seen this type, move on.
if ($this->_imports[$name]->getNamespace() === $namespace) {
return $this;
}
// if there is a conflicting imported type here...
$aliasName = $this->_findNextAliasName($name);
$this->_imports[$aliasName] = new Import($name, $namespace, $aliasName, $requiresImport);
} else if ($name === $this->_localName && $namespace != $this->_localNamespace) {
// if the referenced type has the same name but exists in a different namespace, alias it.
$aliasName = $this->_findNextAliasName($name);
$this->_imports[$aliasName] = new Import($name, $namespace, $aliasName, $requiresImport);
} else {
// otherwise, go ahead and add to map.
$this->_imports[$name] = new Import($name, $namespace, '', $requiresImport);
}

if ($requiresImport) {
$this->_requiredImportCount++;
}

uasort(
$this->_imports,
function (Import $a, Import $b) {
return strnatcasecmp($a->getFullyQualifiedName(false), $b->getFullyQualifiedName(false));
}
);

return $this;
}

public function addCoreFileImports(string ...$entityNames): self
{
foreach ($entityNames as $en) {
$coreFile = $this->_config->getCoreFiles()->getCoreFileByEntityName($en);
$this->addImport($coreFile->getFullyQualifiedNamespace(false), $coreFile->getEntityName());
}
return $this;
}

/**
* @return \DCarbone\PHPFHIR\Builder\Import[]
*/
public function getIterator(): iterable
{
return new \ArrayIterator($this->_imports);
}

/**
* @return \Generator<\DCarbone\PHPFHIR\Builder\Import>
*/
public function getGenerator(): \Generator
{
foreach ($this->_imports as $import) {
yield $import;
}
}

/**
* @return int
*/
public function requiredImportCount(): int
{
return $this->_requiredImportCount;
}

/**
* @param \DCarbone\PHPFHIR\Version\Definition\Type $type
* @return \DCarbone\PHPFHIR\Builder\Import|null
*/
public function getImportByType(Type $type): ?Import
{
$fqn = $type->getFullyQualifiedClassName(false);
foreach ($this->_imports as $import) {
if ($import->getFullyQualifiedName(false) === $fqn) {
return $import;
}
}
return null;
}

/**
* @param string $classname
* @param string $namespace
* @return \DCarbone\PHPFHIR\Builder\Import|null
*/
public function getImportByClassAndNamespace(string $classname, string $namespace): null|Import
{
foreach ($this->_imports as $import) {
if ($import->getNamespace() === $namespace && $import->getClassname() === $classname) {
return $import;
}
}
return null;
}

/**
* @param string $aliasName
* @return \DCarbone\PHPFHIR\Builder\Import|null
*/
public function getImportByAlias(string $aliasName): ?Import
{
return $this->_imports[$aliasName] ?? null;
}

/**
* @return int
*/
public function count(): int
{
return count($this->_imports);
}

/**
* TODO: come up with better alias scheme...
*
* @param string $classname
* @return string
*/
private function _findNextAliasName(string $classname): string
{
$i = 1;
$aliasName = "{$classname}{$i}";
while (null !== $this->getImportByAlias($aliasName)) {
$aliasName = "{$classname}{++$i}";
}
return $aliasName;
}
}
1 change: 1 addition & 0 deletions src/Config.php
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ public function __construct(array $params = [], null|LoggerInterface $logger = n
);

$this->_coreFiles = new CoreFiles(
$this,
$this->getOutputPath(),
PHPFHIR_TEMPLATE_CORE_DIR,
$this->getFullyQualifiedName(true),
Expand Down
Loading

0 comments on commit 0d98ebd

Please sign in to comment.