Skip to content

Add StrictComparisonOperatorRule#443

Open
HSAIG wants to merge 1 commit intoVincentLanglet:mainfrom
HSAIG:feature/strict-comparison-operator-rule
Open

Add StrictComparisonOperatorRule#443
HSAIG wants to merge 1 commit intoVincentLanglet:mainfrom
HSAIG:feature/strict-comparison-operator-rule

Conversation

@HSAIG
Copy link
Copy Markdown

@HSAIG HSAIG commented Mar 27, 2026

Add StrictComparisonOperatorRule

Summary

This PR introduces a new optional fixable rule: StrictComparisonOperatorRule.

It replaces Twig strict comparison tests:

  • is same as(...)===
  • is not same as(...)!==

Motivation

Twig 3.23 introduced === and !== as strict comparison operators.

Using these operators improves readability and aligns Twig syntax with PHP and JavaScript.

Details

  • The rule should be optional
  • It only applies to explicit same as / not same as cases
  • It is intended for projects using Twig >= 3.23

Example

Before

{% if foo is same as(bar) %}
{% endif %}

After

{% if foo === bar %}
{% endif %}

}

$sameAsToken = $tokens->get($sameAsIndex);
$targetIndex = $sameAsIndex;
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

I don't understand the need of this new variable.


$isNegated = $token->isMatching(Token::OPERATOR_TYPE, 'is not');

$sameAsIndex = $tokens->findNext(Token::WHITESPACE_TOKENS, $tokenIndex + 1, exclude: true);
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Exclude EMPTY_TOKENS rather than WHITESPACE.

Cause here you don't support someone with an indent in the middle of the code or a new line. (And add test with this case)

return;
}

$asIndex = $tokens->findNext(Token::WHITESPACE_TOKENS, $targetIndex + 1, exclude: true);
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Exclude EMPTY_TOKENS rather than WHITESPACE.

Cause here you don't support someone with an indent in the middle of the code or a new line. (And add test with this case)

}

$openParenthesisIndex = $tokens->findNext(Token::WHITESPACE_TOKENS, $asIndex + 1, exclude: true);
if (false === $openParenthesisIndex || !$tokens->get($openParenthesisIndex)->isMatching(Token::PUNCTUATION_TYPE, '(')) {
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

You cannot return if there is no punctuation since

{% if foo is same as bar %}

is a valid syntax similar to

{% if foo is same as(bar) %}

}

$fixer = $this->addFixableError(
'Use strict comparison operators === / !== instead of same as / not same as.',
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

I prefer a specific message

'Use strict comparison operators === instead of same as.',

or

'Use strict comparison operators !== instead of not same as.',

based on the situation

return;
}

$closeParenthesisIndex = $this->findMatchingParenthesis($tokens, $openParenthesisIndex);
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

You shouldn't have to do this, there is $token->getRelatedToken() to get the related parenthesis


$fixer->beginChangeSet();

$replacement = $isNegated ? '!==' : '===';
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

This one time var is useless

Comment on lines +72 to +76
// We want only one whitespace between the operator and the parenthesis content.
// If there is already a whitespace between "as" and "(", we can remove the "(".
// Otherwise, we replace "(" by a whitespace.
$hasWhitespaceBeforeParen = $tokens->get($openParenthesisIndex - 1)->isMatching(Token::WHITESPACE_TOKENS);
$fixer->replaceToken($openParenthesisIndex, $hasWhitespaceBeforeParen ? '' : ' ');
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

I wouldn't do any of this here and rely on other fixers.

Once same as(foo) is fixed into ===foo the whitespace fixer will change it into === foo.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants