> the rule being asserted */ public $rule; /** * @var int|string the id of the property/variable, or * the parameter offset of the affected arg */ public $var_id; /** * @param string|int $var_id * @param array> $rule */ public function __construct($var_id, array $rule) { $this->rule = $rule; $this->var_id = $var_id; } /** * @param array> $inferred_upper_bounds */ public function getUntemplatedCopy(array $inferred_upper_bounds, ?string $this_var_id) : self { return new Assertion( \is_string($this->var_id) && $this_var_id ? \str_replace('$this->', $this_var_id . '->', $this->var_id) : $this->var_id, array_map( /** * @param array $rules * * @return array{0: string} */ function (array $rules) use ($inferred_upper_bounds) : array { $first_rule = $rules[0]; if ($inferred_upper_bounds) { $rule_tokens = \Psalm\Internal\Type\TypeTokenizer::tokenize($first_rule); $substitute = false; foreach ($rule_tokens as &$rule_token) { if (isset($inferred_upper_bounds[$rule_token[0]])) { foreach ($inferred_upper_bounds[$rule_token[0]] as $bound) { $substitute = true; $first_type = \array_values($bound->type->getAtomicTypes())[0]; if ($first_type instanceof \Psalm\Type\Atomic\TTemplateParam) { $rule_token[0] = $first_type->param_name; } else { $rule_token[0] = $first_type->getKey(); } } } } if ($substitute) { return [implode( '', array_map( function ($f) { return $f[0]; }, $rule_tokens ) )]; } } return [$first_rule]; }, $this->rule ) ); } }