ai_upgrade_assistant-0.2.0-alpha2/src/Service/MachineLearning/Visitor/ContextPatternVisitor.php

src/Service/MachineLearning/Visitor/ContextPatternVisitor.php
<?php

namespace Drupal\ai_upgrade_assistant\Service\MachineLearning\Visitor;

use PhpParser\Node;
use PhpParser\NodeVisitorAbstract;

/**
 * Visitor for extracting contextual patterns from code.
 */
class ContextPatternVisitor extends NodeVisitorAbstract {

  /**
   * Collected patterns.
   *
   * @var array
   */
  protected $patterns = [];

  /**
   * Context stack.
   *
   * @var array
   */
  protected $contextStack = [];

  /**
   * Current namespace.
   *
   * @var string
   */
  protected $currentNamespace = '';

  /**
   * Use statements.
   *
   * @var array
   */
  protected $useStatements = [];

  /**
   * {@inheritdoc}
   */
  public function beforeTraverse(array $nodes) {
    $this->patterns = [
      'module_context' => [],
      'class_context' => [],
      'method_context' => [],
      'dependency_context' => [],
      'usage_context' => [],
    ];
    $this->contextStack = [];
    return null;
  }

  /**
   * {@inheritdoc}
   */
  public function enterNode(Node $node) {
    if ($node instanceof Node\Stmt\Namespace_) {
      $this->enterNamespace($node);
    }
    elseif ($node instanceof Node\Stmt\Use_) {
      $this->collectUseStatement($node);
    }
    elseif ($node instanceof Node\Stmt\Class_) {
      $this->enterClass($node);
    }
    elseif ($node instanceof Node\Stmt\ClassMethod) {
      $this->enterMethod($node);
    }
    elseif ($node instanceof Node\Expr\MethodCall || $node instanceof Node\Expr\StaticCall) {
      $this->analyzeMethodUsage($node);
    }
  }

  /**
   * {@inheritdoc}
   */
  public function leaveNode(Node $node) {
    if ($node instanceof Node\Stmt\Class_ || $node instanceof Node\Stmt\ClassMethod) {
      array_pop($this->contextStack);
    }
  }

  /**
   * Processes namespace node.
   */
  protected function enterNamespace(Node\Stmt\Namespace_ $node) {
    $this->currentNamespace = $node->name ? $node->name->toString() : '';
    
    // Extract module context from namespace
    if (strpos($this->currentNamespace, 'Drupal\\') === 0) {
      $parts = explode('\\', $this->currentNamespace);
      if (isset($parts[1])) {
        $this->patterns['module_context'][] = [
          'type' => 'module_namespace',
          'module' => $parts[1],
          'namespace' => $this->currentNamespace,
        ];
      }
    }
  }

  /**
   * Collects use statements.
   */
  protected function collectUseStatement(Node\Stmt\Use_ $node) {
    foreach ($node->uses as $use) {
      $this->useStatements[$use->getAlias()->name] = [
        'name' => $use->name->toString(),
        'alias' => $use->alias ? $use->alias->toString() : null,
      ];
    }
  }

  /**
   * Processes class node.
   */
  protected function enterClass(Node\Stmt\Class_ $node) {
    $context = [
      'type' => 'class',
      'name' => $node->name->toString(),
      'namespace' => $this->currentNamespace,
      'dependencies' => $this->collectClassDependencies($node),
    ];
    
    $this->contextStack[] = $context;
    $this->patterns['class_context'][] = $context;
  }

  /**
   * Processes method node.
   */
  protected function enterMethod(Node\Stmt\ClassMethod $node) {
    $context = [
      'type' => 'method',
      'name' => $node->name->toString(),
      'class_context' => end($this->contextStack),
      'dependencies' => $this->collectMethodDependencies($node),
    ];
    
    $this->contextStack[] = $context;
    $this->patterns['method_context'][] = $context;
  }

  /**
   * Analyzes method usage context.
   */
  protected function analyzeMethodUsage(Node $node) {
    $currentContext = end($this->contextStack);
    if (!$currentContext) {
      return;
    }

    $usage = [
      'type' => $node instanceof Node\Expr\StaticCall ? 'static_call' : 'method_call',
      'context' => $currentContext,
    ];

    if ($node instanceof Node\Expr\StaticCall) {
      if ($node->class instanceof Node\Name) {
        $usage['class'] = $this->resolveClassName($node->class);
      }
    }
    elseif ($node instanceof Node\Expr\MethodCall) {
      if ($node->var instanceof Node\Expr\Variable) {
        $usage['variable'] = $node->var->name;
      }
    }

    if ($node->name instanceof Node\Identifier) {
      $usage['method'] = $node->name->toString();
    }

    $this->patterns['usage_context'][] = $usage;
  }

  /**
   * Collects class dependencies.
   */
  protected function collectClassDependencies(Node\Stmt\Class_ $node) {
    $dependencies = [];

    // Collect extends
    if ($node->extends) {
      $dependencies['extends'] = $this->resolveClassName($node->extends);
    }

    // Collect implements
    if ($node->implements) {
      $dependencies['implements'] = array_map(
        function ($interface) {
          return $this->resolveClassName($interface);
        },
        $node->implements
      );
    }

    // Collect traits
    foreach ($node->stmts as $stmt) {
      if ($stmt instanceof Node\Stmt\TraitUse) {
        $dependencies['traits'] = array_map(
          function ($trait) {
            return $this->resolveClassName($trait);
          },
          $stmt->traits
        );
      }
    }

    $this->patterns['dependency_context'][] = [
      'type' => 'class_dependencies',
      'class' => $node->name->toString(),
      'dependencies' => $dependencies,
    ];

    return $dependencies;
  }

  /**
   * Collects method dependencies.
   */
  protected function collectMethodDependencies(Node\Stmt\ClassMethod $node) {
    $dependencies = [];

    // Collect parameter types
    foreach ($node->params as $param) {
      if ($param->type instanceof Node\Name) {
        $dependencies['parameters'][] = [
          'name' => $param->var->name,
          'type' => $this->resolveClassName($param->type),
        ];
      }
    }

    // Collect return type
    if ($node->returnType instanceof Node\Name) {
      $dependencies['return_type'] = $this->resolveClassName($node->returnType);
    }

    $this->patterns['dependency_context'][] = [
      'type' => 'method_dependencies',
      'method' => $node->name->toString(),
      'class_context' => end($this->contextStack),
      'dependencies' => $dependencies,
    ];

    return $dependencies;
  }

  /**
   * Resolves class name using use statements and current namespace.
   */
  protected function resolveClassName(Node\Name $name) {
    if ($name->isFullyQualified()) {
      return $name->toString();
    }

    $firstPart = $name->getFirst();
    if (isset($this->useStatements[$firstPart])) {
      $nameParts = $name->getParts();
      array_shift($nameParts);
      return $this->useStatements[$firstPart]['name'] . ($nameParts ? '\\' . implode('\\', $nameParts) : '');
    }

    return $this->currentNamespace . '\\' . $name->toString();
  }

  /**
   * Gets collected patterns.
   *
   * @return array
   *   The collected patterns.
   */
  public function getPatterns() {
    return $this->patterns;
  }
}

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

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