Skip to content

Global constants in attribute arguments crash weaving (parser-reflection namespace resolution) #602

Description

@lisachenko

Summary

Weaving a namespaced class whose attribute references a global constant (PHP_INT_MAX, PHP_EOL, …) aborts the whole transform:

Go\ParserReflection\ReflectionException: Namespace  was not found in the file .../Php80GlobalConstAttrArg.php

The root cause is upstream in goaop/parser-reflection 4.0.0, but it takes down the framework's weaving pass, so tracking it here from the PHP 8.5 support audit (PR #597). Reproduces on PHP 8.4 / 8.5.10 / 8.6.0beta2.

Reproduction

namespace Some\Ns;

class Php80GlobalConstAttrArg
{
    #[ExprAttr(PHP_INT_MAX)]
    public function limited(): int { return PHP_INT_MAX; }
}
#0 vendor/goaop/parser-reflection/src/ReflectionEngine.php:307 parseFileNamespace()
#1 vendor/goaop/parser-reflection/src/ReflectionFileNamespace.php(102)
#2 vendor/goaop/parser-reflection/src/Resolver/NodeExpressionResolver.php(588): resolveExprConstFetch()
#3 vendor/goaop/parser-reflection/src/Resolver/NodeExpressionResolver.php(189)
#4 vendor/goaop/parser-reflection/src/Traits/AttributeResolverTrait.php(63)
#5 src/Proxy/Generator/MethodGenerator.php(135): ReflectionMethod->getAttributes()

NodeExpressionResolver::resolveExprConstFetch() falls back to looking the constant up in the file's global namespace (ReflectionFileNamespace($file, '')), and since the file only declares Some\Ns, the lookup itself throws.

Fixture: tests/Fixtures/audit/src/Php80GlobalConstAttrArg.php (audit branch). This is also why the audit fixtures initially broke DebugAdvisorCommandTest — one poisoned file aborts debug:advisor for the whole project.

Proposed fix

Two layers:

  1. Framework: this disappears for the weave-time path once attribute arguments are copied from the AST instead of evaluated — see Non-scalar attribute arguments (enum cases, objects, PHP 8.5 closures) crash proxy generation #601. That also stops one bad file from aborting the entire transform for this class of error.
  2. Upstream (goaop/parser-reflection): resolveExprConstFetch() should resolve known built-in/defined constants via defined()/constant() before attempting a ReflectionFileNamespace lookup, and treat a missing global namespace in the file as "not resolvable here" rather than throwing. Filing/fixing that belongs in the parser-reflection repo; this issue tracks the framework-side impact.

Environment

  • goaop/framework master (4.0-dev), goaop/parser-reflection 4.0.0, PHP 8.4 / 8.5.10 / 8.6.0beta2

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions