function DrupalDebugClassLoader::checkAnnotations

File

core/tests/Drupal/TestTools/ErrorHandler/DrupalDebugClassLoader.php, line 39

Class

DrupalDebugClassLoader
Extends Symfony's DebugClassLoader for Drupal-aware vendor boundaries.

Namespace

Drupal\TestTools\ErrorHandler

Code

public function checkAnnotations(\ReflectionClass $refl, string $class) : array {
  $deprecations = parent::checkAnnotations($refl, $class);
  // Only process non-trait Drupal classes.
  if (!str_starts_with($class, 'Drupal\\') || trait_exists($class, FALSE)) {
    return $deprecations;
  }
  self::$returnTypesProperty ??= new \ReflectionProperty(DebugClassLoader::class, 'returnTypes');
  $returnTypes = self::$returnTypesProperty->getValue()[$class] ?? [];
  self::$patchTypesProperty ??= new \ReflectionProperty(DebugClassLoader::class, 'patchTypes');
  if (!$returnTypes || empty(self::$patchTypesProperty->getValue($this)['deprecations'])) {
    return $deprecations;
  }
  $classExtension = self::getExtensionName($class);
  $className = str_contains($class, "@anonymous\x00") ? ((get_parent_class($class) ?: key(class_implements($class))) ?: 'class') . '@anonymous' : $class;
  foreach ($returnTypes as $method => $returnTypeData) {
    [$normalizedType, , $declaringClass] = $returnTypeData;
    // Skip if no cross-extension boundary: empty declaring class (magic
    // methods), same class (own @return), or same/non-Drupal extension.
    $declaringExtension = self::getExtensionName($declaringClass);
    if ($declaringClass === '' || $declaringClass === $class || $declaringExtension === NULL || $classExtension === $declaringExtension) {
      continue;
    }
    // Skip if not actually overridden, or already has a native return type.
    $methodRefl = $refl->getMethod($method);
    if ($methodRefl->class !== $class || $methodRefl->hasReturnType()) {
      continue;
    }
    // Skip if the method's docblock contains @deprecated or @return.
    $docComment = $methodRefl->getDocComment();
    if ($docComment !== FALSE && (str_contains($docComment, '@deprecated') || str_contains($docComment, '@return'))) {
      continue;
    }
    $deprecations[] = \sprintf('Method "%s::%s()" might add "%s" as a native return type declaration in the future. Do the same in %s "%s" now to avoid errors or add an explicit @return annotation to suppress this message.', $declaringClass, $method, $normalizedType, interface_exists($declaringClass) ? 'implementation' : 'child class', $className);
  }
  return $deprecations;
}

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.