1
0
mirror of https://github.com/danog/psalm.git synced 2024-11-30 04:39:00 +01:00

Fix #1254 - merge literal and class-strings types into string

This commit is contained in:
Brown 2019-01-29 10:34:31 -05:00
parent 9edbae2bdc
commit 0bb5143efd
4 changed files with 63 additions and 3 deletions

View File

@ -704,10 +704,23 @@ class TypeCombination
} else {
$type_key = 'string';
$combination->strings = null;
if (!isset($combination->value_types['string'])) {
$combination->value_types[$type_key] = $type;
if ($combination->strings) {
$has_non_literal_class_string = false;
foreach ($combination->strings as $literal_string) {
if (!$literal_string instanceof TLiteralClassString) {
$has_non_literal_class_string = true;
}
}
if ($has_non_literal_class_string || !$type instanceof TClassString) {
$combination->value_types[$type_key] = new TString();
} else {
$combination->value_types[$type_key] = new TClassString();
}
} else {
$combination->value_types[$type_key] = $type;
}
} elseif (get_class($combination->value_types['string']) !== TString::class) {
if (get_class($type) === TString::class) {
$combination->value_types[$type_key] = $type;
@ -715,6 +728,8 @@ class TypeCombination
$combination->value_types[$type_key] = new TString();
}
}
$combination->strings = null;
}
} elseif ($type instanceof TInt) {
if (isset($combination->value_types['array-key'])) {

View File

@ -263,6 +263,10 @@ abstract class Type
return new TClassString($class_name, $param_union_types[0]);
}
if (isset(self::PSALM_RESERVED_WORDS[$generic_type_value])) {
throw new TypeParseTreeException('Cannot create generic object with reserved word');
}
return new TGenericObject($generic_type_value, $generic_params);
}

View File

@ -43,6 +43,15 @@ class TypeCombinationTest extends TestCase
$var[] = new A();
$var[] = new B();',
],
'preventLiteralAndClassString' => [
'<?php
/**
* @param "array"|class-string $type_name
*/
function foo(string $type_name) : bool {
return $type_name === "array";
}',
],
];
}

View File

@ -516,6 +516,16 @@ class TypeParseTest extends TestCase
Type::parseString('string;');
}
/**
* @expectedException \Psalm\Exception\TypeParseTreeException
*
* @return void
*/
public function testBadGenericString()
{
Type::parseString('string<T>');
}
/**
* @expectedException \Psalm\Exception\TypeParseTreeException
*
@ -639,6 +649,28 @@ class TypeParseTest extends TestCase
);
}
/**
* @return void
*/
public function testCombineLiteralStringWithClassString()
{
$this->assertSame(
'string',
(string)Type::parseString('"array"|class-string')
);
}
/**
* @return void
*/
public function testCombineLiteralClassStringWithClassString()
{
$this->assertSame(
'class-string',
(string)Type::parseString('A::class|class-string')
);
}
/**
* @return void
*/