Skip to content

Commit d74311d

Browse files
[12.x] Improve @use directive to support function and const modifiers (#55583)
* refactor use statement compiler to support modifiers function and const * fix target php version * fix code style * Formatting --------- Co-authored-by: Taylor Otwell <taylor@laravel.com>
1 parent 5d5a00e commit d74311d

File tree

2 files changed

+89
-8
lines changed

2 files changed

+89
-8
lines changed

src/Illuminate/View/Compilers/Concerns/CompilesUseStatements.php

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,20 +12,35 @@ trait CompilesUseStatements
1212
*/
1313
protected function compileUse($expression)
1414
{
15-
$expression = preg_replace('/[()]/', '', $expression);
15+
$expression = trim(preg_replace('/[()]/', '', $expression), " '\"");
1616

17-
// Preserve grouped imports as-is...
17+
// Isolate alias...
1818
if (str_contains($expression, '{')) {
19-
$use = ltrim(trim($expression, " '\""), '\\');
19+
$pathWithOptionalModifier = $expression;
20+
$aliasWithLeadingSpace = '';
21+
} else {
22+
$segments = explode(',', $expression);
23+
$pathWithOptionalModifier = trim($segments[0], " '\"");
2024

21-
return "<?php use \\{$use}; ?>";
25+
$aliasWithLeadingSpace = isset($segments[1])
26+
? ' as '.trim($segments[1], " '\"")
27+
: '';
2228
}
2329

24-
$segments = explode(',', $expression);
30+
// Split modifier and path...
31+
if (str_starts_with($pathWithOptionalModifier, 'function ')) {
32+
$modifierWithTrailingSpace = 'function ';
33+
$path = explode(' ', $pathWithOptionalModifier, 2)[1] ?? $pathWithOptionalModifier;
34+
} elseif (str_starts_with($pathWithOptionalModifier, 'const ')) {
35+
$modifierWithTrailingSpace = 'const ';
36+
$path = explode(' ', $pathWithOptionalModifier, 2)[1] ?? $pathWithOptionalModifier;
37+
} else {
38+
$modifierWithTrailingSpace = '';
39+
$path = $pathWithOptionalModifier;
40+
}
2541

26-
$use = ltrim(trim($segments[0], " '\""), '\\');
27-
$as = isset($segments[1]) ? ' as '.trim($segments[1], " '\"") : '';
42+
$path = ltrim($path, '\\');
2843

29-
return "<?php use \\{$use}{$as}; ?>";
44+
return "<?php use {$modifierWithTrailingSpace}\\{$path}{$aliasWithLeadingSpace}; ?>";
3045
}
3146
}

tests/View/Blade/BladeUseTest.php

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,4 +69,70 @@ public function testUseStatementWithBracesAndBackslashAreCompiledCorrectly()
6969
$string = "Foo @use(\SomeNamespace\{Foo, Bar}) bar";
7070
$this->assertEquals($expected, $this->compiler->compileString($string));
7171
}
72+
73+
public function testUseStatementsWithModifiersAreCompiled()
74+
{
75+
$expected = 'Foo <?php use function \SomeNamespace\SomeFunction as Foo; ?> bar';
76+
77+
$string = "Foo @use('function SomeNamespace\SomeFunction', 'Foo') bar";
78+
$this->assertEquals($expected, $this->compiler->compileString($string));
79+
80+
$string = 'Foo @use(function SomeNamespace\SomeFunction, Foo) bar';
81+
$this->assertEquals($expected, $this->compiler->compileString($string));
82+
}
83+
84+
public function testUseStatementsWithModifiersWithoutAliasAreCompiled()
85+
{
86+
$expected = 'Foo <?php use const \SomeNamespace\SOME_CONST; ?> bar';
87+
88+
$string = "Foo @use('const SomeNamespace\SOME_CONST') bar";
89+
$this->assertEquals($expected, $this->compiler->compileString($string));
90+
91+
$string = 'Foo @use(const SomeNamespace\SOME_CONST) bar';
92+
$this->assertEquals($expected, $this->compiler->compileString($string));
93+
}
94+
95+
public function testUseStatementsWithModifiersAndBackslashAtBeginningAreCompiled()
96+
{
97+
$expected = 'Foo <?php use function \SomeNamespace\SomeFunction; ?> bar';
98+
99+
$string = "Foo @use('function \SomeNamespace\SomeFunction') bar";
100+
$this->assertEquals($expected, $this->compiler->compileString($string));
101+
102+
$string = 'Foo @use(function \SomeNamespace\SomeFunction) bar';
103+
$this->assertEquals($expected, $this->compiler->compileString($string));
104+
}
105+
106+
public function testUseStatementsWithModifiersBackslashAtBeginningAndAliasedAreCompiled()
107+
{
108+
$expected = 'Foo <?php use const \SomeNamespace\SOME_CONST as Foo; ?> bar';
109+
110+
$string = "Foo @use('const \SomeNamespace\SOME_CONST', 'Foo') bar";
111+
$this->assertEquals($expected, $this->compiler->compileString($string));
112+
113+
$string = 'Foo @use(const \SomeNamespace\SOME_CONST, Foo) bar';
114+
$this->assertEquals($expected, $this->compiler->compileString($string));
115+
}
116+
117+
public function testUseStatementsWithModifiersWithBracesAreCompiledCorrectly()
118+
{
119+
$expected = 'Foo <?php use function \SomeNamespace\{Foo, Bar}; ?> bar';
120+
121+
$string = "Foo @use('function SomeNamespace\{Foo, Bar}') bar";
122+
$this->assertEquals($expected, $this->compiler->compileString($string));
123+
124+
$string = 'Foo @use(function SomeNamespace\{Foo, Bar}) bar';
125+
$this->assertEquals($expected, $this->compiler->compileString($string));
126+
}
127+
128+
public function testUseFunctionStatementWithBracesAndBackslashAreCompiledCorrectly()
129+
{
130+
$expected = 'Foo <?php use const \SomeNamespace\{FOO, BAR}; ?> bar';
131+
132+
$string = "Foo @use('const \SomeNamespace\{FOO, BAR}') bar";
133+
$this->assertEquals($expected, $this->compiler->compileString($string));
134+
135+
$string = 'Foo @use(const \SomeNamespace\{FOO, BAR}) bar';
136+
$this->assertEquals($expected, $this->compiler->compileString($string));
137+
}
72138
}

0 commit comments

Comments
 (0)