1
0
mirror of https://github.com/danog/psalm.git synced 2025-01-22 13:51:54 +01:00

Merge remote-tracking branch 'origin/unify-deprecation-messages' into unify-deprecation-messages

This commit is contained in:
Alies Lapatsin 2023-01-29 18:32:55 +01:00
commit c75e4bdb28
9 changed files with 179 additions and 105 deletions

View File

@ -1,14 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<files psalm-version="dev-master@6bcd3bffe3385bc33643a694c32af515395bf437">
<files psalm-version="dev-master@8b9cd5fb333866c1e84ca9564394816a7ff5ae6f">
<file src="examples/TemplateChecker.php">
<PossiblyUndefinedIntArrayOffset>
<code>$comment_block-&gt;tags['variablesfrom'][0]</code>
<code><![CDATA[$comment_block->tags['variablesfrom'][0]]]></code>
<code>$matches[1]</code>
</PossiblyUndefinedIntArrayOffset>
</file>
<file src="examples/TemplateScanner.php">
<PossiblyUndefinedIntArrayOffset>
<code>$comment_block-&gt;tags['variablesfrom'][0]</code>
<code><![CDATA[$comment_block->tags['variablesfrom'][0]]]></code>
<code>$matches[1]</code>
</PossiblyUndefinedIntArrayOffset>
</file>
@ -24,7 +24,7 @@
</file>
<file src="src/Psalm/Config/FileFilter.php">
<PossiblyUndefinedIntArrayOffset>
<code>explode('::', $method_id)[1]</code>
<code><![CDATA[explode('::', $method_id)[1]]]></code>
</PossiblyUndefinedIntArrayOffset>
</file>
<file src="src/Psalm/ErrorBaseline.php">
@ -38,7 +38,7 @@
<PossiblyUndefinedIntArrayOffset>
<code>$comments[0]</code>
<code>$property_name</code>
<code>$stmt-&gt;props[0]</code>
<code><![CDATA[$stmt->props[0]]]></code>
<code>$uninitialized_variables[0]</code>
</PossiblyUndefinedIntArrayOffset>
</file>
@ -58,7 +58,7 @@
</file>
<file src="src/Psalm/Internal/Analyzer/Statements/Block/ForAnalyzer.php">
<ArgumentTypeCoercion>
<code>$stmt-&gt;cond</code>
<code><![CDATA[$stmt->cond]]></code>
</ArgumentTypeCoercion>
</file>
<file src="src/Psalm/Internal/Analyzer/Statements/Block/ForeachAnalyzer.php">
@ -69,46 +69,46 @@
</file>
<file src="src/Psalm/Internal/Analyzer/Statements/Block/SwitchAnalyzer.php">
<InvalidPropertyAssignmentValue>
<code>$context-&gt;assigned_var_ids += $switch_scope-&gt;new_assigned_var_ids</code>
<code><![CDATA[$context->assigned_var_ids += $switch_scope->new_assigned_var_ids]]></code>
</InvalidPropertyAssignmentValue>
</file>
<file src="src/Psalm/Internal/Analyzer/Statements/Block/SwitchCaseAnalyzer.php">
<PossiblyUndefinedIntArrayOffset>
<code>$new_case_equality_expr-&gt;getArgs()[1]</code>
<code>$switch_scope-&gt;leftover_statements[0]</code>
<code>$traverser-&gt;traverse([$switch_condition])[0]</code>
<code><![CDATA[$new_case_equality_expr->getArgs()[1]]]></code>
<code><![CDATA[$switch_scope->leftover_statements[0]]]></code>
<code><![CDATA[$traverser->traverse([$switch_condition])[0]]]></code>
</PossiblyUndefinedIntArrayOffset>
</file>
<file src="src/Psalm/Internal/Analyzer/Statements/Expression/AssertionFinder.php">
<PossiblyUndefinedIntArrayOffset>
<code>$assertion-&gt;rule[0]</code>
<code>$assertion-&gt;rule[0]</code>
<code>$assertion-&gt;rule[0]</code>
<code>$assertion-&gt;rule[0]</code>
<code>$assertion-&gt;rule[0]</code>
<code>$assertion-&gt;rule[0]</code>
<code>$assertion-&gt;rule[0]</code>
<code>$count_expr-&gt;getArgs()[0]</code>
<code>$count_expr-&gt;getArgs()[0]</code>
<code>$count_expr-&gt;getArgs()[0]</code>
<code>$count_expr-&gt;getArgs()[0]</code>
<code>$count_expr-&gt;getArgs()[0]</code>
<code>$counted_expr-&gt;getArgs()[0]</code>
<code>$expr-&gt;getArgs()[0]</code>
<code>$expr-&gt;getArgs()[0]</code>
<code>$expr-&gt;getArgs()[0]</code>
<code>$expr-&gt;getArgs()[0]</code>
<code>$expr-&gt;getArgs()[0]</code>
<code>$expr-&gt;getArgs()[0]</code>
<code>$expr-&gt;getArgs()[0]</code>
<code>$expr-&gt;getArgs()[0]</code>
<code>$expr-&gt;getArgs()[1]</code>
<code>$expr-&gt;getArgs()[1]</code>
<code>$get_debug_type_expr-&gt;getArgs()[0]</code>
<code>$get_debug_type_expr-&gt;getArgs()[0]</code>
<code>$getclass_expr-&gt;getArgs()[0]</code>
<code>$gettype_expr-&gt;getArgs()[0]</code>
<code>$gettype_expr-&gt;getArgs()[0]</code>
<code><![CDATA[$assertion->rule[0]]]></code>
<code><![CDATA[$assertion->rule[0]]]></code>
<code><![CDATA[$assertion->rule[0]]]></code>
<code><![CDATA[$assertion->rule[0]]]></code>
<code><![CDATA[$assertion->rule[0]]]></code>
<code><![CDATA[$assertion->rule[0]]]></code>
<code><![CDATA[$assertion->rule[0]]]></code>
<code><![CDATA[$count_expr->getArgs()[0]]]></code>
<code><![CDATA[$count_expr->getArgs()[0]]]></code>
<code><![CDATA[$count_expr->getArgs()[0]]]></code>
<code><![CDATA[$count_expr->getArgs()[0]]]></code>
<code><![CDATA[$count_expr->getArgs()[0]]]></code>
<code><![CDATA[$counted_expr->getArgs()[0]]]></code>
<code><![CDATA[$expr->getArgs()[0]]]></code>
<code><![CDATA[$expr->getArgs()[0]]]></code>
<code><![CDATA[$expr->getArgs()[0]]]></code>
<code><![CDATA[$expr->getArgs()[0]]]></code>
<code><![CDATA[$expr->getArgs()[0]]]></code>
<code><![CDATA[$expr->getArgs()[0]]]></code>
<code><![CDATA[$expr->getArgs()[0]]]></code>
<code><![CDATA[$expr->getArgs()[0]]]></code>
<code><![CDATA[$expr->getArgs()[1]]]></code>
<code><![CDATA[$expr->getArgs()[1]]]></code>
<code><![CDATA[$get_debug_type_expr->getArgs()[0]]]></code>
<code><![CDATA[$get_debug_type_expr->getArgs()[0]]]></code>
<code><![CDATA[$getclass_expr->getArgs()[0]]]></code>
<code><![CDATA[$gettype_expr->getArgs()[0]]]></code>
<code><![CDATA[$gettype_expr->getArgs()[0]]]></code>
</PossiblyUndefinedIntArrayOffset>
</file>
<file src="src/Psalm/Internal/Analyzer/Statements/Expression/Assignment/StaticPropertyAssignmentAnalyzer.php">
@ -129,7 +129,7 @@
<PossiblyUndefinedIntArrayOffset>
<code>$method_name</code>
<code>$parts[1]</code>
<code>explode('::', $cased_method_id)[1]</code>
<code><![CDATA[explode('::', $cased_method_id)[1]]]></code>
</PossiblyUndefinedIntArrayOffset>
</file>
<file src="src/Psalm/Internal/Analyzer/Statements/Expression/Call/ArrayFunctionArgumentsAnalyzer.php">
@ -143,7 +143,7 @@
</file>
<file src="src/Psalm/Internal/Analyzer/Statements/Expression/Call/FunctionCallAnalyzer.php">
<PossiblyUndefinedArrayOffset>
<code>$stmt-&gt;getArgs()[0]</code>
<code><![CDATA[$stmt->getArgs()[0]]]></code>
</PossiblyUndefinedArrayOffset>
<PossiblyUndefinedIntArrayOffset>
<code>$parts[1]</code>
@ -156,12 +156,12 @@
</file>
<file src="src/Psalm/Internal/Analyzer/Statements/Expression/Call/MethodCallAnalyzer.php">
<PossiblyUndefinedIntArrayOffset>
<code>$result-&gt;invalid_method_call_types[0]</code>
<code>$result-&gt;non_existent_class_method_ids[0]</code>
<code>$result-&gt;non_existent_class_method_ids[0]</code>
<code>$result-&gt;non_existent_interface_method_ids[0]</code>
<code>$result-&gt;non_existent_interface_method_ids[0]</code>
<code>$result-&gt;non_existent_magic_method_ids[0]</code>
<code><![CDATA[$result->invalid_method_call_types[0]]]></code>
<code><![CDATA[$result->non_existent_class_method_ids[0]]]></code>
<code><![CDATA[$result->non_existent_class_method_ids[0]]]></code>
<code><![CDATA[$result->non_existent_interface_method_ids[0]]]></code>
<code><![CDATA[$result->non_existent_interface_method_ids[0]]]></code>
<code><![CDATA[$result->non_existent_magic_method_ids[0]]]></code>
</PossiblyUndefinedIntArrayOffset>
</file>
<file src="src/Psalm/Internal/Analyzer/Statements/Expression/Call/StaticMethod/ExistingAtomicStaticCallAnalyzer.php">
@ -171,8 +171,8 @@
</file>
<file src="src/Psalm/Internal/Analyzer/Statements/Expression/CallAnalyzer.php">
<PossiblyUndefinedIntArrayOffset>
<code>$callable_arg-&gt;items[0]</code>
<code>$callable_arg-&gt;items[1]</code>
<code><![CDATA[$callable_arg->items[0]]]></code>
<code><![CDATA[$callable_arg->items[1]]]></code>
</PossiblyUndefinedIntArrayOffset>
</file>
<file src="src/Psalm/Internal/Analyzer/Statements/Expression/ClassConstAnalyzer.php">
@ -205,7 +205,7 @@
</file>
<file src="src/Psalm/Internal/Analyzer/Statements/Expression/YieldAnalyzer.php">
<PossiblyUndefinedIntArrayOffset>
<code>$atomic_return_type-&gt;type_params[2]</code>
<code><![CDATA[$atomic_return_type->type_params[2]]]></code>
</PossiblyUndefinedIntArrayOffset>
</file>
<file src="src/Psalm/Internal/Analyzer/Statements/ReturnAnalyzer.php">
@ -225,7 +225,7 @@
</file>
<file src="src/Psalm/Internal/Analyzer/StatementsAnalyzer.php">
<PossiblyUndefinedArrayOffset>
<code>$stmt-&gt;expr-&gt;getArgs()[0]</code>
<code><![CDATA[$stmt->expr->getArgs()[0]]]></code>
</PossiblyUndefinedArrayOffset>
<PossiblyUndefinedIntArrayOffset>
<code>$check_type_string</code>
@ -233,7 +233,7 @@
</file>
<file src="src/Psalm/Internal/Cli/LanguageServer.php">
<PossiblyInvalidArgument>
<code>$options['tcp'] ?? null</code>
<code><![CDATA[$options['tcp'] ?? null]]></code>
</PossiblyInvalidArgument>
</file>
<file src="src/Psalm/Internal/Cli/Refactor.php">
@ -283,11 +283,11 @@
</file>
<file src="src/Psalm/Internal/Diff/ClassStatementsDiffer.php">
<PossiblyUndefinedIntArrayOffset>
<code>$a-&gt;props[0]</code>
<code>$a-&gt;stmts[0]</code>
<code><![CDATA[$a->props[0]]]></code>
<code><![CDATA[$a->stmts[0]]]></code>
<code>$a_stmt_comments[0]</code>
<code>$b-&gt;props[0]</code>
<code>$b-&gt;stmts[0]</code>
<code><![CDATA[$b->props[0]]]></code>
<code><![CDATA[$b->stmts[0]]]></code>
<code>$b_stmt_comments[0]</code>
</PossiblyUndefinedIntArrayOffset>
</file>
@ -304,14 +304,14 @@
</file>
<file src="src/Psalm/Internal/FileManipulation/PropertyDocblockManipulator.php">
<PossiblyUndefinedIntArrayOffset>
<code>$stmt-&gt;props[0]</code>
<code><![CDATA[$stmt->props[0]]]></code>
</PossiblyUndefinedIntArrayOffset>
</file>
<file src="src/Psalm/Internal/LanguageServer/LanguageClient.php">
<DocblockTypeContradiction>
<code>$type &lt; 1</code>
<code>$type &lt; 1 || $type &gt; 4</code>
<code>$type &gt; 4</code>
<code><![CDATA[$type < 1]]></code>
<code><![CDATA[$type < 1 || $type > 4]]></code>
<code><![CDATA[$type > 4]]></code>
</DocblockTypeContradiction>
</file>
<file src="src/Psalm/Internal/LanguageServer/LanguageServer.php">
@ -347,7 +347,7 @@
<code>$match[0]</code>
<code>$match[1]</code>
<code>$match[2]</code>
<code>$node-&gt;stmts[0]</code>
<code><![CDATA[$node->stmts[0]]]></code>
<code>$replacement_stmts[0]</code>
<code>$replacement_stmts[0]</code>
<code>$replacement_stmts[0]</code>
@ -357,8 +357,8 @@
<PossiblyUndefinedIntArrayOffset>
<code>$doc_line_parts[1]</code>
<code>$matches[0]</code>
<code>$method_tree-&gt;children[0]</code>
<code>$method_tree-&gt;children[1]</code>
<code><![CDATA[$method_tree->children[0]]]></code>
<code><![CDATA[$method_tree->children[1]]]></code>
</PossiblyUndefinedIntArrayOffset>
</file>
<file src="src/Psalm/Internal/PhpVisitor/Reflector/ClassLikeNodeScanner.php">
@ -369,8 +369,8 @@
</file>
<file src="src/Psalm/Internal/PhpVisitor/Reflector/ExpressionScanner.php">
<PossiblyUndefinedIntArrayOffset>
<code>$node-&gt;getArgs()[0]</code>
<code>$node-&gt;getArgs()[1]</code>
<code><![CDATA[$node->getArgs()[0]]]></code>
<code><![CDATA[$node->getArgs()[1]]]></code>
</PossiblyUndefinedIntArrayOffset>
</file>
<file src="src/Psalm/Internal/PhpVisitor/Reflector/FunctionLikeDocblockParser.php">
@ -378,7 +378,7 @@
<code>$since_parts[1]</code>
</PossiblyUndefinedIntArrayOffset>
<RedundantCondition>
<code>count($line_parts) &gt; 0</code>
<code><![CDATA[count($line_parts) > 0]]></code>
</RedundantCondition>
</file>
<file src="src/Psalm/Internal/PhpVisitor/Reflector/FunctionLikeDocblockScanner.php">
@ -391,7 +391,7 @@
</file>
<file src="src/Psalm/Internal/PhpVisitor/Reflector/FunctionLikeNodeScanner.php">
<PossiblyUndefinedIntArrayOffset>
<code>$stmt-&gt;stmts[0]</code>
<code><![CDATA[$stmt->stmts[0]]]></code>
</PossiblyUndefinedIntArrayOffset>
</file>
<file src="src/Psalm/Internal/PhpVisitor/SimpleNameResolver.php">
@ -419,8 +419,8 @@
<code>isContainedBy</code>
</ComplexMethod>
<PossiblyUndefinedIntArrayOffset>
<code>$array-&gt;properties[0]</code>
<code>$array-&gt;properties[0]</code>
<code><![CDATA[$array->properties[0]]]></code>
<code><![CDATA[$array->properties[0]]]></code>
</PossiblyUndefinedIntArrayOffset>
</file>
<file src="src/Psalm/Internal/Type/Comparator/CallableTypeComparator.php">
@ -433,7 +433,7 @@
</file>
<file src="src/Psalm/Internal/Type/SimpleAssertionReconciler.php">
<PossiblyUndefinedIntArrayOffset>
<code>$array_atomic_type-&gt;properties[0]</code>
<code><![CDATA[$array_atomic_type->properties[0]]]></code>
<code>$properties[0]</code>
<code>$properties[0]</code>
<code>$properties[0]</code>
@ -447,13 +447,13 @@
</file>
<file src="src/Psalm/Internal/Type/TypeCombiner.php">
<PossiblyUndefinedIntArrayOffset>
<code>$combination-&gt;array_type_params[1]</code>
<code>$combination-&gt;array_type_params[1]</code>
<code>$combination-&gt;array_type_params[1]</code>
<code>$combination-&gt;array_type_params[1]</code>
<code>$combination-&gt;array_type_params[1]</code>
<code>$combination-&gt;array_type_params[1]</code>
<code>$combination-&gt;array_type_params[1]</code>
<code><![CDATA[$combination->array_type_params[1]]]></code>
<code><![CDATA[$combination->array_type_params[1]]]></code>
<code><![CDATA[$combination->array_type_params[1]]]></code>
<code><![CDATA[$combination->array_type_params[1]]]></code>
<code><![CDATA[$combination->array_type_params[1]]]></code>
<code><![CDATA[$combination->array_type_params[1]]]></code>
<code><![CDATA[$combination->array_type_params[1]]]></code>
</PossiblyUndefinedIntArrayOffset>
</file>
<file src="src/Psalm/Internal/Type/TypeExpander.php">
@ -466,8 +466,8 @@
<code>$const_name</code>
<code>$const_name</code>
<code>$intersection_types[0]</code>
<code>$parse_tree-&gt;children[0]</code>
<code>$parse_tree-&gt;condition-&gt;children[0]</code>
<code><![CDATA[$parse_tree->children[0]]]></code>
<code><![CDATA[$parse_tree->condition->children[0]]]></code>
<code>array_keys($offset_template_data)[0]</code>
<code>array_keys($template_type_map[$array_param_name])[0]</code>
<code>array_keys($template_type_map[$class_name])[0]</code>
@ -485,7 +485,7 @@
</file>
<file src="src/Psalm/Plugin/Shepherd.php">
<DeprecatedProperty>
<code>$codebase-&gt;config-&gt;shepherd_host</code>
<code><![CDATA[$codebase->config->shepherd_host]]></code>
</DeprecatedProperty>
</file>
<file src="src/Psalm/Storage/ClassConstantStorage.php">
@ -543,7 +543,7 @@
<code>replace</code>
</ImpureMethodCall>
<PossiblyUndefinedIntArrayOffset>
<code>$this-&gt;type_params[1]</code>
<code><![CDATA[$this->type_params[1]]]></code>
</PossiblyUndefinedIntArrayOffset>
</file>
<file src="src/Psalm/Type/Atomic/HasIntersectionTrait.php">
@ -569,7 +569,7 @@
<code>replace</code>
</ImpureMethodCall>
<ImpurePropertyAssignment>
<code>$cloned-&gt;value_param</code>
<code><![CDATA[$cloned->value_param]]></code>
</ImpurePropertyAssignment>
</file>
<file src="src/Psalm/Type/Atomic/TConditional.php">
@ -585,8 +585,8 @@
<file src="src/Psalm/Type/Atomic/TKeyedArray.php">
<DeprecatedClass>
<code>TList</code>
<code>new TList($this-&gt;getGenericValueType())</code>
<code>new TNonEmptyList($this-&gt;getGenericValueType())</code>
<code><![CDATA[new TList($this->getGenericValueType())]]></code>
<code><![CDATA[new TNonEmptyList($this->getGenericValueType())]]></code>
</DeprecatedClass>
<ImpureMethodCall>
<code>combine</code>
@ -604,12 +604,12 @@
<code>replace</code>
</ImpureMethodCall>
<ImpurePropertyAssignment>
<code>$key_type-&gt;possibly_undefined</code>
<code><![CDATA[$key_type->possibly_undefined]]></code>
</ImpurePropertyAssignment>
<PossiblyUndefinedIntArrayOffset>
<code>$this-&gt;properties[0]</code>
<code>$this-&gt;properties[0]</code>
<code>$this-&gt;properties[0]</code>
<code><![CDATA[$this->properties[0]]]></code>
<code><![CDATA[$this->properties[0]]]></code>
<code><![CDATA[$this->properties[0]]]></code>
</PossiblyUndefinedIntArrayOffset>
<PossiblyUnusedMethod>
<code>getList</code>
@ -621,7 +621,7 @@
<code>replace</code>
</ImpureMethodCall>
<ImpurePropertyAssignment>
<code>$cloned-&gt;type_param</code>
<code><![CDATA[$cloned->type_param]]></code>
</ImpurePropertyAssignment>
</file>
<file src="src/Psalm/Type/Atomic/TNonEmptyList.php">
@ -697,7 +697,7 @@
<code>TArray|TKeyedArray|TClassStringMap</code>
</MoreSpecificReturnType>
<PossiblyUndefinedStringArrayOffset>
<code>$this-&gt;types['array']</code>
<code><![CDATA[$this->types['array']]]></code>
</PossiblyUndefinedStringArrayOffset>
<PossiblyUnusedMethod>
<code>allFloatLiterals</code>
@ -708,7 +708,7 @@
</file>
<file src="vendor/nikic/php-parser/lib/PhpParser/Node/Expr/ArrowFunction.php">
<PossiblyUndefinedStringArrayOffset>
<code>$subNodes['expr']</code>
<code><![CDATA[$subNodes['expr']]]></code>
</PossiblyUndefinedStringArrayOffset>
</file>
</files>

View File

@ -16,6 +16,7 @@ use function array_merge;
use function array_reduce;
use function array_values;
use function get_loaded_extensions;
use function htmlspecialchars;
use function implode;
use function ksort;
use function min;
@ -266,7 +267,12 @@ final class ErrorBaseline
foreach ($existingIssueType['s'] as $selection) {
$codeNode = $baselineDoc->createElement('code');
$codeNode->textContent = trim($selection);
$textContent = trim($selection);
if ($textContent !== htmlspecialchars($textContent)) {
$codeNode->append($baselineDoc->createCDATASection($textContent));
} else {
$codeNode->textContent = trim($textContent);
}
$issueNode->appendChild($codeNode);
}
$fileNode->appendChild($issueNode);

View File

@ -162,7 +162,7 @@ class CommentAnalyzer
throw new DocblockParseException(
$line_parts[0] .
' is not a valid type' .
' (from ' .
' ('.$e->getMessage().' in ' .
$source->getFilePath() .
':' .
$comment->getStartLine() .

View File

@ -1895,7 +1895,7 @@ class ClassLikeNodeScanner
$self_fqcln,
);
} catch (TypeParseTreeException $e) {
throw new DocblockParseException($type_string . ' is not a valid type');
throw new DocblockParseException($type_string . ' is not a valid type: '.$e->getMessage());
}
$type_alias_tokens[$type_alias] = new InlineTypeAlias($type_tokens);

View File

@ -12,6 +12,7 @@ use Psalm\Type\Atomic\TArray;
use Psalm\Type\Atomic\TKeyedArray;
use Psalm\Type\Atomic\TNamedObject;
use Psalm\Type\Union;
use ReflectionProperty;
use function count;
use function implode;
@ -63,6 +64,40 @@ class PhpStormMetaScanner
} elseif ($array_item->value instanceof PhpParser\Node\Scalar\String_) {
$map[$array_item->key->value] = $array_item->value->value;
}
} elseif ($array_item
&& $array_item->key instanceof PhpParser\Node\Expr\ClassConstFetch
&& $array_item->key->class instanceof PhpParser\Node\Name\FullyQualified
&& $array_item->key->name instanceof PhpParser\Node\Identifier
) {
/** @var string|null $resolved_name */
$resolved_name = $array_item->key->class->getAttribute('resolvedName');
if (!$resolved_name) {
continue;
}
$constant_type = $codebase->classlikes->getClassConstantType(
$resolved_name,
$array_item->key->name->name,
ReflectionProperty::IS_PRIVATE,
);
if (!$constant_type instanceof Union || !$constant_type->isSingleStringLiteral()) {
continue;
}
$meta_key = $constant_type->getSingleStringLiteral()->value;
if ($array_item->value instanceof PhpParser\Node\Expr\ClassConstFetch
&& $array_item->value->class instanceof PhpParser\Node\Name\FullyQualified
&& $array_item->value->name instanceof PhpParser\Node\Identifier
&& strtolower($array_item->value->name->name)
) {
$map[$meta_key] = new Union([
new TNamedObject(implode('\\', $array_item->value->class->parts)),
]);
} elseif ($array_item->value instanceof PhpParser\Node\Scalar\String_) {
$map[$meta_key] = $array_item->value->value;
}
}
}
}

View File

@ -1478,6 +1478,10 @@ class TypeParser
$had_optional = true;
}
if (isset($properties[$property_key])) {
throw new TypeParseTreeException("Duplicate key $property_key detected");
}
$properties[$property_key] = $property_type;
if ($class_string) {
$class_strings[$property_key] = true;
@ -1485,7 +1489,7 @@ class TypeParser
}
if ($had_explicit && $had_implicit) {
throw new TypeParseTreeException('Cannot mix explicit and implicit keys!');
throw new TypeParseTreeException('Cannot mix explicit and implicit keys');
}
if ($type === 'object') {
@ -1500,7 +1504,7 @@ class TypeParser
}
if ($callable && !$properties) {
throw new TypeParseTreeException('A callable array cannot be empty!');
throw new TypeParseTreeException('A callable array cannot be empty');
}
if ($type !== 'array' && $type !== 'list') {
@ -1508,7 +1512,7 @@ class TypeParser
}
if ($type === 'list' && !$is_list) {
throw new TypeParseTreeException('A list shape cannot describe a non-list!');
throw new TypeParseTreeException('A list shape cannot describe a non-list');
}
if (!$properties) {
@ -1520,7 +1524,7 @@ class TypeParser
$class_strings,
$sealed
? null
: [$is_list ? Type::getInt() : Type::getArrayKey(), Type::getMixed()],
: [$is_list ? Type::getListKey() : Type::getArrayKey(), Type::getMixed()],
$is_list,
$from_docblock,
);

View File

@ -317,6 +317,10 @@ class StubTest extends TestCase
'<?php
namespace Ns {
class MyClass {
public const OBJECT = "object";
private const EXCEPTION = "exception";
/**
* @return mixed
* @psalm-suppress InvalidReturnType
@ -328,6 +332,12 @@ class StubTest extends TestCase
* @psalm-suppress InvalidReturnType
*/
public function create2(string $s) {}
/**
* @return mixed
* @psalm-suppress InvalidReturnType
*/
public function create3(string $s) {}
/**
* @param mixed $s
@ -374,6 +384,9 @@ class StubTest extends TestCase
$y1 = (new \Ns\MyClass)->creAte2("object");
$y2 = (new \Ns\MyClass)->creaTe2("exception");
$const1 = (new \Ns\MyClass)->creAte3(\Ns\MyClass::OBJECT);
$const2 = (new \Ns\MyClass)->creaTe3("exception");
$b1 = \Create("object");
$b2 = \cReate("exception");
@ -404,6 +417,9 @@ class StubTest extends TestCase
'$y1===' => 'stdClass',
'$y2===' => 'Exception',
'$const1===' => 'stdClass',
'$const2===' => 'Exception',
'$b1===' => 'stdClass',
'$b2===' => 'Exception',

View File

@ -473,54 +473,60 @@ class TypeParseTest extends TestCase
public function testTKeyedListNonList(): void
{
$this->expectExceptionMessage('A list shape cannot describe a non-list!');
$this->expectExceptionMessage('A list shape cannot describe a non-list');
Type::parseString('list{a: 0, b: 1, c: 2}');
}
public function testTKeyedListNonListOptional(): void
{
$this->expectExceptionMessage('A list shape cannot describe a non-list!');
$this->expectExceptionMessage('A list shape cannot describe a non-list');
Type::parseString('list{a: 0, b?: 1, c?: 2}');
}
public function testTKeyedListNonListOptionalWrongOrder1(): void
{
$this->expectExceptionMessage('A list shape cannot describe a non-list!');
$this->expectExceptionMessage('A list shape cannot describe a non-list');
Type::parseString('list{0?: 0, 1: 1, 2: 2}');
}
public function testTKeyedListNonListOptionalWrongOrder2(): void
{
$this->expectExceptionMessage('A list shape cannot describe a non-list!');
$this->expectExceptionMessage('A list shape cannot describe a non-list');
Type::parseString('list{0: 0, 1?: 1, 2: 2}');
}
public function testTKeyedListWrongOrder(): void
{
$this->expectExceptionMessage('A list shape cannot describe a non-list!');
$this->expectExceptionMessage('A list shape cannot describe a non-list');
Type::parseString('list{1: 1, 0: 0}');
}
public function testTKeyedListNonListKeys(): void
{
$this->expectExceptionMessage('A list shape cannot describe a non-list!');
$this->expectExceptionMessage('A list shape cannot describe a non-list');
Type::parseString('list{1: 1, 2: 2}');
}
public function testTKeyedListNoExplicitAndImplicitKeys(): void
{
$this->expectExceptionMessage('Cannot mix explicit and implicit keys!');
$this->expectExceptionMessage('Cannot mix explicit and implicit keys');
Type::parseString('list{0: 0, 1}');
}
public function testTKeyedArrayNoExplicitAndImplicitKeys(): void
{
$this->expectExceptionMessage('Cannot mix explicit and implicit keys!');
$this->expectExceptionMessage('Cannot mix explicit and implicit keys');
Type::parseString('array{0, test: 1}');
}
public function testTKeyedArrayNoDuplicateKeys(): void
{
$this->expectExceptionMessage('Duplicate key a detected');
Type::parseString('array{a: int, a: int}');
}
public function testSimpleCallable(): void
{
$this->assertSame(

View File

@ -25,6 +25,13 @@ namespace PHPSTORM_META {
'object' => \stdClass::class,
]));
// tests with class constant as key
override(\Ns\MyClass::crEate3(), map([
'' => '@',
\Ns\MyClass::EXCEPTION => \Exception::class,
\Ns\MyClass::OBJECT => \stdClass::class,
]));
override(\Ns\MyClass::foO(0), type(0));
override(\Ns\MyClass::Bar(0), elementType(0));
override(\foo(0), type(0));