Skip to content

Commit

Permalink
Merge pull request #8999 from VincentLanglet/union
Browse files Browse the repository at this point in the history
Preserve from_docblock in TypeCombiner
  • Loading branch information
orklah committed Dec 28, 2022
2 parents 41ae518 + a263e5d commit d338b00
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 13 deletions.
38 changes: 26 additions & 12 deletions src/Psalm/Internal/Type/TypeCombiner.php
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,7 @@ public static function combine(
$new_types = self::handleKeyedArrayEntries(
$combination,
$overwrite_empty_array,
$from_docblock,
);
}

Expand All @@ -225,6 +226,7 @@ public static function combine(
$allow_mixed_union,
$type,
$combination->array_type_params,
$from_docblock,
);
}

Expand All @@ -239,7 +241,7 @@ public static function combine(
foreach ($combination->builtin_type_params as $generic_type => $generic_type_params) {
if ($generic_type === 'iterable') {
assert(count($generic_type_params) <= 2);
$new_types[] = new TIterable($generic_type_params);
$new_types[] = new TIterable($generic_type_params, [], $from_docblock);
} else {
/** @psalm-suppress ArgumentTypeCoercion Caused by the PropertyTypeCoercion above */
$generic_object = new TGenericObject(
Expand All @@ -248,6 +250,7 @@ public static function combine(
false,
false,
$combination->extra_types,
$from_docblock,
);
$new_types[] = $generic_object;

Expand All @@ -267,6 +270,7 @@ public static function combine(
false,
$combination->object_static[$generic_type] ?? false,
$combination->extra_types,
$from_docblock,
);

$new_types[] = $generic_object;
Expand All @@ -293,10 +297,14 @@ public static function combine(

foreach ($object_type->getAtomicTypes() as $object_atomic_type) {
if ($object_atomic_type instanceof TNamedObject) {
$new_types[] = new TClassString($object_atomic_type->value, $object_atomic_type);
$class_type = new TClassString($object_atomic_type->value, $object_atomic_type);
} elseif ($object_atomic_type instanceof TObject) {
$new_types[] = new TClassString();
$class_type = new TClassString();
} else {
continue;
}

$new_types[] = $class_type->setFromDocblock($from_docblock);
}
}
}
Expand Down Expand Up @@ -351,7 +359,7 @@ public static function combine(
continue;
}

$new_types[] = $type;
$new_types[] = $type->setFromDocblock($from_docblock);
}

if (!$new_types && !$has_never) {
Expand Down Expand Up @@ -1321,7 +1329,8 @@ private static function getClassLikes(Codebase $codebase, string $fq_classlike_n
*/
private static function handleKeyedArrayEntries(
TypeCombination $combination,
bool $overwrite_empty_array
bool $overwrite_empty_array,
bool $from_docblock
): array {
$new_types = [];

Expand Down Expand Up @@ -1397,6 +1406,7 @@ private static function handleKeyedArrayEntries(
? null
: [$fallback_key_type, $fallback_value_type],
(bool)$combination->all_arrays_lists,
$from_docblock,
);
} else {
$objectlike = new TKeyedArray(
Expand All @@ -1406,6 +1416,7 @@ private static function handleKeyedArrayEntries(
? null
: [$fallback_key_type, $fallback_value_type],
(bool)$combination->all_arrays_lists,
$from_docblock,
);
}

Expand All @@ -1414,10 +1425,12 @@ private static function handleKeyedArrayEntries(
$key_type = $combination->objectlike_key_type ?? Type::getArrayKey();
$value_type = $combination->objectlike_value_type ?? Type::getMixed();
if ($combination->array_always_filled) {
$new_types[] = new TNonEmptyArray([$key_type, $value_type]);
$array_type = new TNonEmptyArray([$key_type, $value_type]);
} else {
$new_types[] = new TArray([$key_type, $value_type]);
$array_type = new TArray([$key_type, $value_type]);
}

$new_types[] = $array_type->setFromDocblock($from_docblock);
}

// if we're merging an empty array with an object-like, clobber empty array
Expand All @@ -1436,7 +1449,8 @@ private static function getArrayTypeFromGenericParams(
bool $overwrite_empty_array,
bool $allow_mixed_union,
Atomic $type,
array $generic_type_params
array $generic_type_params,
bool $from_docblock
): Atomic {
if ($combination->objectlike_entries) {
$objectlike_generic_type = null;
Expand All @@ -1455,11 +1469,11 @@ private static function getArrayTypeFromGenericParams(
);

if (is_int($property_name)) {
$objectlike_keys[$property_name] = new TLiteralInt($property_name);
$objectlike_keys[$property_name] = new TLiteralInt($property_name, $from_docblock);
} elseif ($type instanceof TKeyedArray && isset($type->class_strings[$property_name])) {
$objectlike_keys[$property_name] = new TLiteralClassString($property_name);
$objectlike_keys[$property_name] = new TLiteralClassString($property_name, $from_docblock);
} else {
$objectlike_keys[$property_name] = new TLiteralString($property_name);
$objectlike_keys[$property_name] = new TLiteralString($property_name, $from_docblock);
}
}

Expand Down Expand Up @@ -1580,6 +1594,6 @@ private static function getArrayTypeFromGenericParams(
}
}

return $array_type;
return $array_type->setFromDocblock($from_docblock);
}
}
8 changes: 7 additions & 1 deletion src/Psalm/Type/Atomic.php
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,13 @@ public static function create(
?string $text = null,
bool $from_docblock = false
): Atomic {
$result = self::createInner($value, $analysis_php_version_id, $template_type_map, $type_aliases);
$result = self::createInner(
$value,
$analysis_php_version_id,
$template_type_map,
$type_aliases,
$from_docblock,
);
$result->offset_start = $offset_start;
$result->offset_end = $offset_end;
$result->text = $text;
Expand Down
23 changes: 23 additions & 0 deletions tests/TypeReconciliation/RedundantConditionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -1546,6 +1546,29 @@ function f(array $p) : void {
}',
'error_message' => 'RedundantCondition',
],
'from_docblock should be kept when removing types' => [
'code' => '<?php
/**
* @see https://github.com/vimeo/psalm/issues/8932
*
* @param array|null $value
*
* @return null
*/
function reverseTransform($value)
{
if (null === $value) {
return null;
}
if (!\is_array($value)) {
throw new \Exception("array");
}
return null;
}',
'error_message' => 'DocblockTypeContradiction',
],
];
}
}

0 comments on commit d338b00

Please sign in to comment.