I was evaluating this module to see if I could use it for something, and in my basic assumptions test I discovered that in the given code:
1: package Foo;
2:
3: sub bar {
4:
5:}
6:
7:my $code = sub {
8:
9:};
10:
lines 6 to 10 are considered "inside bar"
A quick analysis concludes that the code at present relies on new sub declarations to invalidate old ones, so you abuse a subsequent "sub" statement to mean "end of previous sub", when you should really be looking at PPI::Statement::Sub->block->finish->location
Additionally, the present code will also assume that forward declared subs like:
sub foo();
Are full blocks, and lines appearing after them are *also* logically inside 'foo'
Attached is my test case which I have todoised the failing examples.
#!/usr/bin/env perl
# ABSTRACT: Ensure PPIx::LineToSub does what I think it does
use strict;
use warnings;
use Test::More;
use PPI::Util qw( _Document );
use PPIx::LineToSub;
my $code = <<"EOF";
sub un_packaged {
}
package Example;
sub sub_a {
}
package OtherExample;
sub sub_b {
}
my \$anonsub = sub {
};
sub forward();
my \$code = q//;
EOF
my $dom = _Document( \$code );
$dom->index_line_to_sub;
is_linesub( 1, 'main', 'main' );
is_linesub( 2, 'main', 'un_packaged' );
is_linesub( 3, 'main', 'un_packaged' );
is_linesub( 4, 'main', 'un_packaged' );
{
local $TODO = "broken";
is_linesub( 5, 'main', 'main' );
}
is_linesub( 6, 'Example', 'main' );
is_linesub( 7, 'Example', 'main' );
is_linesub( 8, 'Example', 'sub_a' );
is_linesub( 9, 'Example', 'sub_a' );
is_linesub( 10, 'Example', 'sub_a' );
{
local $TODO = "broken";
is_linesub( 11, 'Example', 'main' );
}
is_linesub( 12, 'OtherExample', 'main' );
is_linesub( 13, 'OtherExample', 'main' );
is_linesub( 14, 'OtherExample', 'sub_b' );
is_linesub( 15, 'OtherExample', 'sub_b' );
is_linesub( 16, 'OtherExample', 'sub_b' );
{
local $TODO = "broken";
is_linesub( 17, 'OtherExample', 'main' );
is_linesub( 18, 'OtherExample', 'main' );
is_linesub( 19, 'OtherExample', 'main' );
is_linesub( 20, 'OtherExample', 'main' );
is_linesub( 21, 'OtherExample', 'main' );
}
is_linesub( 22, 'OtherExample', 'forward' );
{
local $TODO = "broken";
is_linesub( 23, 'OtherExample', 'main' );
}
done_testing;
sub is_linesub {
my ( $line, $package, $sub ) = @_;
my ( $got_package, $got_sub ) = $dom->line_to_sub($line);
note "line_to_sub($line)";
if ( defined $package ) {
cmp_ok( $got_package, q[eq], $package, "line $line is package $package" );
}
else {
ok( !defined $got_package, "line $line has undefined package" ) or diag explain $got_package;
}
if ( defined $sub ) {
cmp_ok( $got_sub, q[eq], $sub, "line $line is sub $sub" );
}
else {
ok( !defined $got_sub, "line $line is undefined sub" ) or diag explain $got_sub;
}
}