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

[4.0] Support string literals #4123

Closed
wants to merge 1 commit into from
Closed

Conversation

ruudk
Copy link
Contributor

@ruudk ruudk commented Jul 6, 2024

After posting this as an idea in #3951 (comment) I tried to implement it. It looks like it's quite doable. But maybe I'm missing something.


This allows to write a string literal using backticks. When using a literal, you don't need to escape backslashes. This is ideal for situation where you want to reference a fully qualified class name. For example in a constant function.

For example, before you had to write:

{{ constant("App\\Entity\\Class::Constant") }}

Now you can write:

{{ constant(`App\Entity\Class::Constant`) }}

Besides easier to read, there is another huge benefit: when doing a text search for a fully qualified class name, it will show up.

This allows to write a string literal using backticks. When using a literal, you don't need to
escape backslashes. This is ideal for situation where you want to reference a fully qualified
class name. For example in a `constant` function.

For example, before you had to write:
```twig
{{ constant("App\\Entity\\Class::Constant") }}
```

Now you can write:
```twig
{{ constant(`App\Entity\Class::Constant`) }}
```

Besides easier to read, there is another huge benefit: when doing a text search for a fully
qualified class name, it will show up.
@smnandre
Copy link
Contributor

smnandre commented Jul 7, 2024

To clarify the terminology and avoid any misunderstandings in this conversation:

Twig already supports string literals, as 'foo' and "foo" are both already... string literals. To be precise they are quoted sequence of characters using single or double-quote paired delimiters, using \\ as escaping prefix.

What you suggest here is about introducing another syntax of string literals: with ` as delimiter (and still \ as escaping prefix, but without the need to escape... itself).

In the Javascript world, the backtick is used in template literals, offering two things harder to do without:

  • multi-lines strings
  • string interpolation

These two points do not offer significant advantages for Twig, as it already provides mechanisms for these needs.

Therefore, I am not entirely convinced that the advantages (facilitating PHP execution in very specific cases) outweigh the costs (significant changes to the Lexer, increased maintenance, and additional documentation).

But maybe there are other features/benefits i don't see here?


PhpStorm already does offer support for the constant function in Twig, i'm sure if it does not support Enum yet, it will be done soon. And i guess similar plugin can be found for alternative IDEs.

twig-phpstorm-enum

@ruudk
Copy link
Contributor Author

ruudk commented Jul 7, 2024

Regarding the PHPStorm screenshot: is that native or via that Symfony plugin?

@smnandre
Copy link
Contributor

smnandre commented Jul 7, 2024

Regarding the PHPStorm screenshot: is that native or via that Symfony plugin?

Via the Symfony plugin it seems (found this PR that seems very related to the current PR : Haehnchen/idea-php-symfony2-plugin@b358ff0 )

@stof
Copy link
Member

stof commented Jul 10, 2024

There was a discussion in the past about adding support for unescaped slashes in existing string literals (keeping the option to escape them as well), by producing a deprecation warning for any useless escaping in strings (\d in a Twig string currently means d as unknown escape sequence is treated as resolving to the unescaped character).
This would allow to avoid escaping the \ except when the following character has a meaning in an escape sequence, like the way double-quoted string literals work in PHP (see https://3v4l.org/A2mPT).

Implementing this involves replacing stripcslashes by an implementation distinguishing useless escaping in

$this->pushToken(/* Token::STRING_TYPE */ 7, stripcslashes(substr($match[0], 1, -1)));

If this gets implemented, we might not need to introduce a third syntax for string literals in Twig.

@smnandre
Copy link
Contributor

smnandre commented Jul 10, 2024

If this gets implemented, we might not need to introduce a third syntax for string literals in Twig.

But to get there you'd have to change the string regexp no ?

Edit: nope, that works

https://3v4l.org/RfnYM

@fabpot
Copy link
Contributor

fabpot commented Aug 3, 2024

I agree with @stof suggestion.

@ruudk
Copy link
Contributor Author

ruudk commented Aug 3, 2024

Should I try a PR for that?

@fabpot
Copy link
Contributor

fabpot commented Aug 4, 2024

Should I try a PR for that?

That would be great!

ruudk added a commit to ruudk/Twig that referenced this pull request Aug 7, 2024
@ruudk
Copy link
Contributor Author

ruudk commented Aug 7, 2024

Created a PR to attempt to solve this:

ruudk added a commit to ruudk/Twig that referenced this pull request Aug 7, 2024
See twigphp#4123 twigphp#2712

This allows to change the implementation in v4 so that we no longer have to escape backslashes.
ruudk added a commit to ruudk/Twig that referenced this pull request Aug 7, 2024
See twigphp#4123 twigphp#2712

This allows to change the implementation in v4 so that we no longer have to escape backslashes.
ruudk added a commit to ruudk/Twig that referenced this pull request Aug 7, 2024
See twigphp#4123 twigphp#2712

This allows to change the implementation in v4 so that we no longer have to escape backslashes.
ruudk added a commit to ruudk/Twig that referenced this pull request Aug 7, 2024
See twigphp#4123 twigphp#2712

This allows to change the implementation in v4 so that we no longer have to escape backslashes.
ruudk added a commit to ruudk/Twig that referenced this pull request Aug 7, 2024
See twigphp#4123 twigphp#2712

This allows to change the implementation in v4 so that we no longer have to escape backslashes.
ruudk added a commit to ruudk/Twig that referenced this pull request Aug 7, 2024
See twigphp#4123 twigphp#2712

This allows to change the implementation in v4 so that we no longer have to escape backslashes.
ruudk added a commit to ruudk/Twig that referenced this pull request Aug 7, 2024
See twigphp#4123 twigphp#2712

This allows to change the implementation in v4 so that we no longer have to escape backslashes.
ruudk added a commit to ruudk/Twig that referenced this pull request Aug 7, 2024
See twigphp#4123 twigphp#2712

This allows to change the implementation in v4 so that we no longer have to escape backslashes.
ruudk added a commit to ruudk/Twig that referenced this pull request Aug 8, 2024
See twigphp#4123 twigphp#2712

This allows to change the implementation in v4 so that we no longer have to escape backslashes.
ruudk added a commit to ruudk/Twig that referenced this pull request Aug 8, 2024
See twigphp#4123 twigphp#2712

This allows to change the implementation in v4 so that we no longer have to escape backslashes.
ruudk added a commit to ruudk/Twig that referenced this pull request Aug 8, 2024
See twigphp#4123 twigphp#2712

This allows to change the implementation in v4 so that we no longer have to escape backslashes.
ruudk added a commit to ruudk/Twig that referenced this pull request Aug 8, 2024
See twigphp#4123 twigphp#2712

This allows to change the implementation in v4 so that we no longer have to escape backslashes.
ruudk added a commit to ruudk/Twig that referenced this pull request Aug 10, 2024
See twigphp#4123 twigphp#2712

This allows to change the implementation in v4 so that we no longer have to escape backslashes.
@fabpot
Copy link
Contributor

fabpot commented Aug 11, 2024

Can we close this one @ruudk?

ruudk added a commit to ruudk/Twig that referenced this pull request Aug 11, 2024
See twigphp#4123 twigphp#2712

This allows to change the implementation in v4 so that we no longer have to escape backslashes.
ruudk added a commit to ruudk/Twig that referenced this pull request Aug 11, 2024
See twigphp#4123 twigphp#2712

This allows to change the implementation in v4 so that we no longer have to escape backslashes.
ruudk added a commit to ruudk/Twig that referenced this pull request Aug 11, 2024
See twigphp#4123 twigphp#2712

This allows to change the implementation in v4 so that we no longer have to escape backslashes.
@ruudk ruudk closed this Aug 11, 2024
@ruudk
Copy link
Contributor Author

ruudk commented Aug 11, 2024

See #4176

@ruudk ruudk deleted the string-literals branch August 11, 2024 14:24
fabpot added a commit that referenced this pull request Aug 11, 2024
This PR was merged into the 3.x branch.

Discussion
----------

Deprecate unnecessary escape characters

This is a first attempt at solving #4123 and #2712.

Currently it writes the deprecations to an array in the Lexer. This is probably not the way to do it. Should we directly trigger `E_USER_DEPRECATED` errors?

/cc `@stof` `@fabpot` Let me know what you think 😊

Commits
-------

c6656cf Deprecate unnecessary escape characters
ruudk added a commit to ruudk/Twig that referenced this pull request Aug 12, 2024
Follow up of twigphp#4176, twigphp#4123 and twigphp#2712.

Now that we have deprecated unnecessary escape in v3, we can change the behavior in v4.

With this change, unnecessary will no longer be ignored, but handled like any other character.

This allows for writing fully qualified class names like this:
```twig
{{ constant('App\Entity\User::SOME_CONSTANT') }}
```

Instead of having to escape the `\` in v3:
```twig
{{ constant('App\\Entity\\User::SOME_CONSTANT') }}
```
ruudk added a commit to ruudk/Twig that referenced this pull request Aug 15, 2024
Follow up of twigphp#4176, twigphp#4123 and twigphp#2712.

Now that we have deprecated unnecessary escape in v3, we can change the behavior in v4.

With this change, unnecessary will no longer be ignored, but handled like any other character.

This allows for writing fully qualified class names like this:
```twig
{{ constant('App\Entity\User::SOME_CONSTANT') }}
```

Instead of having to escape the `\` in v3:
```twig
{{ constant('App\\Entity\\User::SOME_CONSTANT') }}
```
ruudk added a commit to ruudk/Twig that referenced this pull request Aug 21, 2024
Follow up of twigphp#4176, twigphp#4123 and twigphp#2712.

Now that we have deprecated unnecessary escape in v3, we can change the behavior in v4.

With this change, unnecessary will no longer be ignored, but handled like any other character.

This allows for writing fully qualified class names like this:
```twig
{{ constant('App\Entity\User::SOME_CONSTANT') }}
```

Instead of having to escape the `\` in v3:
```twig
{{ constant('App\\Entity\\User::SOME_CONSTANT') }}
```
fabpot added a commit that referenced this pull request Aug 21, 2024
This PR was squashed before being merged into the 4.x branch.

Discussion
----------

Do not hide unnecessary escape characters

Follow up of #4176, #4123 and #2712.

Now that we have deprecated unnecessary escape in v3, we can change the behavior in v4.

With this change, unnecessary will no longer be ignored, but handled like any other character.

This allows for writing fully qualified class names like this:
```twig
{{ constant('App\Entity\User::SOME_CONSTANT') }}
```

Instead of having to escape the `\` in v3:
```twig
{{ constant('App\\Entity\\User::SOME_CONSTANT') }}
```

/cc `@fabpot` `@stof`

Commits
-------

53c24bf Do not hide unnecessary escape characters
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.

4 participants