Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Parser Reflection Laravel Package

goaop/parser-reflection

AST-based Reflection API for PHP: introspect classes, methods, and properties directly from source code without autoloading or executing anything. Built on nikic/php-parser and compatible with native Reflection classes—ideal for static analyzers, code generators, and IDE tooling.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation

    composer require goaop/parser-reflection:^3.1.0
    

    Add to require-dev if only needed for testing/analysis. Critical: Requires PHP 8.2+ (minimum version enforced in this release).

  2. First Use Case Analyze a class with PHP 8+ attributes and AST-preserving features:

    use GoAop\ParserReflection\ParserReflection;
    
    $reflection = new ParserReflection();
    $class = $reflection->getClass('App\Models\User');
    
    // New: Check for PHP 8+ attributes
    $attributes = $class->getAttributes();
    foreach ($attributes as $attribute) {
        echo $attribute->getName(); // e.g., #[Cacheable]
    }
    
    // New: AST-preserving node resolution
    $usedNodes = $class->getUsedNodes();
    foreach ($usedNodes as $node) {
        if ($node->isClassReference()) {
            echo $node->getClassName(); // Resolves dynamic references
        }
    }
    
  3. Key Files to Explore

    • src/ParserReflection.php (Core class, fully PHP 8.2+ compliant)
    • src/Reflection/ClassReflection.php (Now supports getAttributes() and AST nodes)
    • src/Reflection/MethodReflection.php (Updated for PHP 8.2+ and new expressions in defaults)
    • src/Reflection/PropertyReflection.php (Fixed getModifiers() for PHP 8.4+)

Implementation Patterns

Common Workflows

  1. PHP 8+ Attributes Analysis

    $reflection = new ParserReflection();
    $class = $reflection->getClass('App\Services\CachedService');
    
    // Get all attributes on a class
    $attributes = $class->getAttributes();
    foreach ($attributes as $attribute) {
        if ($attribute->getName() === 'App\Attributes\Cacheable') {
            $args = $attribute->getArguments();
            // Process attribute arguments (e.g., cache TTL)
        }
    }
    
    // Get attributes on a method
    $method = $class->getMethod('execute');
    $methodAttributes = $method->getAttributes();
    
  2. AST-Preserving Dependency Analysis

    $reflection = new ParserReflection();
    $class = $reflection->getClass('App\Services\OrderService');
    
    // New: AST-preserving node resolution (e.g., for complex expressions)
    $usedNodes = $class->getUsedNodes();
    foreach ($usedNodes as $node) {
        if ($node->isClassReference()) {
            echo $node->getClassName(); // Resolves dynamic references
        }
        if ($node->isNewExpression()) {
            echo $node->getClassName(); // Supports new expressions in defaults
        }
    }
    
  3. Laravel Integration (PHP 8.2+)

    • Use in boot() for runtime analysis:
      public function boot()
      {
          $reflection = new ParserReflection();
          $this->analyzeServiceClasses($reflection);
      }
      
    • Bind to Laravel container (PHP 8.2+):
      $this->app->singleton(ParserReflection::class, function ($app) {
          return new ParserReflection($app['cache']);
      });
      
  4. Testing Patterns with PHP 8.2+ Features

    public function testMethodCoverage()
    {
        $reflection = new ParserReflection();
        $class = $reflection->getClass('App\Tests\Feature\ExampleTest');
    
        // Check for PHP 8.2+ attributes in tests
        $testMethods = $class->getMethods(METHOD_PUBLIC);
        foreach ($testMethods as $method) {
            $attributes = $method->getAttributes();
            if (in_array('App\Attributes\TestCase', array_column($attributes, 'name'))) {
                // Special handling for annotated tests
            }
        }
    }
    
  5. New: Unary Expressions Support

    $property = $reflection->getClass('App\Model')->getProperty('value');
    $defaultValue = $property->getDefaultValue();
    if ($defaultValue->isUnaryMinus()) {
        echo 'Handles unary minus expressions (e.g., -10)';
    }
    

Integration Tips

  • Caching: Cache parsed results for performance (works with PHP 8.2+):
    $cache = new \Symfony\Component\Cache\Adapter\FilesystemAdapter();
    $reflection = new ParserReflection($cache);
    
  • Path Resolution: Override default paths (unchanged):
    $reflection = new ParserReflection();
    $reflection->setBasePath(base_path('custom/vendor'));
    
  • Event Listeners: Use for compile-time checks (e.g., registering event in Laravel).
  • PHP 8.2+ Compatibility: Leverage new features like:
    • getModifiers() for properties (fixed for PHP 8.4+).
    • Support for new expressions in parameter default values.
    • AST-preserving node resolution for advanced analysis.

Gotchas and Tips

Pitfalls

  1. PHP Version Requirement (BREAKING)

    • Critical: This release requires PHP 8.2+. Update your environment:
      php -v  # Must show 8.2.0 or higher
      
    • If using Laravel, ensure your server and local environment meet the requirement.
  2. File Not Found

    • Ensure paths are correct; use getFileName() to debug:
      $reflection->getClass('Class')->getFileName(); // Returns full path
      
    • For Laravel, prepend app/ to class names if not autoloaded.
  3. Attribute Resolution

    • Attributes must be fully qualified (e.g., App\Attributes\Cacheable).
    • Dynamic attributes (e.g., new SomeAttribute()) may not resolve correctly.
  4. AST Node Limitations

    • AST-preserving features are experimental. Use getUsedNodes() cautiously in production.
    • Not all node types are supported (check isNewExpression(), isClassReference(), etc.).
  5. Deprecated Features

    • Avoid deprecated nullable type declarations (fixed for PHP 8.4+):
      // Avoid (deprecated in PHP 8.4+)
      public function foo(?string $bar): ?string;
      
      // Use instead
      public function foo(string|null $bar): string|null;
      
  6. New Expressions in Defaults

    • Support for new expressions in parameter defaults is new. Test thoroughly:
      // Example: new \App\Models\User() in default value
      $method = $reflection->getClass('App\Service')->getMethod('create');
      $defaultValue = $method->getParameter('user')->getDefaultValue();
      if ($defaultValue->isNewExpression()) {
          echo 'Handles new expressions in defaults';
      }
      

Debugging

  • Enable Verbose Output:
    $reflection = new ParserReflection();
    $reflection->setVerbose(true); // Logs parsing steps
    
  • Check for Parsing Errors:
    try {
        $reflection->getClass('BrokenClass');
    } catch (\GoAop\ParserReflection\Exception\ParseException $e) {
        report($e); // Laravel-specific error handling
    }
    
  • PHP 8.2+ Specific Issues:
    • If getModifiers() fails on properties, ensure your PHP version is 8.4+ or use:
      $modifiers = $property->getModifiers() ?? 0;
      
    • For unary expressions, verify node types:
      if (!$defaultValue->isUnaryMinus() && !$defaultValue->isUnaryPlus()) {
          // Handle other cases
      }
      

Extension Points

  1. Custom Reflection Classes Extend GoAop\ParserReflection\Reflection\AbstractReflection for domain-specific analysis (now supports attributes and AST nodes).

  2. Hook into Parsing Override ParserReflection::parseFile() to preprocess files (supports PHP 8.2+ syntax and AST preservation).

  3. Laravel Service Provider Bind the parser to the container (ensure PHP 8.2+ compatibility):

    $this->app->singleton(ParserReflection::class, function ($app) {
        return new ParserReflection($app['cache']);
    });
    
  4. New: AST Node Extensions Extend AST node resolution for custom logic:

    $nodes = $reflection->getClass('App\Service')->getUsedNodes();
    foreach ($nodes as $node) {
        if ($node->isAttribute()) {
            // Custom logic for attributes
        }
        if ($node->
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
terminal42/code-quality-tools
codifyo/ts-generator-bundle
andydefer/laravel-cluster
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky