Skip to content

Commit

Permalink
Merge pull request #6533 from orklah/combineTypes
Browse files Browse the repository at this point in the history
Combine types with null argument
  • Loading branch information
orklah authored Sep 25, 2021
2 parents f86e3b1 + a92fee8 commit 9c65953
Show file tree
Hide file tree
Showing 37 changed files with 382 additions and 801 deletions.
12 changes: 5 additions & 7 deletions src/Psalm/Internal/Analyzer/ClassAnalyzer.php
Original file line number Diff line number Diff line change
Expand Up @@ -1539,13 +1539,11 @@ private function checkForMissingPropertyType(
$suggested_type = $property_storage->suggested_type;

if (isset($this->inferred_property_types[$property_name])) {
$suggested_type = $suggested_type
? Type::combineUnionTypes(
$suggested_type,
$this->inferred_property_types[$property_name],
$codebase
)
: $this->inferred_property_types[$property_name];
$suggested_type = Type::combineUnionTypes(
$suggested_type,
$this->inferred_property_types[$property_name] ?? null,
$codebase
);
}

if ($suggested_type && !$property_storage->has_default && $property_storage->is_static) {
Expand Down
13 changes: 2 additions & 11 deletions src/Psalm/Internal/Analyzer/FunctionLike/ReturnTypeCollector.php
Original file line number Diff line number Diff line change
Expand Up @@ -243,17 +243,8 @@ private static function processYieldTypes(
if ($type instanceof Type\Atomic\TArray) {
[$key_type_param, $value_type_param] = $type->type_params;

if (!$key_type) {
$key_type = clone $key_type_param;
} else {
$key_type = Type::combineUnionTypes($key_type_param, $key_type);
}

if (!$value_type) {
$value_type = clone $value_type_param;
} else {
$value_type = Type::combineUnionTypes($value_type_param, $value_type);
}
$key_type = Type::combineUnionTypes(clone $key_type_param, $key_type);
$value_type = Type::combineUnionTypes(clone $value_type_param, $value_type);
} elseif ($type instanceof Type\Atomic\TIterable
|| $type instanceof Type\Atomic\TNamedObject
) {
Expand Down
114 changes: 26 additions & 88 deletions src/Psalm/Internal/Analyzer/Statements/Block/ForeachAnalyzer.php
Original file line number Diff line number Diff line change
Expand Up @@ -456,19 +456,11 @@ public static function checkIteratorType(
$always_non_empty_array = false;
}

if (!$value_type) {
$value_type = clone $iterator_atomic_type->type_params[1];
} else {
$value_type = Type::combineUnionTypes($value_type, $iterator_atomic_type->type_params[1]);
}
$value_type = Type::combineUnionTypes($value_type, clone $iterator_atomic_type->type_params[1]);

$key_type_part = $iterator_atomic_type->type_params[0];

if (!$key_type) {
$key_type = $key_type_part;
} else {
$key_type = Type::combineUnionTypes($key_type, $key_type_part);
}
$key_type = Type::combineUnionTypes($key_type, $key_type_part);

ArrayFetchAnalyzer::taintArrayFetch(
$statements_analyzer,
Expand Down Expand Up @@ -573,17 +565,8 @@ public static function checkIteratorType(
throw new \UnexpectedValueException('Should not happen');
}

if (!$value_type) {
$value_type = $intersection_value_type;
} else {
$value_type = Type::combineUnionTypes($value_type, $intersection_value_type);
}

if (!$key_type) {
$key_type = $intersection_key_type;
} else {
$key_type = Type::combineUnionTypes($key_type, $intersection_key_type);
}
$value_type = Type::combineUnionTypes($value_type, $intersection_value_type);
$key_type = Type::combineUnionTypes($key_type, $intersection_key_type);

ArrayFetchAnalyzer::taintArrayFetch(
$statements_analyzer,
Expand Down Expand Up @@ -755,23 +738,15 @@ public static function handleIterable(
if ($iterator_atomic_type instanceof Type\Atomic\TNamedObject
&& strtolower($iterator_atomic_type->value) === 'simplexmlelement'
) {
if ($value_type) {
$value_type = Type::combineUnionTypes(
$value_type,
new Type\Union([clone $iterator_atomic_type])
);
} else {
$value_type = new Type\Union([clone $iterator_atomic_type]);
}
$value_type = Type::combineUnionTypes(
$value_type,
new Type\Union([clone $iterator_atomic_type])
);

if ($key_type) {
$key_type = Type::combineUnionTypes(
$key_type,
Type::getString()
);
} else {
$key_type = Type::getString();
}
$key_type = Type::combineUnionTypes(
$key_type,
Type::getString()
);
}

if ($iterator_atomic_type instanceof Type\Atomic\TIterable
Expand Down Expand Up @@ -914,17 +889,8 @@ public static function handleIterable(
break;
}

if (!$key_type) {
$key_type = $key_type_part;
} else {
$key_type = Type::combineUnionTypes($key_type, $key_type_part);
}

if (!$value_type) {
$value_type = $value_type_part;
} else {
$value_type = Type::combineUnionTypes($value_type, $value_type_part);
}
$key_type = Type::combineUnionTypes($key_type, $key_type_part);
$value_type = Type::combineUnionTypes($value_type, $value_type_part);
}
}
} elseif ($codebase->classImplements(
Expand Down Expand Up @@ -954,19 +920,11 @@ public static function handleIterable(
);

if ($iterator_value_type && !$iterator_value_type->isMixed()) {
if (!$value_type) {
$value_type = $iterator_value_type;
} else {
$value_type = Type::combineUnionTypes($value_type, $iterator_value_type);
}
$value_type = Type::combineUnionTypes($value_type, $iterator_value_type);
}

if ($iterator_key_type && !$iterator_key_type->isMixed()) {
if (!$key_type) {
$key_type = $iterator_key_type;
} else {
$key_type = Type::combineUnionTypes($key_type, $iterator_key_type);
}
$key_type = Type::combineUnionTypes($key_type, $iterator_key_type);
}
}

Expand Down Expand Up @@ -998,21 +956,9 @@ public static function getKeyValueParamsForTraversableObject(
|| ($iterator_atomic_type instanceof Type\Atomic\TGenericObject
&& strtolower($iterator_atomic_type->value) === 'traversable')
) {
$value_type_part = $iterator_atomic_type->type_params[1];

if (!$value_type) {
$value_type = $value_type_part;
} else {
$value_type = Type::combineUnionTypes($value_type, $value_type_part);
}
$value_type = Type::combineUnionTypes($value_type, $iterator_atomic_type->type_params[1]);
$key_type = Type::combineUnionTypes($key_type, $iterator_atomic_type->type_params[0]);

$key_type_part = $iterator_atomic_type->type_params[0];

if (!$key_type) {
$key_type = $key_type_part;
} else {
$key_type = Type::combineUnionTypes($key_type, $key_type_part);
}
return;
}

Expand Down Expand Up @@ -1162,14 +1108,10 @@ private static function getExtendedType(

foreach ($extended_type->getAtomicTypes() as $extended_atomic_type) {
if (!$extended_atomic_type instanceof Type\Atomic\TTemplateParam) {
if (!$return_type) {
$return_type = $extended_type;
} else {
$return_type = Type::combineUnionTypes(
$return_type,
$extended_type
);
}
$return_type = Type::combineUnionTypes(
$return_type,
$extended_type
);

continue;
}
Expand All @@ -1184,14 +1126,10 @@ private static function getExtendedType(
);

if ($candidate_type) {
if (!$return_type) {
$return_type = $candidate_type;
} else {
$return_type = Type::combineUnionTypes(
$return_type,
$candidate_type
);
}
$return_type = Type::combineUnionTypes(
$return_type,
$candidate_type
);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -517,15 +517,11 @@ public static function updateIfScope(
}

foreach ($possibly_redefined_vars as $var => $type) {
if (isset($if_scope->possibly_redefined_vars[$var])) {
$if_scope->possibly_redefined_vars[$var] = Type::combineUnionTypes(
$type,
$if_scope->possibly_redefined_vars[$var],
$codebase
);
} else {
$if_scope->possibly_redefined_vars[$var] = $type;
}
$if_scope->possibly_redefined_vars[$var] = Type::combineUnionTypes(
$type,
$if_scope->possibly_redefined_vars[$var] ?? null,
$codebase
);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -519,14 +519,10 @@ public static function analyze(
} else {
foreach ($case_scope->break_vars as $var_id => $type) {
if (isset($context->vars_in_scope[$var_id])) {
if (!isset($switch_scope->possibly_redefined_vars[$var_id])) {
$switch_scope->possibly_redefined_vars[$var_id] = clone $type;
} else {
$switch_scope->possibly_redefined_vars[$var_id] = Type::combineUnionTypes(
clone $type,
$switch_scope->possibly_redefined_vars[$var_id]
);
}
$switch_scope->possibly_redefined_vars[$var_id] = Type::combineUnionTypes(
clone $type,
$switch_scope->possibly_redefined_vars[$var_id] ?? null
);
}
}
}
Expand Down Expand Up @@ -618,14 +614,10 @@ private static function handleNonReturningCase(
$switch_scope->possibly_redefined_vars = $case_redefined_vars;
} else {
foreach ($case_redefined_vars as $var_id => $type) {
if (!isset($switch_scope->possibly_redefined_vars[$var_id])) {
$switch_scope->possibly_redefined_vars[$var_id] = clone $type;
} else {
$switch_scope->possibly_redefined_vars[$var_id] = Type::combineUnionTypes(
clone $type,
$switch_scope->possibly_redefined_vars[$var_id]
);
}
$switch_scope->possibly_redefined_vars[$var_id] = Type::combineUnionTypes(
clone $type,
$switch_scope->possibly_redefined_vars[$var_id] ?? null
);
}
}

Expand Down
16 changes: 5 additions & 11 deletions src/Psalm/Internal/Analyzer/Statements/Block/TryAnalyzer.php
Original file line number Diff line number Diff line change
Expand Up @@ -89,17 +89,11 @@ public static function analyze(

if ($try_context->finally_scope) {
foreach ($context->vars_in_scope as $var_id => $type) {
if (isset($try_context->finally_scope->vars_in_scope[$var_id])) {
if ($try_context->finally_scope->vars_in_scope[$var_id] !== $type) {
$try_context->finally_scope->vars_in_scope[$var_id] = Type::combineUnionTypes(
$try_context->finally_scope->vars_in_scope[$var_id],
$type,
$statements_analyzer->getCodebase()
);
}
} else {
$try_context->finally_scope->vars_in_scope[$var_id] = $type;
}
$try_context->finally_scope->vars_in_scope[$var_id] = Type::combineUnionTypes(
$try_context->finally_scope->vars_in_scope[$var_id] ?? null,
$type,
$statements_analyzer->getCodebase()
);
}
}

Expand Down
48 changes: 17 additions & 31 deletions src/Psalm/Internal/Analyzer/Statements/BreakAnalyzer.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,42 +39,32 @@ public static function analyze(
$loop_scope->possibly_redefined_loop_parent_vars = $redefined_vars;
} else {
foreach ($redefined_vars as $var => $type) {
if (isset($loop_scope->possibly_redefined_loop_parent_vars[$var])) {
$loop_scope->possibly_redefined_loop_parent_vars[$var] = Type::combineUnionTypes(
$type,
$loop_scope->possibly_redefined_loop_parent_vars[$var]
);
} else {
$loop_scope->possibly_redefined_loop_parent_vars[$var] = $type;
}
$loop_scope->possibly_redefined_loop_parent_vars[$var] = Type::combineUnionTypes(
$type,
$loop_scope->possibly_redefined_loop_parent_vars[$var] ?? null
);
}
}

if ($loop_scope->iteration_count === 0) {
foreach ($context->vars_in_scope as $var_id => $type) {
if (!isset($loop_scope->loop_parent_context->vars_in_scope[$var_id])) {
if (isset($loop_scope->possibly_defined_loop_parent_vars[$var_id])) {
$loop_scope->possibly_defined_loop_parent_vars[$var_id] = Type::combineUnionTypes(
$type,
$loop_scope->possibly_defined_loop_parent_vars[$var_id]
);
} else {
$loop_scope->possibly_defined_loop_parent_vars[$var_id] = $type;
}
$loop_scope->possibly_defined_loop_parent_vars[$var_id] = Type::combineUnionTypes(
$type,
$loop_scope->possibly_defined_loop_parent_vars[$var_id] ?? null
);
}
}
}

if ($context->finally_scope) {
foreach ($context->vars_in_scope as $var_id => $type) {
if (isset($context->finally_scope->vars_in_scope[$var_id])) {
if ($context->finally_scope->vars_in_scope[$var_id] !== $type) {
$context->finally_scope->vars_in_scope[$var_id] = Type::combineUnionTypes(
$context->finally_scope->vars_in_scope[$var_id],
$type,
$statements_analyzer->getCodebase()
);
}
$context->finally_scope->vars_in_scope[$var_id] = Type::combineUnionTypes(
$context->finally_scope->vars_in_scope[$var_id],
$type,
$statements_analyzer->getCodebase()
);
} else {
$context->finally_scope->vars_in_scope[$var_id] = $type;
$type->possibly_undefined = true;
Expand All @@ -92,14 +82,10 @@ public static function analyze(
$case_scope->break_vars = [];
}

if (isset($case_scope->break_vars[$var_id])) {
$case_scope->break_vars[$var_id] = Type::combineUnionTypes(
$type,
$case_scope->break_vars[$var_id]
);
} else {
$case_scope->break_vars[$var_id] = $type;
}
$case_scope->break_vars[$var_id] = Type::combineUnionTypes(
$type,
$case_scope->break_vars[$var_id] ?? null
);
}
}
}
Expand Down
Loading

0 comments on commit 9c65953

Please sign in to comment.