Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Compile starts/ends with using str_starts_with and str_ends_with #3897

Merged
merged 1 commit into from
Oct 22, 2023

Conversation

GromNaN
Copy link
Contributor

@GromNaN GromNaN commented Oct 21, 2023

Since we now require PHP 8.0 polyfill #3884, we can use str_starts_with and str_ends_with to compile starts with and ends with expressions.

Example with bootstrap_4_layout.html.twig line 6-7 (see deep diff):

    {%- set prepend = not (money_pattern starts with '{{') -%}
    {%- set append = not (money_pattern ends with '}}') -%}

Previous compilation:

// line 6
$context["prepend"] =  !(is_string($__internal_compile_0 = (isset($context["money_pattern"]) || array_key_exists("money_pattern", $context) ? $context["money_pattern"] : (function () { throw new RuntimeError('Variable "money_pattern" does not exist.', 6, $this->source); })())) && is_string($__internal_compile_1 = "{{") && ('' === $__internal_compile_1 || 0 === strpos($__internal_compile_0, $__internal_compile_1)));
// line 7
$context["append"] =  !(is_string($__internal_compile_2 = (isset($context["money_pattern"]) || array_key_exists("money_pattern", $context) ? $context["money_pattern"] : (function () { throw new RuntimeError('Variable "money_pattern" does not exist.', 7, $this->source); })())) && is_string($__internal_compile_3 = "}}") && ('' === $__internal_compile_3 || $__internal_compile_3 === substr($__internal_compile_2, -strlen($__internal_compile_3))));

With this change:

// line 6
$context["prepend"] =  !(is_string($__internal_compile_0 = (isset($context["money_pattern"]) || array_key_exists("money_pattern", $context) ? $context["money_pattern"] : (function () { throw new RuntimeError('Variable "money_pattern" does not exist.', 6, $this->source); })())) && is_string($__internal_compile_1 = "{{") && str_starts_with($__internal_compile_0, $__internal_compile_1));
// line 7
$context["append"] =  !(is_string($__internal_compile_2 = (isset($context["money_pattern"]) || array_key_exists("money_pattern", $context) ? $context["money_pattern"] : (function () { throw new RuntimeError('Variable "money_pattern" does not exist.', 7, $this->source); })())) && is_string($__internal_compile_3 = "}}") && str_ends_with($__internal_compile_2, $__internal_compile_3));

@GromNaN GromNaN changed the title Compile starts/ends with using PHP8 functions str_starts/ends_with Compile starts/ends with using PHP8 functions str_starts_with str_ends_with Oct 21, 2023
@GromNaN GromNaN changed the title Compile starts/ends with using PHP8 functions str_starts_with str_ends_with Compile starts/ends with using str_starts_with and str_ends_with Oct 21, 2023
@@ -24,7 +24,7 @@ public function compile(Compiler $compiler): void
->subcompile($this->getNode('left'))
->raw(sprintf(') && is_string($%s = ', $right))
Copy link
Contributor Author

@GromNaN GromNaN Oct 21, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An additional optimization could be to remove the is_string($right = <right>) when the right expression is a constant string. And using strict mode, it should throw an exception if it is a constant that is not a string.

@fabpot
Copy link
Contributor

fabpot commented Oct 22, 2023

Thank you @GromNaN.

@fabpot fabpot merged commit 758018b into twigphp:3.x Oct 22, 2023
58 checks passed
@GromNaN GromNaN deleted the compile-str_starts_ends_with branch October 22, 2023 13:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants