From 001a061278bbf974ca36238edcccc694eaeaeb0b Mon Sep 17 00:00:00 2001 From: Rodolfo Rodas Date: Mon, 28 Apr 2025 14:46:29 -0600 Subject: [PATCH 1/4] refactor use statement compiler to support modifiers function and const --- .../Concerns/CompilesUseStatements.php | 35 +++++++--- tests/View/Blade/BladeUseTest.php | 66 +++++++++++++++++++ 2 files changed, 92 insertions(+), 9 deletions(-) diff --git a/src/Illuminate/View/Compilers/Concerns/CompilesUseStatements.php b/src/Illuminate/View/Compilers/Concerns/CompilesUseStatements.php index 49a524a5fd9f..587975ee1c03 100644 --- a/src/Illuminate/View/Compilers/Concerns/CompilesUseStatements.php +++ b/src/Illuminate/View/Compilers/Concerns/CompilesUseStatements.php @@ -4,6 +4,9 @@ trait CompilesUseStatements { + private const string FUNCTION_MODIFIER_WITH_TRAILING_SPACE = 'function '; + private const string CONST_MODIFIER_WITH_TRAILING_SPACE = 'const '; + /** * Compile the use statements into valid PHP. * @@ -12,20 +15,34 @@ trait CompilesUseStatements */ protected function compileUse($expression) { - $expression = preg_replace('/[()]/', '', $expression); + $expression = trim(preg_replace('/[()]/', '', $expression), " '\""); - // Preserve grouped imports as-is... + // isolate alias if (str_contains($expression, '{')) { - $use = ltrim(trim($expression, " '\""), '\\'); - - return ""; + $pathWithOptionalModifier = $expression; + $aliasWithLeadingSpace = ''; + } else { + $segments = explode(',', $expression); + $pathWithOptionalModifier = trim($segments[0], " '\""); + $aliasWithLeadingSpace = isset($segments[1]) + ? ' as ' . trim($segments[1], " '\"") + : ''; } - $segments = explode(',', $expression); + // split modifier and path + if (str_starts_with($pathWithOptionalModifier, self::FUNCTION_MODIFIER_WITH_TRAILING_SPACE)) { + $modifierWithTrailingSpace = self::FUNCTION_MODIFIER_WITH_TRAILING_SPACE; + $path = explode(' ', $pathWithOptionalModifier, 2)[1] ?? $pathWithOptionalModifier; + } elseif (str_starts_with($pathWithOptionalModifier, self::CONST_MODIFIER_WITH_TRAILING_SPACE)) { + $modifierWithTrailingSpace = self::CONST_MODIFIER_WITH_TRAILING_SPACE; + $path = explode(' ', $pathWithOptionalModifier, 2)[1] ?? $pathWithOptionalModifier; + } else { + $modifierWithTrailingSpace = ''; + $path = $pathWithOptionalModifier; + } - $use = ltrim(trim($segments[0], " '\""), '\\'); - $as = isset($segments[1]) ? ' as '.trim($segments[1], " '\"") : ''; + $path = ltrim($path, '\\'); - return ""; + return ""; } } diff --git a/tests/View/Blade/BladeUseTest.php b/tests/View/Blade/BladeUseTest.php index 980a266128a6..28072b64559c 100644 --- a/tests/View/Blade/BladeUseTest.php +++ b/tests/View/Blade/BladeUseTest.php @@ -69,4 +69,70 @@ public function testUseStatementWithBracesAndBackslashAreCompiledCorrectly() $string = "Foo @use(\SomeNamespace\{Foo, Bar}) bar"; $this->assertEquals($expected, $this->compiler->compileString($string)); } + + public function testUseStatementsWithModifiersAreCompiled() + { + $expected = 'Foo bar'; + + $string = "Foo @use('function SomeNamespace\SomeFunction', 'Foo') bar"; + $this->assertEquals($expected, $this->compiler->compileString($string)); + + $string = 'Foo @use(function SomeNamespace\SomeFunction, Foo) bar'; + $this->assertEquals($expected, $this->compiler->compileString($string)); + } + + public function testUseStatementsWithModifiersWithoutAliasAreCompiled() + { + $expected = 'Foo bar'; + + $string = "Foo @use('const SomeNamespace\SOME_CONST') bar"; + $this->assertEquals($expected, $this->compiler->compileString($string)); + + $string = 'Foo @use(const SomeNamespace\SOME_CONST) bar'; + $this->assertEquals($expected, $this->compiler->compileString($string)); + } + + public function testUseStatementsWithModifiersAndBackslashAtBeginningAreCompiled() + { + $expected = 'Foo bar'; + + $string = "Foo @use('function \SomeNamespace\SomeFunction') bar"; + $this->assertEquals($expected, $this->compiler->compileString($string)); + + $string = 'Foo @use(function \SomeNamespace\SomeFunction) bar'; + $this->assertEquals($expected, $this->compiler->compileString($string)); + } + + public function testUseStatementsWithModifiersBackslashAtBeginningAndAliasedAreCompiled() + { + $expected = 'Foo bar'; + + $string = "Foo @use('const \SomeNamespace\SOME_CONST', 'Foo') bar"; + $this->assertEquals($expected, $this->compiler->compileString($string)); + + $string = 'Foo @use(const \SomeNamespace\SOME_CONST, Foo) bar'; + $this->assertEquals($expected, $this->compiler->compileString($string)); + } + + public function testUseStatementsWithModifiersWithBracesAreCompiledCorrectly() + { + $expected = 'Foo bar'; + + $string = "Foo @use('function SomeNamespace\{Foo, Bar}') bar"; + $this->assertEquals($expected, $this->compiler->compileString($string)); + + $string = 'Foo @use(function SomeNamespace\{Foo, Bar}) bar'; + $this->assertEquals($expected, $this->compiler->compileString($string)); + } + + public function testUseFunctionStatementWithBracesAndBackslashAreCompiledCorrectly() + { + $expected = 'Foo bar'; + + $string = "Foo @use('const \SomeNamespace\{FOO, BAR}') bar"; + $this->assertEquals($expected, $this->compiler->compileString($string)); + + $string = 'Foo @use(const \SomeNamespace\{FOO, BAR}) bar'; + $this->assertEquals($expected, $this->compiler->compileString($string)); + } } From 006d4d7880727d307d0ab5db9ca1708088b53c99 Mon Sep 17 00:00:00 2001 From: Rodolfo Rodas Date: Mon, 28 Apr 2025 14:51:19 -0600 Subject: [PATCH 2/4] fix target php version --- .../View/Compilers/Concerns/CompilesUseStatements.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Illuminate/View/Compilers/Concerns/CompilesUseStatements.php b/src/Illuminate/View/Compilers/Concerns/CompilesUseStatements.php index 587975ee1c03..d17b70ba7063 100644 --- a/src/Illuminate/View/Compilers/Concerns/CompilesUseStatements.php +++ b/src/Illuminate/View/Compilers/Concerns/CompilesUseStatements.php @@ -4,8 +4,8 @@ trait CompilesUseStatements { - private const string FUNCTION_MODIFIER_WITH_TRAILING_SPACE = 'function '; - private const string CONST_MODIFIER_WITH_TRAILING_SPACE = 'const '; + private const FUNCTION_MODIFIER_WITH_TRAILING_SPACE = 'function '; + private const CONST_MODIFIER_WITH_TRAILING_SPACE = 'const '; /** * Compile the use statements into valid PHP. From f9d207c67a48d9551fe7b824ee228e86b036bf7b Mon Sep 17 00:00:00 2001 From: Rodolfo Rodas Date: Mon, 28 Apr 2025 14:55:25 -0600 Subject: [PATCH 3/4] fix code style --- .../View/Compilers/Concerns/CompilesUseStatements.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Illuminate/View/Compilers/Concerns/CompilesUseStatements.php b/src/Illuminate/View/Compilers/Concerns/CompilesUseStatements.php index d17b70ba7063..fb072b56c70c 100644 --- a/src/Illuminate/View/Compilers/Concerns/CompilesUseStatements.php +++ b/src/Illuminate/View/Compilers/Concerns/CompilesUseStatements.php @@ -25,7 +25,7 @@ protected function compileUse($expression) $segments = explode(',', $expression); $pathWithOptionalModifier = trim($segments[0], " '\""); $aliasWithLeadingSpace = isset($segments[1]) - ? ' as ' . trim($segments[1], " '\"") + ? ' as '.trim($segments[1], " '\"") : ''; } From a21827cc92956ab25cb73ff4f1d607c19b5b4de6 Mon Sep 17 00:00:00 2001 From: Taylor Otwell Date: Tue, 29 Apr 2025 14:35:10 -0500 Subject: [PATCH 4/4] Formatting --- .../Compilers/Concerns/CompilesUseStatements.php | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/src/Illuminate/View/Compilers/Concerns/CompilesUseStatements.php b/src/Illuminate/View/Compilers/Concerns/CompilesUseStatements.php index fb072b56c70c..cefd5fd6eb94 100644 --- a/src/Illuminate/View/Compilers/Concerns/CompilesUseStatements.php +++ b/src/Illuminate/View/Compilers/Concerns/CompilesUseStatements.php @@ -4,9 +4,6 @@ trait CompilesUseStatements { - private const FUNCTION_MODIFIER_WITH_TRAILING_SPACE = 'function '; - private const CONST_MODIFIER_WITH_TRAILING_SPACE = 'const '; - /** * Compile the use statements into valid PHP. * @@ -17,24 +14,25 @@ protected function compileUse($expression) { $expression = trim(preg_replace('/[()]/', '', $expression), " '\""); - // isolate alias + // Isolate alias... if (str_contains($expression, '{')) { $pathWithOptionalModifier = $expression; $aliasWithLeadingSpace = ''; } else { $segments = explode(',', $expression); $pathWithOptionalModifier = trim($segments[0], " '\""); + $aliasWithLeadingSpace = isset($segments[1]) ? ' as '.trim($segments[1], " '\"") : ''; } - // split modifier and path - if (str_starts_with($pathWithOptionalModifier, self::FUNCTION_MODIFIER_WITH_TRAILING_SPACE)) { - $modifierWithTrailingSpace = self::FUNCTION_MODIFIER_WITH_TRAILING_SPACE; + // Split modifier and path... + if (str_starts_with($pathWithOptionalModifier, 'function ')) { + $modifierWithTrailingSpace = 'function '; $path = explode(' ', $pathWithOptionalModifier, 2)[1] ?? $pathWithOptionalModifier; - } elseif (str_starts_with($pathWithOptionalModifier, self::CONST_MODIFIER_WITH_TRAILING_SPACE)) { - $modifierWithTrailingSpace = self::CONST_MODIFIER_WITH_TRAILING_SPACE; + } elseif (str_starts_with($pathWithOptionalModifier, 'const ')) { + $modifierWithTrailingSpace = 'const '; $path = explode(' ', $pathWithOptionalModifier, 2)[1] ?? $pathWithOptionalModifier; } else { $modifierWithTrailingSpace = '';