Skip to content

Commit

Permalink
Merge pull request #868 from cakephp/codegen-utility
Browse files Browse the repository at this point in the history
Move duplicate import functions into ImportHelper
  • Loading branch information
othercorey authored Sep 19, 2022
2 parents 5f35ac8 + 1d11205 commit fc7440b
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 91 deletions.
64 changes: 3 additions & 61 deletions src/CodeGen/FileBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ public function classBuilder(): ClassBuilder
*/
public function getClassImports(array $imports = []): array
{
return $this->mergeFileImports($this->normalizeImports($imports), $this->parsedFile->classImports ?? []);
return ImportHelper::merge($imports, $this->parsedFile->classImports ?? [], $this->io);
}

/**
Expand All @@ -98,7 +98,7 @@ public function getClassImports(array $imports = []): array
*/
public function getFunctionImports(array $imports = []): array
{
return $this->mergeFileImports($this->normalizeImports($imports), $this->parsedFile->functionImports ?? []);
return ImportHelper::merge($imports, $this->parsedFile->functionImports ?? [], $this->io);
}

/**
Expand All @@ -109,64 +109,6 @@ public function getFunctionImports(array $imports = []): array
*/
public function getConstImports(array $imports = []): array
{
return $this->mergeFileImports($this->normalizeImports($imports), $this->parsedFile->constImports ?? []);
}

/**
* Normalizes imports included from generated code into [alias => name] format.
*
* @param array<string|int, string> $imports Imports
* @return array<string, string>
*/
protected function normalizeImports(array $imports): array
{
$normalized = [];
foreach ($imports as $alias => $class) {
if (is_int($alias)) {
$last = strrpos($class, '\\', -1);
if ($last !== false) {
$alias = substr($class, strrpos($class, '\\', -1) + 1);
} else {
$alias = $class;
}
}

$normalized[$alias] = $class;
}

return $normalized;
}

/**
* @param array<string, string> $imports Imports
* @param array<string, string> $fileImports File imports to merge
* @return array<string, string>
*/
protected function mergeFileImports(array $imports, array $fileImports): array
{
foreach ($fileImports as $alias => $class) {
if (isset($imports[$alias]) && $imports[$alias] !== $class) {
$this->io->warning(sprintf(
'File import `%s` conflicts with generated import, discarding',
$class
));
continue;
}

$existingAlias = array_search($class, $imports, true);
if ($existingAlias !== false && $existingAlias != $alias) {
$this->io->warning(sprintf(
'File import `%s` conflicts with generated import, discarding',
$class
));
continue;
}

$imports[$alias] = $class;
}

asort($imports, SORT_STRING | SORT_FLAG_CASE);

return $imports;
return ImportHelper::merge($imports, $this->parsedFile->constImports ?? [], $this->io);
}
}
88 changes: 88 additions & 0 deletions src/CodeGen/ImportHelper.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
<?php
declare(strict_types=1);

/**
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @since 2.8.0
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
namespace Bake\CodeGen;

use Cake\Console\ConsoleIo;

class ImportHelper
{
/**
* Normalizes imports included from generated code into [alias => name] format.
*
* @param array<string|int, string> $imports Imports
* @return array<string, string>
*/
public static function normalize(array $imports): array
{
$normalized = [];
foreach ($imports as $alias => $class) {
if (is_int($alias)) {
$last = strrpos($class, '\\', -1);
if ($last !== false) {
$alias = substr($class, strrpos($class, '\\', -1) + 1);
} else {
$alias = $class;
}
}

$normalized[$alias] = $class;
}

return $normalized;
}

/**
* Merges imports allowing for duplicates and collisions.
*
* @param array<string|int, string> $existing Existing imports to merge into
* @param array<string|int, string> $imports Imports to merge into existing
* @param \Cake\Console\ConsoleIo|null $io Used to output warnings on collisions
* @return array<string, string>
*/
public static function merge(array $existing, array $imports, ?ConsoleIo $io = null): array
{
$existing = static::normalize($existing);
foreach (static::normalize($imports) as $alias => $class) {
if (isset($existing[$alias]) && $existing[$alias] !== $class) {
if ($io) {
$io->warning(sprintf(
'Import `%s` conflicts with existing import, discarding.',
$class
));
}
continue;
}

$existingAlias = array_search($class, $existing, true);
if ($existingAlias !== false && $existingAlias != $alias) {
if ($io) {
$io->warning(sprintf(
'Import `%s` conflicts with existing import, discarding.',
$class
));
}
continue;
}

$existing[$alias] = $class;
}

asort($existing, SORT_STRING | SORT_FLAG_CASE);

return $existing;
}
}
32 changes: 4 additions & 28 deletions src/View/Helper/BakeHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

namespace Bake\View\Helper;

use Bake\CodeGen\ImportHelper;
use Bake\Utility\Model\AssociationFilter;
use Brick\VarExporter\VarExporter;
use Cake\Core\Configure;
Expand Down Expand Up @@ -466,7 +467,7 @@ public function getClassUses(array $imports): string
{
$uses = [];

$imports = $this->normalizeImports($imports);
$imports = ImportHelper::normalize($imports);
asort($imports, SORT_STRING | SORT_FLAG_CASE);
foreach ($imports as $alias => $type) {
$uses[] = 'use ' . $this->getUseType($alias, $type) . ';';
Expand All @@ -485,7 +486,7 @@ public function getFunctionUses(array $imports): string
{
$uses = [];

$imports = $this->normalizeImports($imports);
$imports = ImportHelper::normalize($imports);
asort($imports, SORT_STRING | SORT_FLAG_CASE);
foreach ($imports as $alias => $type) {
$uses[] = 'use function ' . $this->getUseType($alias, $type) . ';';
Expand All @@ -504,7 +505,7 @@ public function getConstUses(array $imports): string
{
$uses = [];

$imports = $this->normalizeImports($imports);
$imports = ImportHelper::normalize($imports);
asort($imports, SORT_STRING | SORT_FLAG_CASE);
foreach ($imports as $alias => $type) {
$uses[] = 'use const ' . $this->getUseType($alias, $type) . ';';
Expand All @@ -513,31 +514,6 @@ public function getConstUses(array $imports): string
return implode("\n", $uses);
}

/**
* Normalizes imports included from generated code into [alias => name] format.
*
* @param array<string|int, string> $imports Imports
* @return array<string, string>
*/
protected function normalizeImports(array $imports): array
{
$normalized = [];
foreach ($imports as $alias => $class) {
if (is_int($alias)) {
$last = strrpos($class, '\\', -1);
if ($last !== false) {
$alias = substr($class, strrpos($class, '\\', -1) + 1);
} else {
$alias = $class;
}
}

$normalized[$alias] = $class;
}

return $normalized;
}

/**
* Gets use type string from name and alias.
*
Expand Down
4 changes: 2 additions & 2 deletions tests/TestCase/CodeGen/FileBuilderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ class TestTable{}
$builder = new FileBuilder($this->io, 'MyApp\Model', $file);

$builder->getClassImports(['Cake\ORM\Query']);
$this->assertThat('File import `Cake\ORM\Query` conflicts with generated import, discarding', new ContentsContain($this->out->messages(), 'output'));
$this->assertThat('Import `Cake\ORM\Query` conflicts with existing import, discarding', new ContentsContain($this->out->messages(), 'output'));
}

public function testImportConflictUserAlias(): void
Expand All @@ -170,6 +170,6 @@ class TestTable{}
$builder = new FileBuilder($this->io, 'MyApp\Model', $file);

$builder->getClassImports(['Cake\ORM\Query']);
$this->assertThat('File import `MyApp\Query` conflicts with generated import, discarding', new ContentsContain($this->out->messages(), 'output'));
$this->assertThat('Import `MyApp\Query` conflicts with existing import, discarding', new ContentsContain($this->out->messages(), 'output'));
}
}

0 comments on commit fc7440b

Please sign in to comment.