-
Notifications
You must be signed in to change notification settings - Fork 471
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
Implement array shapes for preg_match()
$matches
by-ref parameter
#2589
Merged
Merged
Changes from all commits
Commits
Show all changes
55 commits
Select commit
Hold shift + click to select a range
8a6bc34
Implement array shapes for preg_match()
staabm 633a661
added tests
staabm d922a1b
fix regex pattern
staabm 1775cce
fix group name
staabm 32b3a9c
Fix PHP < 7.4
staabm a15d5bd
fix tests per php version
staabm 6ae9639
add more tests
staabm 3df46e8
added more tests
staabm c58a990
moved php 8.2 only test
staabm 68ada66
patch Grammer.pp to support capturing groups
staabm 4f03514
ast
staabm 53ec814
fix
staabm d4b7cd0
fix
staabm 43d496d
fix
staabm 887e6a5
fix
staabm c361855
fix
staabm 25e7940
refactor
staabm 8c61968
Update preg_match_shapes_php82.php
staabm 1c52274
fix build
staabm 96780ce
Update composer.lock
staabm d782ab3
fix hoa/regex parseable named captures
staabm 3dd7fc5
Prevent "Call to function preg_match() with arguments '/^(?<name>\\S+…
staabm 5387535
Fix hoa/regex bug31
staabm e03f6b1
read the grammar only once
staabm 45f9ab3
simplify
staabm cce33a5
remove outdated comment
staabm 71f409d
fix test typo
staabm 25de902
test more quantifiers
staabm e1e33be
test hoa/regex unsupported regex syntax
staabm 5afdf6f
enable only in bleeding edge
staabm 85cff74
use nette/utils
staabm 1650b00
refactor into service
staabm 6e246e2
fix dash outside of capturing group
staabm 1c977c8
decouple RegexArrayShapeMatcher from TypeSpecifierContext
staabm 6cae0ac
use separate feature flag
staabm 7fca860
move NodeScopeResolverTest-tests into "nsrt"
staabm 11512bb
Implement additional PregMatchParameterOutTypeExtension
staabm 5334cfd
utlize feature flag
staabm bf66341
Update composer.lock
staabm f85da99
Update PregMatchParameterOutTypeExtension.php
staabm da8653d
Update composer.lock
staabm eb76681
Update composer.lock
staabm f8b9b8a
cs
staabm ae0b208
use conditionalTags
staabm 6ae7dda
Update preg_match_shapes.php
staabm 84a4ca1
Improve negative context inference
staabm 28103f8
separate php 7.x expectations
staabm 891a631
php 7.2/7.3 expectation fixes
staabm c073c6a
fix phpstan
staabm db824cd
Update LegacyNodeScopeResolverTest.php
staabm d74d107
move test into separate file
staabm 1ccfcfe
turn test into a php 7.3 only test
staabm 71f4223
Update preg_match_shapes_php73.php
staabm 328fcb9
TypeSpecifier - understand `preg_match() === 1` same way as `preg_mat…
ondrejmirtes cf3fc13
PHPStan fix
ondrejmirtes File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
--- Grammar.pp 2024-05-18 12:15:53 | ||
+++ Grammar.pp.fix 2024-05-18 12:15:05 | ||
@@ -109,7 +109,7 @@ | ||
// Please, see PCRESYNTAX(3), General Category properties, PCRE special category | ||
// properties and script names for \p{} and \P{}. | ||
%token character_type \\([CdDhHNRsSvVwWX]|[pP]{[^}]+}) | ||
-%token anchor \\(bBAZzG)|\^|\$ | ||
+%token anchor \\([bBAZzG])|\^|\$ | ||
%token match_point_reset \\K | ||
%token literal \\.|. | ||
|
||
@@ -168,7 +168,7 @@ | ||
::negative_class_:: #negativeclass | ||
| ::class_:: | ||
) | ||
- ( range() | literal() )+ | ||
+ ( <class_> | range() | literal() )+ | ||
::_class:: | ||
|
||
#range: | ||
@@ -178,7 +178,7 @@ | ||
capturing() | ||
| literal() | ||
|
||
-capturing: | ||
+#capturing: | ||
Comment on lines
+25
to
+26
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. upstream hoa fix |
||
::comment_:: <comment>? ::_comment:: #comment | ||
| ( | ||
::named_capturing_:: <capturing_name> ::_named_capturing:: #namedcapturing | ||
@@ -191,6 +191,7 @@ | ||
|
||
literal: | ||
<character> | ||
+ | <range> | ||
| <dynamic_character> | ||
| <character_type> | ||
| <anchor> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
<?php declare(strict_types = 1); | ||
|
||
namespace PHPStan\Type\Php; | ||
|
||
use PhpParser\Node\Expr\FuncCall; | ||
use PHPStan\Analyser\Scope; | ||
use PHPStan\Reflection\FunctionReflection; | ||
use PHPStan\Reflection\ParameterReflection; | ||
use PHPStan\TrinaryLogic; | ||
use PHPStan\Type\FunctionParameterOutTypeExtension; | ||
use PHPStan\Type\Type; | ||
use function in_array; | ||
use function strtolower; | ||
|
||
final class PregMatchParameterOutTypeExtension implements FunctionParameterOutTypeExtension | ||
{ | ||
|
||
public function __construct( | ||
private RegexArrayShapeMatcher $regexShapeMatcher, | ||
) | ||
{ | ||
} | ||
|
||
public function isFunctionSupported(FunctionReflection $functionReflection, ParameterReflection $parameter): bool | ||
{ | ||
return in_array(strtolower($functionReflection->getName()), ['preg_match'], true) && $parameter->getName() === 'matches'; | ||
} | ||
|
||
public function getParameterOutTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $funcCall, ParameterReflection $parameter, Scope $scope): ?Type | ||
{ | ||
$args = $funcCall->getArgs(); | ||
$patternArg = $args[0] ?? null; | ||
$matchesArg = $args[2] ?? null; | ||
$flagsArg = $args[3] ?? null; | ||
|
||
if ( | ||
$patternArg === null || $matchesArg === null | ||
) { | ||
return null; | ||
} | ||
|
||
$patternType = $scope->getType($patternArg->value); | ||
$flagsType = null; | ||
if ($flagsArg !== null) { | ||
$flagsType = $scope->getType($flagsArg->value); | ||
} | ||
|
||
return $this->regexShapeMatcher->matchType($patternType, $flagsType, TrinaryLogic::createMaybe()); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
<?php declare(strict_types = 1); | ||
|
||
namespace PHPStan\Type\Php; | ||
|
||
use PhpParser\Node\Expr\FuncCall; | ||
use PHPStan\Analyser\Scope; | ||
use PHPStan\Analyser\SpecifiedTypes; | ||
use PHPStan\Analyser\TypeSpecifier; | ||
use PHPStan\Analyser\TypeSpecifierAwareExtension; | ||
use PHPStan\Analyser\TypeSpecifierContext; | ||
use PHPStan\Reflection\FunctionReflection; | ||
use PHPStan\TrinaryLogic; | ||
use PHPStan\Type\FunctionTypeSpecifyingExtension; | ||
use function in_array; | ||
use function strtolower; | ||
|
||
final class PregMatchTypeSpecifyingExtension implements FunctionTypeSpecifyingExtension, TypeSpecifierAwareExtension | ||
{ | ||
|
||
private TypeSpecifier $typeSpecifier; | ||
|
||
public function __construct( | ||
private RegexArrayShapeMatcher $regexShapeMatcher, | ||
) | ||
{ | ||
} | ||
|
||
public function setTypeSpecifier(TypeSpecifier $typeSpecifier): void | ||
{ | ||
$this->typeSpecifier = $typeSpecifier; | ||
} | ||
|
||
public function isFunctionSupported(FunctionReflection $functionReflection, FuncCall $node, TypeSpecifierContext $context): bool | ||
{ | ||
return in_array(strtolower($functionReflection->getName()), ['preg_match'], true) && !$context->null(); | ||
} | ||
|
||
public function specifyTypes(FunctionReflection $functionReflection, FuncCall $node, Scope $scope, TypeSpecifierContext $context): SpecifiedTypes | ||
{ | ||
$args = $node->getArgs(); | ||
$patternArg = $args[0] ?? null; | ||
$matchesArg = $args[2] ?? null; | ||
$flagsArg = $args[3] ?? null; | ||
|
||
if ( | ||
$patternArg === null || $matchesArg === null | ||
) { | ||
return new SpecifiedTypes(); | ||
} | ||
|
||
$patternType = $scope->getType($patternArg->value); | ||
$flagsType = null; | ||
if ($flagsArg !== null) { | ||
$flagsType = $scope->getType($flagsArg->value); | ||
} | ||
|
||
$matchedType = $this->regexShapeMatcher->matchType($patternType, $flagsType, TrinaryLogic::createFromBoolean($context->true())); | ||
if ($matchedType === null) { | ||
return new SpecifiedTypes(); | ||
} | ||
|
||
$overwrite = false; | ||
if ($context->false()) { | ||
$overwrite = true; | ||
$context = $context->negate(); | ||
} | ||
|
||
return $this->typeSpecifier->create( | ||
$matchesArg->value, | ||
$matchedType, | ||
$context, | ||
$overwrite, | ||
$scope, | ||
$node, | ||
); | ||
} | ||
|
||
} |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
unreleased hoa/regex upstream fix
hoaproject/Regex@5f670af