Skip to content

Commit 356250a

Browse files
authored
Feature/undefined expression allowed
1 parent 1cdd9ba commit 356250a

16 files changed

+268
-67
lines changed

src/Analyser/DirectScopeFactory.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ public function __construct(
5151
* @param VariableTypeHolder[] $moreSpecificTypes
5252
* @param array<string, ConditionalExpressionHolder[]> $conditionalExpressions
5353
* @param array<string, true> $currentlyAssignedExpressions
54+
* @param array<string, bool> $currentlyAllowedUndefinedExpressions
5455
* @param array<string, Type> $nativeExpressionTypes
5556
* @param array<(FunctionReflection|MethodReflection)> $inFunctionCallsStack
5657
*
@@ -68,6 +69,7 @@ public function create(
6869
?ParametersAcceptor $anonymousFunctionReflection = null,
6970
bool $inFirstLevelStatement = true,
7071
array $currentlyAssignedExpressions = [],
72+
array $currentlyAllowedUndefinedExpressions = [],
7173
array $nativeExpressionTypes = [],
7274
array $inFunctionCallsStack = [],
7375
bool $afterExtractCall = false,
@@ -102,6 +104,7 @@ public function create(
102104
$anonymousFunctionReflection,
103105
$inFirstLevelStatement,
104106
$currentlyAssignedExpressions,
107+
$currentlyAllowedUndefinedExpressions,
105108
$nativeExpressionTypes,
106109
$inFunctionCallsStack,
107110
$this->dynamicConstantNames,

src/Analyser/LazyScopeFactory.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ public function __construct(
4242
* @param VariableTypeHolder[] $moreSpecificTypes
4343
* @param array<string, ConditionalExpressionHolder[]> $conditionalExpressions
4444
* @param array<string, true> $currentlyAssignedExpressions
45+
* @param array<string, bool> $currentlyAllowedUndefinedExpressions
4546
* @param array<string, Type> $nativeExpressionTypes
4647
* @param array<(FunctionReflection|MethodReflection)> $inFunctionCallsStack
4748
*
@@ -59,6 +60,7 @@ public function create(
5960
?ParametersAcceptor $anonymousFunctionReflection = null,
6061
bool $inFirstLevelStatement = true,
6162
array $currentlyAssignedExpressions = [],
63+
array $currentlyAllowedUndefinedExpressions = [],
6264
array $nativeExpressionTypes = [],
6365
array $inFunctionCallsStack = [],
6466
bool $afterExtractCall = false,
@@ -93,6 +95,7 @@ public function create(
9395
$anonymousFunctionReflection,
9496
$inFirstLevelStatement,
9597
$currentlyAssignedExpressions,
98+
$currentlyAllowedUndefinedExpressions,
9699
$nativeExpressionTypes,
97100
$inFunctionCallsStack,
98101
$this->dynamicConstantNames,

src/Analyser/MutatingScope.php

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,7 @@ class MutatingScope implements Scope
167167
* @param VariableTypeHolder[] $moreSpecificTypes
168168
* @param array<string, ConditionalExpressionHolder[]> $conditionalExpressions
169169
* @param array<string, true> $currentlyAssignedExpressions
170+
* @param array<string, bool> $currentlyAllowedUndefinedExpressions
170171
* @param array<string, Type> $nativeExpressionTypes
171172
* @param array<MethodReflection|FunctionReflection> $inFunctionCallsStack
172173
* @param string[] $dynamicConstantNames
@@ -194,6 +195,7 @@ public function __construct(
194195
private ?ParametersAcceptor $anonymousFunctionReflection = null,
195196
private bool $inFirstLevelStatement = true,
196197
private array $currentlyAssignedExpressions = [],
198+
private array $currentlyAllowedUndefinedExpressions = [],
197199
private array $nativeExpressionTypes = [],
198200
private array $inFunctionCallsStack = [],
199201
private array $dynamicConstantNames = [],
@@ -341,6 +343,7 @@ public function afterExtractCall(): self
341343
$this->anonymousFunctionReflection,
342344
$this->isInFirstLevelStatement(),
343345
$this->currentlyAssignedExpressions,
346+
$this->currentlyAllowedUndefinedExpressions,
344347
$this->nativeExpressionTypes,
345348
$this->inFunctionCallsStack,
346349
true,
@@ -397,6 +400,7 @@ public function afterClearstatcacheCall(): self
397400
$this->anonymousFunctionReflection,
398401
$this->isInFirstLevelStatement(),
399402
$this->currentlyAssignedExpressions,
403+
$this->currentlyAllowedUndefinedExpressions,
400404
$this->nativeExpressionTypes,
401405
$this->inFunctionCallsStack,
402406
$this->afterExtractCall,
@@ -3016,6 +3020,7 @@ public function doNotTreatPhpDocTypesAsCertain(): Scope
30163020
$this->anonymousFunctionReflection,
30173021
$this->inFirstLevelStatement,
30183022
$this->currentlyAssignedExpressions,
3023+
$this->currentlyAllowedUndefinedExpressions,
30193024
$this->nativeExpressionTypes,
30203025
$this->inFunctionCallsStack,
30213026
$this->dynamicConstantNames,
@@ -3056,6 +3061,7 @@ private function promoteNativeTypes(): self
30563061
$this->anonymousFunctionReflection,
30573062
$this->inFirstLevelStatement,
30583063
$this->currentlyAssignedExpressions,
3064+
$this->currentlyAllowedUndefinedExpressions,
30593065
[],
30603066
);
30613067
}
@@ -3315,6 +3321,7 @@ public function pushInFunctionCall($reflection): self
33153321
$this->anonymousFunctionReflection,
33163322
$this->isInFirstLevelStatement(),
33173323
$this->currentlyAssignedExpressions,
3324+
$this->currentlyAllowedUndefinedExpressions,
33183325
$this->nativeExpressionTypes,
33193326
$stack,
33203327
$this->afterExtractCall,
@@ -3340,6 +3347,7 @@ public function popInFunctionCall(): self
33403347
$this->anonymousFunctionReflection,
33413348
$this->isInFirstLevelStatement(),
33423349
$this->currentlyAssignedExpressions,
3350+
$this->currentlyAllowedUndefinedExpressions,
33433351
$this->nativeExpressionTypes,
33443352
$stack,
33453353
$this->afterExtractCall,
@@ -3596,6 +3604,7 @@ private function enterFunctionLike(
35963604
null,
35973605
true,
35983606
[],
3607+
[],
35993608
$nativeExpressionTypes,
36003609
);
36013610
}
@@ -3716,6 +3725,7 @@ public function enterAnonymousFunction(
37163725
$anonymousFunctionReflection,
37173726
true,
37183727
[],
3728+
[],
37193729
$scope->nativeExpressionTypes,
37203730
[],
37213731
false,
@@ -3807,6 +3817,7 @@ private function enterAnonymousFunctionWithoutReflection(
38073817
new TrivialParametersAcceptor(),
38083818
true,
38093819
[],
3820+
[],
38103821
$nativeTypes,
38113822
[],
38123823
false,
@@ -3842,6 +3853,7 @@ public function enterArrowFunction(Expr\ArrowFunction $arrowFunction, ?array $ca
38423853
[],
38433854
[],
38443855
[],
3856+
[],
38453857
$scope->afterExtractCall,
38463858
$scope->parentScope,
38473859
);
@@ -3962,6 +3974,7 @@ private function enterArrowFunctionWithoutReflection(Expr\ArrowFunction $arrowFu
39623974
[],
39633975
[],
39643976
[],
3977+
[],
39653978
$this->afterExtractCall,
39663979
$this->parentScope,
39673980
);
@@ -4089,6 +4102,7 @@ public function enterExpressionAssign(Expr $expr): self
40894102
$this->anonymousFunctionReflection,
40904103
$this->isInFirstLevelStatement(),
40914104
$currentlyAssignedExpressions,
4105+
$this->currentlyAllowedUndefinedExpressions,
40924106
$this->nativeExpressionTypes,
40934107
[],
40944108
$this->afterExtractCall,
@@ -4115,6 +4129,7 @@ public function exitExpressionAssign(Expr $expr): self
41154129
$this->anonymousFunctionReflection,
41164130
$this->isInFirstLevelStatement(),
41174131
$currentlyAssignedExpressions,
4132+
$this->currentlyAllowedUndefinedExpressions,
41184133
$this->nativeExpressionTypes,
41194134
[],
41204135
$this->afterExtractCall,
@@ -4129,6 +4144,70 @@ public function isInExpressionAssign(Expr $expr): bool
41294144
return array_key_exists($exprString, $this->currentlyAssignedExpressions);
41304145
}
41314146

4147+
public function setAllowedUndefinedExpression(Expr $expr, bool $isAllowed): self
4148+
{
4149+
$exprString = $this->getNodeKey($expr);
4150+
if (array_key_exists($exprString, $this->currentlyAllowedUndefinedExpressions)) {
4151+
return $this;
4152+
}
4153+
$currentlyAllowedUndefinedExpressions = $this->currentlyAllowedUndefinedExpressions;
4154+
$currentlyAllowedUndefinedExpressions[$exprString] = $isAllowed;
4155+
4156+
return $this->scopeFactory->create(
4157+
$this->context,
4158+
$this->isDeclareStrictTypes(),
4159+
$this->constantTypes,
4160+
$this->getFunction(),
4161+
$this->getNamespace(),
4162+
$this->getVariableTypes(),
4163+
$this->moreSpecificTypes,
4164+
$this->conditionalExpressions,
4165+
$this->inClosureBindScopeClass,
4166+
$this->anonymousFunctionReflection,
4167+
$this->isInFirstLevelStatement(),
4168+
$this->currentlyAssignedExpressions,
4169+
$currentlyAllowedUndefinedExpressions,
4170+
$this->nativeExpressionTypes,
4171+
[],
4172+
$this->afterExtractCall,
4173+
$this->parentScope,
4174+
);
4175+
}
4176+
4177+
public function unsetAllowedUndefinedExpression(Expr $expr): self
4178+
{
4179+
$exprString = $this->getNodeKey($expr);
4180+
$currentlyAllowedUndefinedExpressions = $this->currentlyAllowedUndefinedExpressions;
4181+
unset($currentlyAllowedUndefinedExpressions[$exprString]);
4182+
4183+
return $this->scopeFactory->create(
4184+
$this->context,
4185+
$this->isDeclareStrictTypes(),
4186+
$this->constantTypes,
4187+
$this->getFunction(),
4188+
$this->getNamespace(),
4189+
$this->getVariableTypes(),
4190+
$this->moreSpecificTypes,
4191+
$this->conditionalExpressions,
4192+
$this->inClosureBindScopeClass,
4193+
$this->anonymousFunctionReflection,
4194+
$this->isInFirstLevelStatement(),
4195+
$this->currentlyAssignedExpressions,
4196+
$currentlyAllowedUndefinedExpressions,
4197+
$this->nativeExpressionTypes,
4198+
[],
4199+
$this->afterExtractCall,
4200+
$this->parentScope,
4201+
);
4202+
}
4203+
4204+
/** @api */
4205+
public function isUndefinedExpressionAllowed(Expr $expr): bool
4206+
{
4207+
$exprString = $this->getNodeKey($expr);
4208+
return array_key_exists($exprString, $this->currentlyAllowedUndefinedExpressions) && $this->currentlyAllowedUndefinedExpressions[$exprString];
4209+
}
4210+
41324211
public function assignVariable(string $variableName, Type $type, ?TrinaryLogic $certainty = null): self
41334212
{
41344213
if ($certainty === null) {
@@ -4191,6 +4270,7 @@ public function assignVariable(string $variableName, Type $type, ?TrinaryLogic $
41914270
$this->anonymousFunctionReflection,
41924271
$this->inFirstLevelStatement,
41934272
$this->currentlyAssignedExpressions,
4273+
$this->currentlyAllowedUndefinedExpressions,
41944274
$nativeTypes,
41954275
$this->inFunctionCallsStack,
41964276
$this->afterExtractCall,
@@ -4227,6 +4307,7 @@ public function unsetExpression(Expr $expr): self
42274307
$this->anonymousFunctionReflection,
42284308
$this->inFirstLevelStatement,
42294309
[],
4310+
[],
42304311
$nativeTypes,
42314312
[],
42324313
$this->afterExtractCall,
@@ -4270,6 +4351,7 @@ public function specifyExpressionType(Expr $expr, Type $type, ?Type $nativeType
42704351
$this->anonymousFunctionReflection,
42714352
$this->inFirstLevelStatement,
42724353
$this->currentlyAssignedExpressions,
4354+
$this->currentlyAllowedUndefinedExpressions,
42734355
$this->nativeExpressionTypes,
42744356
$this->inFunctionCallsStack,
42754357
$this->afterExtractCall,
@@ -4308,6 +4390,7 @@ public function specifyExpressionType(Expr $expr, Type $type, ?Type $nativeType
43084390
$this->anonymousFunctionReflection,
43094391
$this->inFirstLevelStatement,
43104392
$this->currentlyAssignedExpressions,
4393+
$this->currentlyAllowedUndefinedExpressions,
43114394
$nativeTypes,
43124395
$this->inFunctionCallsStack,
43134396
$this->afterExtractCall,
@@ -4425,6 +4508,7 @@ public function invalidateExpression(Expr $expressionToInvalidate, bool $require
44254508
$this->anonymousFunctionReflection,
44264509
$this->inFirstLevelStatement,
44274510
$this->currentlyAssignedExpressions,
4511+
$this->currentlyAllowedUndefinedExpressions,
44284512
$nativeExpressionTypes,
44294513
[],
44304514
$this->afterExtractCall,
@@ -4483,6 +4567,7 @@ public function invalidateMethodsOnExpression(Expr $expressionToInvalidate): sel
44834567
$this->anonymousFunctionReflection,
44844568
$this->inFirstLevelStatement,
44854569
$this->currentlyAssignedExpressions,
4570+
$this->currentlyAllowedUndefinedExpressions,
44864571
$nativeExpressionTypes,
44874572
[],
44884573
$this->afterExtractCall,
@@ -4700,6 +4785,7 @@ public function changeConditionalExpressions(array $newConditionalExpressionHold
47004785
$this->anonymousFunctionReflection,
47014786
$this->inFirstLevelStatement,
47024787
$this->currentlyAssignedExpressions,
4788+
$this->currentlyAllowedUndefinedExpressions,
47034789
$this->nativeExpressionTypes,
47044790
$this->inFunctionCallsStack,
47054791
$this->afterExtractCall,
@@ -4727,6 +4813,7 @@ public function addConditionalExpressions(string $exprString, array $conditional
47274813
$this->anonymousFunctionReflection,
47284814
$this->inFirstLevelStatement,
47294815
$this->currentlyAssignedExpressions,
4816+
$this->currentlyAllowedUndefinedExpressions,
47304817
$this->nativeExpressionTypes,
47314818
$this->inFunctionCallsStack,
47324819
$this->afterExtractCall,
@@ -4749,6 +4836,7 @@ public function exitFirstLevelStatements(): self
47494836
$this->anonymousFunctionReflection,
47504837
false,
47514838
$this->currentlyAssignedExpressions,
4839+
$this->currentlyAllowedUndefinedExpressions,
47524840
$this->nativeExpressionTypes,
47534841
$this->inFunctionCallsStack,
47544842
$this->afterExtractCall,
@@ -4786,6 +4874,7 @@ private function addMoreSpecificTypes(array $types): self
47864874
$this->anonymousFunctionReflection,
47874875
$this->inFirstLevelStatement,
47884876
$this->currentlyAssignedExpressions,
4877+
$this->currentlyAllowedUndefinedExpressions,
47894878
$this->nativeExpressionTypes,
47904879
[],
47914880
$this->afterExtractCall,
@@ -4854,6 +4943,7 @@ public function mergeWith(?self $otherScope): self
48544943
$this->anonymousFunctionReflection,
48554944
$this->inFirstLevelStatement,
48564945
[],
4946+
[],
48574947
array_map($variableHolderToType, array_filter($this->mergeVariableHolders(
48584948
array_map($typeToVariableHolder, $this->nativeExpressionTypes),
48594949
array_map($typeToVariableHolder, $otherScope->nativeExpressionTypes),
@@ -5025,6 +5115,7 @@ public function processFinallyScope(self $finallyScope, self $originalFinallySco
50255115
$this->anonymousFunctionReflection,
50265116
$this->inFirstLevelStatement,
50275117
[],
5118+
[],
50285119
array_map($variableHolderToType, array_filter($this->processFinallyScopeVariableTypeHolders(
50295120
array_map($typeToVariableHolder, $this->nativeExpressionTypes),
50305121
array_map($typeToVariableHolder, $finallyScope->nativeExpressionTypes),
@@ -5122,6 +5213,7 @@ public function processClosureScope(
51225213
$this->anonymousFunctionReflection,
51235214
$this->inFirstLevelStatement,
51245215
[],
5216+
[],
51255217
$nativeExpressionTypes,
51265218
$this->inFunctionCallsStack,
51275219
$this->afterExtractCall,
@@ -5172,6 +5264,7 @@ public function processAlwaysIterableForeachScopeWithoutPollute(self $finalScope
51725264
$this->anonymousFunctionReflection,
51735265
$this->inFirstLevelStatement,
51745266
[],
5267+
[],
51755268
$nativeTypes,
51765269
[],
51775270
$this->afterExtractCall,
@@ -5215,6 +5308,7 @@ public function generalizeWith(self $otherScope): self
52155308
$this->anonymousFunctionReflection,
52165309
$this->inFirstLevelStatement,
52175310
[],
5311+
[],
52185312
$nativeTypes,
52195313
[],
52205314
$this->afterExtractCall,

0 commit comments

Comments
 (0)