Skip to content
Permalink
Browse files

Prevent static methods using class instance template types

  • Loading branch information
muglug committed Dec 14, 2019
1 parent b48021d commit 797a059a84f86f66518c8b6c61870f165fcc27d1
@@ -2330,6 +2330,10 @@ function (FunctionLikeParameter $p) {
);
}

$class_template_types = !$stmt instanceof PhpParser\Node\Stmt\ClassMethod || !$stmt->isStatic()
? $this->class_template_types
: [];

foreach ($docblock_info->params_out as $docblock_param_out) {
$param_name = substr($docblock_param_out['name'], 1);

@@ -2339,11 +2343,11 @@ function (FunctionLikeParameter $p) {
Type::fixUpLocalType(
$docblock_param_out['type'],
$this->aliases,
$this->function_template_types + $this->class_template_types,
$this->function_template_types + $class_template_types,
$this->type_aliases
),
null,
$this->function_template_types + $this->class_template_types
$this->function_template_types + $class_template_types
);

$out_type->queueClassLikesForScanning(
@@ -2455,15 +2459,15 @@ function (FunctionLikeParameter $p) {
$fixed_type_tokens = Type::fixUpLocalType(
$docblock_return_type,
$this->aliases,
$this->function_template_types + $this->class_template_types,
$this->function_template_types + $class_template_types,
$this->type_aliases,
$class_storage && !$class_storage->is_trait ? $class_storage->name : null
);

$storage->return_type = Type::parseTokens(
$fixed_type_tokens,
null,
$this->function_template_types + $this->class_template_types
$this->function_template_types + $class_template_types
);

$storage->return_type->setFromDocblock();
@@ -2654,6 +2658,10 @@ private function getAssertionParts(

$assertion_type_parts = explode('|', $assertion_type);

$class_template_types = !$stmt instanceof PhpParser\Node\Stmt\ClassMethod || !$stmt->isStatic()
? $this->class_template_types
: [];

foreach ($assertion_type_parts as $i => $assertion_type_part) {
if ($assertion_type_part !== 'falsy'
&& $assertion_type_part !== 'array'
@@ -2664,7 +2672,7 @@ private function getAssertionParts(
Type::fixUpLocalType(
$assertion_type_part,
$this->aliases,
$this->function_template_types + $this->class_template_types,
$this->function_template_types + $class_template_types,
$this->type_aliases,
null
)
@@ -2673,7 +2681,7 @@ private function getAssertionParts(
$namespaced_type->queueClassLikesForScanning(
$this->codebase,
$this->file_storage,
$this->function_template_types + $this->class_template_types
$this->function_template_types + $class_template_types
);

$assertion_type_parts[$i] = $prefix . $namespaced_type->getId();
@@ -2816,6 +2824,10 @@ private function improveParamsFromDocblock(

$unused_docblock_params = [];

$class_template_types = !$function instanceof PhpParser\Node\Stmt\ClassMethod || !$function->isStatic()
? $this->class_template_types
: [];

foreach ($docblock_params as $docblock_param) {
$param_name = $docblock_param['name'];
$docblock_param_variadic = false;
@@ -2890,12 +2902,12 @@ private function improveParamsFromDocblock(
Type::fixUpLocalType(
$docblock_param['type'],
$this->aliases,
$this->function_template_types + $this->class_template_types,
$this->function_template_types + $class_template_types,
$this->type_aliases,
$fq_classlike_name
),
null,
$this->function_template_types + $this->class_template_types
$this->function_template_types + $class_template_types
);
} catch (TypeParseTreeException $e) {
if (IssueBuffer::accepts(
@@ -3052,7 +3064,7 @@ private function visitPropertyDeclaration(
$comment,
$this->file_scanner,
$this->aliases,
$this->function_template_types + $this->class_template_types,
$this->function_template_types + (!$stmt->isStatic() ? $this->class_template_types : []),
$this->type_aliases
);

@@ -1202,8 +1202,9 @@ private function __construct($t) {
}
/**
* @param T $t
* @return static<T>
* @template U
* @param U $t
* @return static<U>
*/
public static function getContainer($t) {
return new static($t);
@@ -1246,8 +1247,9 @@ private function __construct($t) {
}
/**
* @param T $t
* @return static<T>
* @template U
* @param U $t
* @return static<U>
*/
public static function getContainer($t) {
return new static($t);
@@ -1296,8 +1298,9 @@ private function __construct($t) {
}
/**
* @param T $t
* @return static<T>
* @template U
* @param U $t
* @return static<U>
*/
public static function getContainer($t) {
return new static($t);
@@ -2014,14 +2017,14 @@ public function __construct(array $data) {
/**
* @return key-of<DATA>
*/
abstract public static function getIdProperty() : string;
abstract public function getIdProperty() : string;
}
/**
* @template-extends Foo<array{id:int, name:string}>
*/
class FooChild extends Foo {
public static function getIdProperty() : string {
public function getIdProperty() : string {
return "id";
}
}',
@@ -2266,11 +2269,11 @@ interface Foo {
/**
* @return T
*/
public static function getItem();
public function getItem();
}
trait FooTrait {
public static function getItem() {
public function getItem() {
return "hello";
}
}
@@ -3298,7 +3301,7 @@ abstract class Stringer {
/**
* @param T $t
*/
public static function getString($t, object $o = null) : string {
public function getString($t, object $o = null) : string {
return "hello";
}
}
@@ -3309,7 +3312,7 @@ class A {}
* @template-extends Stringer<A>
*/
class AStringer extends Stringer {
public static function getString($t, object $o = null) : string {
public function getString($t, object $o = null) : string {
if ($o) {
return parent::getString($o);
}
@@ -2636,6 +2636,19 @@ function takesCollectionOfItems(ArrayCollection $i): void {
takesCollectionOfItems($subitem_collection);',
'error_message' => 'InvalidArgument'
],
'noClassTemplatesInStaticMethods' => [
'<?php
/**
* @template T
*/
class C {
/**
* @param T $t
*/
public static function foo($t) : void {}
}',
'error_message' => 'UndefinedDocblockClass'
],
];
}
}

0 comments on commit 797a059

Please sign in to comment.
You can’t perform that action at this time.