Skip to content

Commit 0e283d9

Browse files
committed
PhpNamespace: improved collision checking between class and alias
1 parent 8a12f1d commit 0e283d9

File tree

7 files changed

+21
-23
lines changed

7 files changed

+21
-23
lines changed

src/PhpGenerator/PhpNamespace.php

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -102,32 +102,31 @@ public function addUse(string $name, string $alias = null): self
102102
}
103103

104104
$name = ltrim($name, '\\');
105-
if ($alias === null && $this->name === Helpers::extractNamespace($name)) {
106-
$alias = Helpers::extractShortName($name);
107-
}
108105
if ($alias === null) {
109106
$base = Helpers::extractShortName($name);
110107
$counter = null;
111108
do {
112109
$alias = $base . $counter;
113110
$counter++;
114-
} while (isset($this->aliases[$alias]) && $this->aliases[$alias] !== $name);
111+
} while ((isset($this->aliases[$alias]) && $this->aliases[$alias] !== $name) || isset($this->classes[$alias]));
115112

116113
} elseif (isset($this->aliases[$alias]) && $this->aliases[$alias] !== $name) {
117114
throw new InvalidStateException(
118115
"Alias '$alias' used already for '{$this->aliases[$alias]}', cannot use for '$name'."
119116
);
117+
} elseif (isset($this->classes[$alias])) {
118+
throw new Nette\InvalidStateException("Name '$alias' used already for '$this->name\\{$this->classes[$alias]->getName()}'.");
120119
}
121120

122121
$this->aliases[$alias] = $name;
123-
asort($this->aliases);
124122
return $this;
125123
}
126124

127125

128126
/** @return string[] */
129127
public function getUses(): array
130128
{
129+
asort($this->aliases);
131130
return $this->aliases;
132131
}
133132

@@ -175,8 +174,9 @@ public function add(ClassType $class): self
175174
$name = $class->getName();
176175
if ($name === null) {
177176
throw new Nette\InvalidArgumentException('Class does not have a name.');
177+
} elseif ($orig = $this->aliases[$name] ?? null) {
178+
throw new Nette\InvalidStateException("Name '$name' used already as alias for $orig.");
178179
}
179-
$this->addUse($this->name . '\\' . $name);
180180
$this->classes[$name] = $class;
181181
return $this;
182182
}

src/PhpGenerator/Printer.php

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -281,11 +281,9 @@ protected function printUses(PhpNamespace $namespace): string
281281
$name = $namespace->getName();
282282
$uses = [];
283283
foreach ($namespace->getUses() as $alias => $original) {
284-
if ($original !== ($name ? $name . '\\' . $alias : $alias)) {
285-
$uses[] = $alias === $original || substr($original, -(strlen($alias) + 1)) === '\\' . $alias
286-
? "use $original;"
287-
: "use $original as $alias;";
288-
}
284+
$uses[] = Helpers::extractShortName($original) === $alias
285+
? "use $original;"
286+
: "use $original as $alias;";
289287
}
290288
return implode("\n", $uses);
291289
}

tests/PhpGenerator/PhpFile.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ Assert::same(['Baz\\f2', 'f1'], array_keys($file->getFunctions()));
114114

115115

116116
$file = new PhpFile;
117-
$file->addClass('A');
117+
$file->addClass('CA');
118118
$file->addUse('A')
119119
->addUse('B', 'C');
120120

tests/PhpGenerator/PhpNamespace.aliases.phpt

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@ $namespace->addUse('Foo');
4444
Assert::same('B', $namespace->simplifyName('Foo\B'));
4545

4646
$namespace->addUse('Bar\C');
47-
Assert::same(['C' => 'Bar\C', 'Foo' => 'Foo'], $namespace->getUses());
4847
Assert::same('C', $namespace->simplifyName('Foo\C'));
4948

5049
Assert::same('\Bar', $namespace->simplifyName('Bar'));
@@ -61,14 +60,14 @@ $namespace->addUse('Bar\C');
6160

6261
Assert::exception(function () use ($namespace) {
6362
$namespace->addTrait('C');
64-
}, Nette\InvalidStateException::class, "Alias 'C' used already for 'Bar\\C', cannot use for 'Foo\\C'.");
63+
}, Nette\InvalidStateException::class, "Name 'C' used already as alias for Bar\\C.");
6564

6665
$namespace->addClass('B');
6766
Assert::exception(function () use ($namespace) {
6867
$namespace->addUse('Lorem\B', 'B');
69-
}, Nette\InvalidStateException::class, "Alias 'B' used already for 'Foo\\B', cannot use for 'Lorem\\B'.");
68+
}, Nette\InvalidStateException::class, "Name 'B' used already for 'Foo\\B'.");
7069

71-
Assert::same(['C' => 'Bar\\C', 'B' => 'Foo\\B'], $namespace->getUses());
70+
Assert::same(['C' => 'Bar\\C'], $namespace->getUses());
7271

7372

7473
// alias generation
@@ -80,9 +79,8 @@ Assert::same('C1', $namespace->simplifyName('Bar\C'));
8079

8180
$namespace = new PhpNamespace('');
8281
$namespace->addUse('Bar\C');
83-
Assert::exception(function () use ($namespace) {
84-
$namespace->addUse('C');
85-
}, Nette\InvalidStateException::class, "Alias 'C' used already for 'Bar\\C', cannot use for 'C'.");
82+
$namespace->addUse('C');
83+
Assert::same('C1', $namespace->simplifyName('C'));
8684

8785
$namespace = new PhpNamespace('');
8886
$namespace->addUse('A');
@@ -96,9 +94,8 @@ Assert::same('C', $namespace->simplifyName('C'));
9694
$namespace->addUse('Bar\C');
9795
Assert::same('C1', $namespace->simplifyName('Bar\C'));
9896
Assert::same('C', $namespace->simplifyName('Foo\C'));
99-
Assert::exception(function () use ($namespace) {
100-
$namespace->addUse('Foo\C');
101-
}, Nette\InvalidStateException::class, "Alias 'C' used already for 'C', cannot use for 'Foo\\C'.");
97+
$namespace->addUse('Foo\C');
98+
Assert::same('C', $namespace->simplifyName('Foo\C'));
10299

103100
$namespace = new PhpNamespace('Foo');
104101
$namespace->addUse('Bar\C');
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
<?php
22

3+
use A;
34
use B as C;
45

5-
class A
6+
class CA
67
{
78
}

tests/PhpGenerator/expected/Printer.namespace.expect

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
namespace Foo;
22

33
use Bar\C;
4+
use Foo\D;
45
use Foo\D as E;
56

67
/**

tests/PhpGenerator/expected/Printer.namespace.unresolved.expect

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
namespace Foo;
22

33
use Bar\C;
4+
use Foo\D;
45
use Foo\D as E;
56

67
/**

0 commit comments

Comments
 (0)