Skip to content

Instantly share code, notes, and snippets.

@dasl-
Created November 7, 2019 19:25
Show Gist options
  • Save dasl-/7166fe7b89660c618857bc113f4c5459 to your computer and use it in GitHub Desktop.
Save dasl-/7166fe7b89660c618857bc113f4c5459 to your computer and use it in GitHub Desktop.
diff --git a/src/Phan/Analysis.php b/src/Phan/Analysis.php
index 22b9f1e9..8bdf558b 100644
--- a/src/Phan/Analysis.php
+++ b/src/Phan/Analysis.php
@@ -341,7 +341,14 @@ class Analysis
public static function loadMethodPlugins(CodeBase $code_base) : void
{
$plugin_set = ConfigPluginSet::instance();
- foreach ($plugin_set->getReturnTypeOverrides($code_base) as $fqsen_string => $closure) {
+ $methods_by_defining_fqsen = null;
+ foreach ($plugin_set->getReturnTypeOverrides($code_base) as $fqsen_string => $closure_and_opts) {
+ if (is_array($closure_and_opts)) {
+ [$closure, $opts] = $closure_and_opts;
+ } else {
+ $closure = $closure_and_opts;
+ }
+
try {
if (\stripos($fqsen_string, '::') !== false) {
$fqsen = FullyQualifiedMethodName::fromFullyQualifiedString($fqsen_string);
@@ -353,6 +360,12 @@ class Analysis
if ($code_base->hasMethodWithFQSEN($fqsen)) {
$method = $code_base->getMethodByFQSEN($fqsen);
$method->setDependentReturnTypeClosure($closure);
+ if (isset($opts["should_override_all_method_usages"]) && $opts["should_override_all_method_usages"]) {
+ $methods_by_defining_fqsen = $methods_by_defining_fqsen ?? $code_base->getMethodsGroupedByDefiningFQSEN();
+ foreach ($methods_by_defining_fqsen[$fqsen_string] as $child_method) {
+ $child_method->setDependentReturnTypeClosure($closure);
+ }
+ }
}
}
} else {
diff --git a/src/Phan/CodeBase.php b/src/Phan/CodeBase.php
index 6a76b57b..7a567979 100644
--- a/src/Phan/CodeBase.php
+++ b/src/Phan/CodeBase.php
@@ -1097,6 +1097,18 @@ class CodeBase
return $this->method_set;
}
+ /**
+ * @return array<string,Method[]>
+ */
+ public function getMethodsGroupedByDefiningFQSEN() : array
+ {
+ $methods_by_defining_fqsen = [];
+ foreach ($this->method_set as $method) {
+ $methods_by_defining_fqsen[$method->getDefiningFQSEN()->__toString()][] = $method;
+ }
+ return $methods_by_defining_fqsen;
+ }
+
/**
* @return array<string,array<string,string>>
* A human readable encoding of $this->func_and_method_set [string $function_or_method_name => [int|string $pos => string $spec]]
diff --git a/src/Phan/Plugin/ConfigPluginSet.php b/src/Phan/Plugin/ConfigPluginSet.php
index c6def1e6..0f8642ca 100644
--- a/src/Phan/Plugin/ConfigPluginSet.php
+++ b/src/Phan/Plugin/ConfigPluginSet.php
@@ -625,7 +625,7 @@ final class ConfigPluginSet extends PluginV3 implements
/**
* @param CodeBase $code_base
- * @return array<string,\Closure> maps FQSEN string to closure
+ * @return array<string,\Closure|array{0:\Closure,1:array}> maps FQSEN string to closure
*/
public function getReturnTypeOverrides(CodeBase $code_base) : array
{
diff --git a/src/Phan/PluginV3/ReturnTypeOverrideCapability.php b/src/Phan/PluginV3/ReturnTypeOverrideCapability.php
index 3f8b40fc..424fab56 100644
--- a/src/Phan/PluginV3/ReturnTypeOverrideCapability.php
+++ b/src/Phan/PluginV3/ReturnTypeOverrideCapability.php
@@ -13,7 +13,7 @@ use Phan\CodeBase;
interface ReturnTypeOverrideCapability
{
/**
- * @return array<string,\Closure>
+ * @return array<string,\Closure|array{0:\Closure,1:array}>
* maps FQSEN of function or method to a closure used to override the returned UnionType.
* The returned type is not validated.
* '\A::foo' as a key will override a method, and '\foo' as a key will override a function.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment