Skip to content

Commit

Permalink
Add better error message for templated key-of param
Browse files Browse the repository at this point in the history
  • Loading branch information
muglug committed May 28, 2019
1 parent 602bae3 commit b19d256
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 1 deletion.
12 changes: 11 additions & 1 deletion src/Psalm/Type/Union.php
Original file line number Diff line number Diff line change
Expand Up @@ -970,6 +970,8 @@ public function replaceTemplateTypesWithStandins(
}
} else {
foreach ($replacement_type->getTypes() as $replacement_atomic_type) {
$replacements_found = false;

// @codingStandardsIgnoreStart
if ($replacement_atomic_type instanceof Type\Atomic\TTemplateKeyOf
&& isset($template_types[$replacement_atomic_type->param_name][$replacement_atomic_type->defining_class ?: ''][0])
Expand All @@ -989,13 +991,21 @@ public function replaceTemplateTypesWithStandins(
$key_type = $keyed_template->type_params[0];
}

$replacements_found = true;

foreach ($key_type->getTypes() as $key_type_atomic) {
$this->types[$key_type_atomic->getKey()] = clone $key_type_atomic;
}

$generic_params[$key][$atomic_type->defining_class ?: ''][0]
= clone $key_type;
}
}
// @codingStandardsIgnoreEnd

$this->types[$replacement_atomic_type->getKey()] = clone $replacement_atomic_type;
if (!$replacements_found) {
$this->types[$replacement_atomic_type->getKey()] = clone $replacement_atomic_type;
}
}

foreach ($replacement_type->getTypes() as $replacement_key => $_) {
Expand Down
50 changes: 50 additions & 0 deletions tests/Template/TemplateTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -3237,6 +3237,56 @@ function takesIntCollection(Collection $c): void {}
takesIntCollection($collection);',
'error_message' => 'InvalidScalarArgument',
],
'argumentExpectsFleshOutTIndexedAccess' => [
'<?php
/**
* @template TData as array
*/
abstract class Row {
/**
* @var TData
*/
protected $data;
/**
* @param TData $data
*/
public function __construct(array $data) {
$this->data = $data;
}
/**
* @template K as key-of<TData>
*
* @param K $property
*
* @return TData[K]
*/
public function __get(string $property) {
// validation logic would go here
return $this->data[$property];
}
/**
* @template K as key-of<TData>
*
* @param K $property
* @param TData[K] $value
*/
public function __set(string $property, $value) {
// data updating would go here
$this->data[$property] = $value;
}
}
/** @extends Row<array{id: int, name: string, height: float}> */
class CharacterRow extends Row {}
$mario = new CharacterRow(["id" => 5, "name" => "Mario", "height" => 3.5]);
$mario->ame = "Luigi";',
'error_message' => 'InvalidArgument - src' . DIRECTORY_SEPARATOR . 'somefile.php:47:29 - Argument 1 of CharacterRow::__set expects string(id)|string(name)|string(height), string(ame) provided',
],
];
}
}

0 comments on commit b19d256

Please sign in to comment.