Thanks to visit codestin.com
Credit goes to github.com

Skip to content

[ExpressionLanguage] Add Parser->parseWithoutContext #50144

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

Conversation

homersimpsons
Copy link
Contributor

@homersimpsons homersimpsons commented Apr 24, 2023

Q A
Branch? 6.4
Bug fix? no
New feature? yes
Deprecations? no
Tickets Fix #50105
License MIT
Doc PR symfony/symfony-docs/pull/18298

Code snippet

Let say we want to check that all our #[Security] attributes have an is_granted call with a subject given.

Note that the following example is for illustration purpose and does not really handle all possible outcomes (for instance is_granted(.., ..) || is_granted(.., ..).

$lexer = new Lexer();
$parser = new Parser([]);

$attributes = /* fetch all `#[Security]` attributes */
foreach ($attributes as $attribute) {
    $intance = $attribute->newInstance();
    $parsed = $parser->parseWithoutContext($instance->getExpression()); // Here we can parse without taking care of the possible symbols
    if (
        $parsed instanceof FunctionNode
        && isset($parsed->nodes['arguments'][1])
        && $parsed->nodes['arguments'][1] instanceof NameNode
    ) {
      continue; // it is an `is_granted` call with a subject
    }

    throw new SecurityException('Attribute with expression `' . $instance->getExpression() . '` does not have a valid `is_granted` call.');
}

Other use cases may involve:

  • Executing the expression in another language (such as in browser in JavaScript)
  • Extracting variable name in a first pass to get their values from a database or something else, then evaluating the expression in a second pass

@carsonbot
Copy link

Hey!

I see that this is your first PR. That is great! Welcome!

Symfony has a contribution guide which I suggest you to read.

In short:

  • Always add tests
  • Keep backward compatibility (see https://symfony.com/bc).
  • Bug fixes must be submitted against the lowest maintained branch where they apply (see https://symfony.com/releases)
  • Features and deprecations must be submitted against the 6.3 branch.

Review the GitHub status checks of your pull request and try to solve the reported issues. If some tests are failing, try to see if they are failing because of this change.

When two Symfony core team members approve this change, it will be merged and you will become an official Symfony contributor!
If this PR is merged in a lower version branch, it will be merged up to all maintained branches within a few days.

I am going to sit back now and wait for the reviews.

Cheers!

Carsonbot

@carsonbot carsonbot changed the title [WIP] [ExpressionLanguage] Add Parser->parseWithoutContext [ExpressionLanguage] [WIP] Add Parser->parseWithoutContext Apr 24, 2023
@carsonbot
Copy link

Hey!

Thanks for your PR. You are targeting branch "6.3" but it seems your PR description refers to branch "6.3 for features / 5.4 or 6.2 for bug fixes".
Could you update the PR description or change target branch? This helps core maintainers a lot.

Cheers!

Carsonbot

@homersimpsons homersimpsons force-pushed the feature/expression-language-parse-without-context branch 2 times, most recently from cf5cb7f to a2ca917 Compare April 24, 2023 21:52
@homersimpsons homersimpsons changed the title [ExpressionLanguage] [WIP] Add Parser->parseWithoutContext [WIP] [ExpressionLanguage] Add Parser->parseWithoutContext Apr 24, 2023
@homersimpsons
Copy link
Contributor Author

homersimpsons commented Apr 24, 2023

  • Test failure in "Unit Tests / Unit Tests (8.1, low-deps) (pull_request)" is not because of this Pull Request
  • Test failure in "continuous-integration/appveyor/pr" is not because of this Pull Request
  • Where am I supposed to add the code sample ? I added a code sample to this Pull Request description

@homersimpsons homersimpsons changed the title [WIP] [ExpressionLanguage] Add Parser->parseWithoutContext [ExpressionLanguage] Add Parser->parseWithoutContext May 9, 2023
@homersimpsons homersimpsons force-pushed the feature/expression-language-parse-without-context branch from a2ca917 to b58cff5 Compare May 19, 2023 16:14
@homersimpsons
Copy link
Contributor Author

I just rebased this Pull Request to latest upstream changes, it is ready for review.

@nicolas-grekas nicolas-grekas modified the milestones: 6.3, 6.4 May 23, 2023
@homersimpsons
Copy link
Contributor Author

@stof Can you review this please ?

Note: Sorry for the ping, but it seems you reviewed another PR about ExpressionLanguage and it looks like fabbot is not assigning anyone (is it supposed to?).

@homersimpsons
Copy link
Contributor Author

@fabpot Is there any chance you could assign someone to my PR ? Or tell me what I am missing ?

Note: Sorry for the ping but I still have no human feedback while my PR is ready for review.

@homersimpsons homersimpsons force-pushed the feature/expression-language-parse-without-context branch from b58cff5 to 15ce692 Compare August 5, 2023 17:49
@homersimpsons
Copy link
Contributor Author

Psalm reports the method as PossiblyUnusedMethod. In fact it is not used by any internal API as the goal is to expose it as a public API.

I could not find any @psalm-api in the codebase so I don't know what is the good practice in symfony for this error.

@fancyweb
Copy link
Contributor

fancyweb commented Aug 8, 2023

It looks like your use case sits between lint() and parse(). A lint() that returns, or a parse that doesn't validate the variables 🤷‍♂️ I'm not sure adding a third method is the good move 🤔

Maybe we could "change" lint() return type (since it's void) and starts returning the node?
Or we could deprecate lint() and add a third argument to parse() directly? Maybe a bit mask of what the parse should check..
WDYT @nicolas-grekas?

@fabpot
Copy link
Member

fabpot commented Feb 6, 2024

See #53806 for an alternative implementation.

@fabpot
Copy link
Member

fabpot commented Feb 6, 2024

Closing in favor of #53806

@fabpot fabpot closed this Feb 6, 2024
fabpot added a commit that referenced this pull request Feb 6, 2024
…arsing/linting methods (fabpot)

This PR was merged into the 7.1 branch.

Discussion
----------

[ExpressionLanguage] Add more configurability to the parsing/linting methods

| Q             | A
| ------------- | ---
| Branch?       | 7.1
| Bug fix?      | no
| New feature?  | yes
| Deprecations? | yes
| Issues        | Fixes #50144
| License       | MIT

When linting/parsing an expression, two kinds of errors can be thrown: a syntax error (for which the parser cannot recover) or an unknown variable/function error (which does not block the parser).

When linting an expression, currently you can ignore unknown variables by passing `null` instead of the valid variable names to `lint()` or `parse()`, but you cannot ignore unknown functions. For some use cases, it might be needed to just validate the syntax.

This PR allows developers to ignore functions and/or variables the "proper way" with flags as a new argument to these methods:

```php
$parser->lint($expr, flags: Parser::IGNORE_UNKNOWN_FUNCTIONS | Parser::IGNORE_UNKNOWN_VARIABLES);
$parser->parse($expr, flags: Parser::IGNORE_UNKNOWN_FUNCTIONS | Parser::IGNORE_UNKNOWN_VARIABLES);
```

Passing `null` to the `$names` argument is deprecated:

**Before**:
```php
$parser->lint($expr, null);
```

**After**:

```php
$parser->lint($expr, flags: Parser::IGNORE_UNKNOWN_VARIABLES);
```

Commits
-------

c6182c0 [ExpressionLanguage] Add more configurability to the parsing/linting methods
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Symfony Expression: Parse without context
5 participants