ai_upgrade_assistant-0.2.0-alpha2/src/Service/NodeVisitor/ClassUsageVisitor.php

src/Service/NodeVisitor/ClassUsageVisitor.php
<?php

namespace Drupal\ai_upgrade_assistant\Service\NodeVisitor;

use PhpParser\Node;
use PhpParser\NodeVisitorAbstract;

/**
 * Node visitor that detects class usage and inheritance.
 */
class ClassUsageVisitor extends NodeVisitorAbstract {

  /**
   * List of findings.
   *
   * @var array
   */
  protected $findings = [];

  /**
   * List of deprecated classes and their replacements.
   *
   * @var array
   */
  protected $deprecatedClasses = [
    // Core Entity Classes
    'Drupal\Core\Entity\EntityNG' => [
      'replacement' => 'Drupal\Core\Entity\ContentEntityBase',
      'version' => '8.0.0',
      'critical' => true,
    ],
    'Drupal\Core\Entity\EntityInterface' => [
      'replacement' => 'Drupal\Core\Entity\EntityInterface',
      'version' => '8.0.0',
      'critical' => true,
    ],
    'Drupal\Core\Entity\Entity' => [
      'replacement' => 'Drupal\Core\Entity\EntityBase',
      'version' => '8.0.0',
      'critical' => true,
    ],
    // Field Classes
    'Drupal\field\Plugin\Type\Widget\WidgetBase' => [
      'replacement' => 'Drupal\Core\Field\WidgetBase',
      'version' => '8.0.0',
      'critical' => true,
    ],
    'Drupal\field\Plugin\Type\Formatter\FormatterBase' => [
      'replacement' => 'Drupal\Core\Field\FormatterBase',
      'version' => '8.0.0',
      'critical' => true,
    ],
    // Plugin Classes
    'Drupal\Component\Plugin\Discovery\DerivativeDiscoveryDecorator' => [
      'replacement' => 'Drupal\Component\Plugin\Discovery\DerivativeInspectionDecorator',
      'version' => '8.0.0',
      'critical' => true,
    ],
    // Config Classes
    'Drupal\Core\Config\Entity\ConfigEntityStorage' => [
      'replacement' => 'Drupal\Core\Config\Entity\ConfigEntityStorage',
      'version' => '8.0.0',
      'critical' => true,
    ],
    // Database Classes
    'Drupal\Core\Database\Driver\mysql\Connection' => [
      'replacement' => 'Drupal\mysql\Driver\Database\mysql\Connection',
      'version' => '10.0.0',
      'critical' => false,
    ],
    'Drupal\Core\Database\Driver\pgsql\Connection' => [
      'replacement' => 'Drupal\pgsql\Driver\Database\pgsql\Connection',
      'version' => '10.0.0',
      'critical' => false,
    ],
    // Form Classes
    'Drupal\Core\Form\FormBase' => [
      'replacement' => 'Drupal\Core\Form\FormBase with #lazy_builder',
      'version' => '10.0.0',
      'critical' => false,
      'note' => 'Consider using #lazy_builder for better performance',
    ],
    // Cache Classes
    'Drupal\Core\Cache\CacheBackendInterface' => [
      'replacement' => 'Drupal\Core\Cache\CacheBackendInterface with tags',
      'version' => '10.0.0',
      'critical' => false,
      'note' => 'Ensure proper cache tags are used',
    ],
  ];

  /**
   * List of classes requiring special attention in Drupal 11.
   *
   * @var array
   */
  protected $drupal11Classes = [
    'Drupal\Core\Entity\EntityTypeInterface' => [
      'changes' => [
        'New methods added for revision support',
        'Enhanced bundle handling',
      ],
      'example' => 'implement getRevisionMetadata() method',
    ],
    'Drupal\Core\Config\Entity\ConfigEntityInterface' => [
      'changes' => [
        'New validation constraints',
        'Enhanced schema handling',
      ],
      'example' => 'implement validateSchema() method',
    ],
  ];

  /**
   * {@inheritdoc}
   */
  public function enterNode(Node $node) {
    if ($node instanceof Node\Stmt\Class_) {
      // Check class inheritance
      if ($node->extends) {
        $extends = $node->extends->toString();
        $finding = [
          'type' => 'class_extends',
          'class' => $node->name->toString(),
          'extends' => $extends,
          'line' => $node->getLine(),
          'file' => $node->getAttribute('file'),
        ];

        if (isset($this->deprecatedClasses[$extends])) {
          $finding['deprecated'] = true;
          $finding['replacement'] = $this->deprecatedClasses[$extends]['replacement'];
          $finding['version'] = $this->deprecatedClasses[$extends]['version'];
          $finding['critical'] = $this->deprecatedClasses[$extends]['critical'];
          if (isset($this->deprecatedClasses[$extends]['note'])) {
            $finding['note'] = $this->deprecatedClasses[$extends]['note'];
          }
        }

        if (isset($this->drupal11Classes[$extends])) {
          $finding['drupal11_changes'] = $this->drupal11Classes[$extends];
        }

        $this->findings[] = $finding;
      }

      // Check interface implementations
      foreach ($node->implements as $interface) {
        $interfaceName = $interface->toString();
        $finding = [
          'type' => 'implements_interface',
          'class' => $node->name->toString(),
          'interface' => $interfaceName,
          'line' => $node->getLine(),
          'file' => $node->getAttribute('file'),
        ];

        if (isset($this->deprecatedClasses[$interfaceName])) {
          $finding['deprecated'] = true;
          $finding['replacement'] = $this->deprecatedClasses[$interfaceName]['replacement'];
          $finding['version'] = $this->deprecatedClasses[$interfaceName]['version'];
          $finding['critical'] = $this->deprecatedClasses[$interfaceName]['critical'];
          if (isset($this->deprecatedClasses[$interfaceName]['note'])) {
            $finding['note'] = $this->deprecatedClasses[$interfaceName]['note'];
          }
        }

        if (isset($this->drupal11Classes[$interfaceName])) {
          $finding['drupal11_changes'] = $this->drupal11Classes[$interfaceName];
        }

        $this->findings[] = $finding;
      }

      // Check for trait usage
      foreach ($node->traits as $trait) {
        $traitName = $trait->toString();
        $finding = [
          'type' => 'uses_trait',
          'class' => $node->name->toString(),
          'trait' => $traitName,
          'line' => $node->getLine(),
          'file' => $node->getAttribute('file'),
        ];

        if (isset($this->deprecatedClasses[$traitName])) {
          $finding['deprecated'] = true;
          $finding['replacement'] = $this->deprecatedClasses[$traitName]['replacement'];
          $finding['version'] = $this->deprecatedClasses[$traitName]['version'];
          $finding['critical'] = $this->deprecatedClasses[$traitName]['critical'];
        }

        $this->findings[] = $finding;
      }
    }
    elseif ($node instanceof Node\Expr\New_) {
      // Check class instantiation
      if ($node->class instanceof Node\Name) {
        $className = $node->class->toString();
        $finding = [
          'type' => 'class_instantiation',
          'class' => $className,
          'line' => $node->getLine(),
          'file' => $node->getAttribute('file'),
          'args_count' => count($node->args),
        ];

        if (isset($this->deprecatedClasses[$className])) {
          $finding['deprecated'] = true;
          $finding['replacement'] = $this->deprecatedClasses[$className]['replacement'];
          $finding['version'] = $this->deprecatedClasses[$className]['version'];
          $finding['critical'] = $this->deprecatedClasses[$className]['critical'];
          if (isset($this->deprecatedClasses[$className]['note'])) {
            $finding['note'] = $this->deprecatedClasses[$className]['note'];
          }
        }

        // Add constructor argument info if available
        if ($node->args) {
          $args = [];
          foreach ($node->args as $arg) {
            if ($arg->value instanceof Node\Scalar\String_) {
              $args[] = $arg->value->value;
            }
          }
          if ($args) {
            $finding['constructor_args'] = $args;
          }
        }

        $this->findings[] = $finding;
      }
    }
  }

  /**
   * Gets the findings.
   *
   * @return array
   *   Array of findings.
   */
  public function getFindings() {
    return $this->findings;
  }

  /**
   * Resets the findings.
   */
  public function reset() {
    $this->findings = [];
  }

}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc