Skip to content

fix(ppi): strip trailing :: from bareword method invocants#517

Merged
fglock merged 1 commit intomasterfrom
fix/ppi-bareword-trailing-colons
Apr 21, 2026
Merged

fix(ppi): strip trailing :: from bareword method invocants#517
fglock merged 1 commit intomasterfrom
fix/ppi-bareword-trailing-colons

Conversation

@fglock
Copy link
Copy Markdown
Owner

@fglock fglock commented Apr 20, 2026

Summary

  • Strip trailing :: from bareword method invocants so Foo::->bar() is
    equivalent to Foo->bar() and passes "Foo" (not "Foo::") as the
    first argument, matching real Perl.
  • Fixed in both backends:
    • JVM: Dereference.handleArrowOperator
    • Interpreter: CompileBinaryOperator method-call path
  • Only the bareword-literal form is stripped; a runtime string "Foo::"
    used as invocant is left alone.

Why

PPI's test suite uses the idiom PPI::Token::Whitespace::->new(...)
heavily. Before this fix, PerlOnJava looked up methods in the package
"PPI::Token::Whitespace::" and failed, which aborted
t/ppi_token_whitespace.t on line 1 and contributed to many related PPI
subtest failures.

Discovered while investigating ./jcpan -t PPI. See
dev/modules/ppi.md for the full investigation notes, including a
separate refcount/DESTROY bug (RC2) that still blocks PPI's
while/until/for lexing and requires a coordinated container-store
refcount-parity pass across push/pop/shift/splice/hash-store,
plus rebalancing of unit/refcount/*.t. That work is deferred to its
own project.

Test plan

  • make (full unit tests) passes.
  • New regression test src/test/resources/unit/method_call_trailing_colons.t
    (5 subtests) passes.
  • t/ppi_token_whitespace.t from the PPI CPAN distribution now
    passes 6/6.
  • Before: Foo::->bar() prints [Foo::]. After: prints [Foo],
    matching perl.

Generated with Devin

In Perl, `Foo::->bar()` is equivalent to `Foo->bar()`: the trailing `::`
on a bareword class-method invocant is part of the syntactic form and
is stripped before the class name is passed as the method's first
argument.

PerlOnJava was keeping the `::`, so PPI's `PPI::Token::Whitespace::->new(...)`
idiom (very common throughout PPI's test suite) was looking up methods
in the package `"PPI::Token::Whitespace::"` and failing. This is the
root cause of early aborts in `t/ppi_token_whitespace.t` and contributes
to many related PPI subtest failures.

Strip a trailing `::` from the bareword class name in both backends
where the method invocant is an `IdentifierNode` (JVM backend in
`Dereference.handleArrowOperator`, interpreter backend in
`CompileBinaryOperator` method-call path). Only the bareword-literal
form is stripped; a runtime string `"Foo::"` used as invocant is not
touched.

Adds a unit regression test and records the broader PPI investigation
in dev/modules/ppi.md (including the separate refcount/DESTROY bug that
still blocks PPI's while/until/for lexing, which needs its own
coordinated fix).

Generated with [Devin](https://app.devin.ai/)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@fglock fglock merged commit d890c96 into master Apr 21, 2026
2 checks passed
@fglock fglock deleted the fix/ppi-bareword-trailing-colons branch April 21, 2026 07:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant