Skip to content

Commit eb0ef91

Browse files
authored
Merge pull request #5378 from magento-architects/ECP-356
ECP-356: class_alias function causes DI compilation failure
2 parents 2d46d98 + 01de924 commit eb0ef91

File tree

4 files changed

+193
-131
lines changed

4 files changed

+193
-131
lines changed

dev/tests/static/testsuite/Magento/Test/Legacy/_files/autogenerated_class_not_in_constructor_whitelist.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,6 @@
99
'Symfony\Component\Console\Application',
1010
'Customer\Address\Attributes',
1111
'Order\Address\Type',
12-
'Order\Address\Attributes'
12+
'Order\Address\Attributes',
13+
'This\Is\Another\Ns',
1314
];

setup/src/Magento/Setup/Module/Di/Code/Reader/ClassesScanner.php

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
* Copyright © Magento, Inc. All rights reserved.
44
* See COPYING.txt for license details.
55
*/
6+
declare(strict_types=1);
67

78
namespace Magento\Setup\Module\Di\Code\Reader;
89

@@ -12,8 +13,6 @@
1213

1314
/**
1415
* Class ClassesScanner
15-
*
16-
* @package Magento\Setup\Module\Di\Code\Reader
1716
*/
1817
class ClassesScanner implements ClassesScannerInterface
1918
{
@@ -100,7 +99,7 @@ public function getList($path)
10099
*/
101100
private function extract(\RecursiveIteratorIterator $recursiveIterator)
102101
{
103-
$classes = [[]];
102+
$classes = [];
104103
foreach ($recursiveIterator as $fileItem) {
105104
/** @var $fileItem \SplFileInfo */
106105
if ($fileItem->isDir() || $fileItem->getExtension() !== 'php' || $fileItem->getBasename()[0] == '.') {
@@ -113,28 +112,29 @@ private function extract(\RecursiveIteratorIterator $recursiveIterator)
113112
}
114113
}
115114
$fileScanner = new FileClassScanner($fileItemPath);
116-
$classNames = $fileScanner->getClassNames();
117-
$this->includeClasses($classNames, $fileItemPath);
118-
$classes [] = $classNames;
115+
$className = $fileScanner->getClassName();
116+
if (!empty($className)) {
117+
$this->includeClass($className, $fileItemPath);
118+
$classes[] = $className;
119+
}
119120
}
120-
return array_merge(...$classes);
121+
122+
return $classes;
121123
}
122124

123125
/**
124-
* Include classes from file path
126+
* Include class from file path.
125127
*
126-
* @param array $classNames
128+
* @param string $className
127129
* @param string $fileItemPath
128130
* @return bool Whether the class is included or not
129131
*/
130-
private function includeClasses(array $classNames, $fileItemPath)
132+
private function includeClass(string $className, string $fileItemPath): bool
131133
{
132-
foreach ($classNames as $className) {
133-
if (!class_exists($className)) {
134-
// phpcs:ignore
135-
require_once $fileItemPath;
136-
return true;
137-
}
134+
if (!class_exists($className)) {
135+
// phpcs:ignore
136+
require_once $fileItemPath;
137+
return true;
138138
}
139139
return false;
140140
}

setup/src/Magento/Setup/Module/Di/Code/Reader/FileClassScanner.php

Lines changed: 29 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,12 @@
33
* Copyright © Magento, Inc. All rights reserved.
44
* See COPYING.txt for license details.
55
*/
6+
declare(strict_types=1);
67

78
namespace Magento\Setup\Module\Di\Code\Reader;
89

910
/**
1011
* Class FileClassScanner
11-
*
12-
* @package Magento\Setup\Module\Di\Code\Reader
1312
*/
1413
class FileClassScanner
1514
{
@@ -20,9 +19,10 @@ class FileClassScanner
2019
];
2120

2221
private const ALLOWED_OPEN_BRACES_TOKENS = [
23-
T_CURLY_OPEN => true,
22+
T_CURLY_OPEN => true,
2423
T_DOLLAR_OPEN_CURLY_BRACES => true,
25-
T_STRING_VARNAME => true];
24+
T_STRING_VARNAME => true
25+
];
2626

2727
/**
2828
* The filename of the file to introspect
@@ -32,11 +32,11 @@ class FileClassScanner
3232
private $filename;
3333

3434
/**
35-
* The list of classes found in the file.
35+
* The class name found in the file.
3636
*
3737
* @var bool
3838
*/
39-
private $classNames = false;
39+
private $className = false;
4040

4141
/**
4242
* @var array
@@ -75,6 +75,19 @@ public function getFileContents()
7575
return file_get_contents($this->filename);
7676
}
7777

78+
/**
79+
* Retrieves the first class found in a class file.
80+
*
81+
* @return string
82+
*/
83+
public function getClassName(): string
84+
{
85+
if ($this->className === false) {
86+
$this->className = $this->extract();
87+
}
88+
return $this->className;
89+
}
90+
7891
/**
7992
* Extracts the fully qualified class name from a file.
8093
*
@@ -85,11 +98,10 @@ public function getFileContents()
8598
*
8699
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
87100
* @SuppressWarnings(PHPMD.NPathComplexity)
88-
* @return array
101+
* @return string
89102
*/
90-
private function extract()
103+
private function extract(): string
91104
{
92-
$classes = [];
93105
$namespaceParts = [];
94106
$class = '';
95107
$triggerClass = false;
@@ -117,6 +129,9 @@ private function extract()
117129
}
118130
$namespaceParts[] = $token[1];
119131

132+
// `class` token is not used with a valid class name
133+
} elseif ($triggerClass && !$tokenIsArray) {
134+
$triggerClass = false;
120135
// The class keyword was found in the last loop
121136
} elseif ($triggerClass && $token[0] === T_STRING) {
122137
$triggerClass = false;
@@ -125,27 +140,26 @@ private function extract()
125140

126141
switch ($token[0]) {
127142
case T_NAMESPACE:
128-
// Current loop contains the namespace keyword. Between this and the semicolon is the namespace
143+
// Current loop contains the namespace keyword. Between this and the semicolon is the namespace
129144
$triggerNamespace = true;
130145
$namespaceParts = [];
131146
$bracedNamespace = $this->isBracedNamespace($index);
132147
break;
133148
case T_CLASS:
134-
// Current loop contains the class keyword. Next loop will have the class name itself.
149+
// Current loop contains the class keyword. Next loop will have the class name itself.
135150
if ($braceLevel == 0 || ($bracedNamespace && $braceLevel == 1)) {
136151
$triggerClass = true;
137152
}
138153
break;
139154
}
140155

141-
// We have a class name, let's concatenate and store it!
156+
// We have a class name, let's concatenate and return it!
142157
if ($class !== '') {
143158
$fqClassName = trim(join('', $namespaceParts)) . trim($class);
144-
$classes[] = $fqClassName;
145-
$class = '';
159+
return $fqClassName;
146160
}
147161
}
148-
return $classes;
162+
return $class;
149163
}
150164

151165
/**
@@ -173,19 +187,4 @@ private function isBracedNamespace($index)
173187
}
174188
throw new InvalidFileException('Could not find namespace termination');
175189
}
176-
177-
/**
178-
* Retrieves the first class found in a class file.
179-
*
180-
* The return value is in an array format so it retains the same usage as the FileScanner.
181-
*
182-
* @return array
183-
*/
184-
public function getClassNames()
185-
{
186-
if ($this->classNames === false) {
187-
$this->classNames = $this->extract();
188-
}
189-
return $this->classNames;
190-
}
191190
}

0 commit comments

Comments
 (0)