PerlNavigator icon indicating copy to clipboard operation
PerlNavigator copied to clipboard

"Go to definition" on a subroutine fails for subs in different packages and lexical subs

Open HaraldJoerg opened this issue 2 years ago • 2 comments

The function "Go to Definition" fails to identify the correct definition if a subroutine with the same name is present in another package in the same file, or if the subroutine is a lexical sub.

Here's a demo code:

use strict;
package main;

sub show { print "main::show\n"; }

package Private {
    my sub show { print "lexical sub show in package Private\n"; }

    sub barf { 
        # This calls the lexical subroutine in package Private
        show(@_) # but find definition -> main::show
    }
}

package Inner {
    sub show {  print "Inner::show\n" }
}

# This calls main::show
show; # but find definition -> Inner::show

This code has three subroutines called show: "public" subroutines in packages main and Inner, and a lexical subroutine in package Private. When I invoke "Go to Definition" from the places where show is called, it does not select the correct one.

It seems that lexical subroutines are not found at all, and the namespace is ignored for public subroutines.

HaraldJoerg avatar Jul 26 '22 09:07 HaraldJoerg

Thanks for the report. Lexical subroutines are certainly worth supporting and should be fairly straightforward.

Scoping is much harder and the Go To Definition doesn't currently attempt to resolve based on scope. It does have some understanding of scope that is visible in the nested outline view (image below). I suspect the Navigator needs PPI to build a stronger tree based understanding of the document, which would also help with https://github.com/bscan/PerlNavigator/issues/35

image

Currently, it will always Go To the next highest definition. This makes the most sense for $variables, as the prior definition is usually the correct one (e.g. multiple subs that re-use variable names), but this can also fail. Go To Definition in the following example is an example where this doesn't work properly.

my $foo = 1;

sub bar {
    my $foo = 2;
}

print $foo; # This points to the wrong definition. 

bscan avatar Jul 26 '22 14:07 bscan

I understand that scoping is a difficult topic. With PPI, it would be rather cumbersome - if at all possible - to process Object::Pad code, which right now is a unique selling point of PerlNavigator among the Perl language servers.

HaraldJoerg avatar Jul 27 '22 10:07 HaraldJoerg