Skip to content

Commit 78a9f05

Browse files
committed
Bleeding edge - new $string leads to object, not mixed
1 parent fa9ee15 commit 78a9f05

File tree

6 files changed

+28
-1
lines changed

6 files changed

+28
-1
lines changed

conf/bleedingEdge.neon

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,4 @@ parameters:
1414
checkMissingTemplateTypeInParameter: true
1515
wrongVarUsage: true
1616
arrayDestructuring: true
17+
objectFromNewClass: true

conf/config.neon

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ parameters:
2727
checkMissingTemplateTypeInParameter: false
2828
wrongVarUsage: false
2929
arrayDestructuring: false
30+
objectFromNewClass: false
3031
fileExtensions:
3132
- php
3233
checkAlwaysTrueCheckTypeFunctionCall: false
@@ -180,7 +181,8 @@ parametersSchema:
180181
checkLogicalOrConstantCondition: bool(),
181182
checkMissingTemplateTypeInParameter: bool(),
182183
wrongVarUsage: bool(),
183-
arrayDestructuring: bool()
184+
arrayDestructuring: bool(),
185+
objectFromNewClass: bool()
184186
])
185187
fileExtensions: listOf(string())
186188
checkAlwaysTrueCheckTypeFunctionCall: bool()

src/Analyser/DirectScopeFactory.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ class DirectScopeFactory implements ScopeFactory
3636

3737
private bool $treatPhpDocTypesAsCertain;
3838

39+
private bool $objectFromNewClass;
40+
3941
/** @var string[] */
4042
private array $dynamicConstantNames;
4143

@@ -50,6 +52,7 @@ public function __construct(
5052
\PHPStan\Parser\Parser $parser,
5153
NodeScopeResolver $nodeScopeResolver,
5254
bool $treatPhpDocTypesAsCertain,
55+
bool $objectFromNewClass,
5356
Container $container
5457
)
5558
{
@@ -63,6 +66,7 @@ public function __construct(
6366
$this->parser = $parser;
6467
$this->nodeScopeResolver = $nodeScopeResolver;
6568
$this->treatPhpDocTypesAsCertain = $treatPhpDocTypesAsCertain;
69+
$this->objectFromNewClass = $objectFromNewClass;
6670
$this->dynamicConstantNames = $container->getParameter('dynamicConstantNames');
6771
}
6872

@@ -136,6 +140,7 @@ public function create(
136140
$inFunctionCallsStack,
137141
$this->dynamicConstantNames,
138142
$this->treatPhpDocTypesAsCertain,
143+
$this->objectFromNewClass,
139144
$afterExtractCall,
140145
$parentScope
141146
);

src/Analyser/LazyScopeFactory.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ class LazyScopeFactory implements ScopeFactory
2323

2424
private bool $treatPhpDocTypesAsCertain;
2525

26+
private bool $objectFromNewClass;
27+
2628
public function __construct(
2729
string $scopeClass,
2830
Container $container
@@ -32,6 +34,7 @@ public function __construct(
3234
$this->container = $container;
3335
$this->dynamicConstantNames = $container->getParameter('dynamicConstantNames');
3436
$this->treatPhpDocTypesAsCertain = $container->getParameter('treatPhpDocTypesAsCertain');
37+
$this->objectFromNewClass = $container->getParameter('featureToggles')['objectFromNewClass'];
3538
}
3639

3740
/**
@@ -104,6 +107,7 @@ public function create(
104107
$inFunctionCallsStack,
105108
$this->dynamicConstantNames,
106109
$this->treatPhpDocTypesAsCertain,
110+
$this->objectFromNewClass,
107111
$afterExtractCall,
108112
$parentScope
109113
);

src/Analyser/MutatingScope.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,8 @@ class MutatingScope implements Scope
165165

166166
private bool $treatPhpDocTypesAsCertain;
167167

168+
private bool $objectFromNewClass;
169+
168170
private bool $afterExtractCall;
169171

170172
private ?Scope $parentScope;
@@ -195,6 +197,7 @@ class MutatingScope implements Scope
195197
* @param array<MethodReflection|FunctionReflection> $inFunctionCallsStack
196198
* @param string[] $dynamicConstantNames
197199
* @param bool $treatPhpDocTypesAsCertain
200+
* @param bool $objectFromNewClass
198201
* @param bool $afterExtractCall
199202
* @param Scope|null $parentScope
200203
*/
@@ -224,6 +227,7 @@ public function __construct(
224227
array $inFunctionCallsStack = [],
225228
array $dynamicConstantNames = [],
226229
bool $treatPhpDocTypesAsCertain = true,
230+
bool $objectFromNewClass = false,
227231
bool $afterExtractCall = false,
228232
?Scope $parentScope = null
229233
)
@@ -257,6 +261,7 @@ public function __construct(
257261
$this->inFunctionCallsStack = $inFunctionCallsStack;
258262
$this->dynamicConstantNames = $dynamicConstantNames;
259263
$this->treatPhpDocTypesAsCertain = $treatPhpDocTypesAsCertain;
264+
$this->objectFromNewClass = $objectFromNewClass;
260265
$this->afterExtractCall = $afterExtractCall;
261266
$this->parentScope = $parentScope;
262267
}
@@ -2204,6 +2209,7 @@ public function doNotTreatPhpDocTypesAsCertain(): Scope
22042209
$this->inFunctionCallsStack,
22052210
$this->dynamicConstantNames,
22062211
false,
2212+
$this->objectFromNewClass,
22072213
$this->afterExtractCall,
22082214
$this->parentScope
22092215
);
@@ -4641,6 +4647,10 @@ private function getTypeToInstantiateForNew(Type $type): Type
46414647
foreach ($type->getTypes() as $innerType) {
46424648
$decidedType = $decideType($innerType);
46434649
if ($decidedType === null) {
4650+
if ($this->objectFromNewClass) {
4651+
return new ObjectWithoutClassType();
4652+
}
4653+
46444654
return new MixedType(false, new StringType());
46454655
}
46464656

@@ -4652,6 +4662,10 @@ private function getTypeToInstantiateForNew(Type $type): Type
46524662

46534663
$decidedType = $decideType($type);
46544664
if ($decidedType === null) {
4665+
if ($this->objectFromNewClass) {
4666+
return new ObjectWithoutClassType();
4667+
}
4668+
46554669
return new MixedType(false, new StringType());
46564670
}
46574671

src/Testing/TestCase.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -564,6 +564,7 @@ public function createScopeFactory(Broker $broker, TypeSpecifier $typeSpecifier)
564564
$this->getParser(),
565565
self::getContainer()->getByType(NodeScopeResolver::class),
566566
$this->shouldTreatPhpDocTypesAsCertain(),
567+
false,
567568
$container
568569
);
569570
}

0 commit comments

Comments
 (0)