Skip to content

Commit 570d6c9

Browse files
committed
cache earlier
1 parent 60ead9a commit 570d6c9

File tree

1 file changed

+31
-21
lines changed

1 file changed

+31
-21
lines changed

src/Type/Regex/RegexGroupParser.php

Lines changed: 31 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
use PHPStan\Type\StringType;
2222
use PHPStan\Type\Type;
2323
use PHPStan\Type\TypeCombinator;
24+
use function array_key_exists;
2425
use function array_values;
2526
use function count;
2627
use function in_array;
@@ -44,7 +45,7 @@ final class RegexGroupParser
4445

4546
private static ?Parser $parser = null;
4647

47-
/** @var array<string, TreeNode> */
48+
/** @var array<string, ?TreeNode> */
4849
private static array $parsedAst = [];
4950

5051
public function __construct(
@@ -59,30 +60,39 @@ public function parseGroups(string $regex): ?RegexAstWalkResult
5960
/** @throws void */
6061
self::$parser ??= Llk::load(new Read(__DIR__ . '/../../../resources/RegexGrammar.pp'));
6162

62-
try {
63-
Strings::match('', $regex);
64-
} catch (RegexpException) {
65-
// pattern is invalid, so let the RegularExpressionPatternRule report it
66-
return null;
67-
}
68-
69-
$modifiers = $this->regexExpressionHelper->getPatternModifiers($regex) ?? '';
70-
foreach (self::NOT_SUPPORTED_MODIFIERS as $notSupportedModifier) {
71-
if (str_contains($modifiers, $notSupportedModifier)) {
63+
if (array_key_exists($regex, self::$parsedAst)) {
64+
$ast = self::$parsedAst[$regex];
65+
if ($ast === null) {
7266
return null;
7367
}
74-
}
7568

76-
if (str_contains($modifiers, 'x')) {
77-
// in freespacing mode the # character starts a comment and runs until the end of the line
78-
$regex = preg_replace('/(?<!\?)#.*/', '', $regex) ?? '';
79-
}
69+
$modifiers = $this->regexExpressionHelper->getPatternModifiers($regex) ?? '';
70+
} else {
71+
try {
72+
Strings::match('', $regex);
73+
} catch (RegexpException) {
74+
// pattern is invalid, so let the RegularExpressionPatternRule report it
75+
return self::$parsedAst[$regex] = null;
76+
}
8077

81-
$rawRegex = $this->regexExpressionHelper->removeDelimitersAndModifiers($regex);
82-
try {
83-
$ast = self::$parsedAst[$rawRegex] ??= self::$parser->parse($rawRegex);
84-
} catch (Exception) {
85-
return null;
78+
$modifiers = $this->regexExpressionHelper->getPatternModifiers($regex) ?? '';
79+
foreach (self::NOT_SUPPORTED_MODIFIERS as $notSupportedModifier) {
80+
if (str_contains($modifiers, $notSupportedModifier)) {
81+
return self::$parsedAst[$regex] = null;
82+
}
83+
}
84+
85+
if (str_contains($modifiers, 'x')) {
86+
// in freespacing mode the # character starts a comment and runs until the end of the line
87+
$regex = preg_replace('/(?<!\?)#.*/', '', $regex) ?? '';
88+
}
89+
90+
$rawRegex = $this->regexExpressionHelper->removeDelimitersAndModifiers($regex);
91+
try {
92+
$ast = self::$parsedAst[$regex] = self::$parser->parse($rawRegex);
93+
} catch (Exception) {
94+
return self::$parsedAst[$regex] = null;
95+
}
8696
}
8797

8898
$this->updateAlternationAstRemoveVerticalBarsAndAddEmptyToken($ast);

0 commit comments

Comments
 (0)