#!/usr/bin/perl

use Modern::Perl;
use B;
use PPI;
use Devel::Symdump;

my $document = PPI::Document->new( $ARGV[0] );
my $package = $document->find_first('PPI::Statement::Package')->namespace;

require $ARGV[0];

my $syms = Devel::Symdump->new($package);

my @package_methods;

for my $sym ( $syms->functions ) {
	my $b_cv = B::svref_2object(\&{ $sym });
	next unless $b_cv->GV->STASH->NAME eq $package;

	push @package_methods, $b_cv->GV->NAME;
}

my @ms_methods;

my $words = $document->find(sub {
	my $sib_content;
	my $matched = (
		$_[1]->isa('PPI::Token::Word')
		&& grep($_[1]->content() eq $_ , qw/func method/)
		&& $_[1]->next_sibling()->isa('PPI::Token::Whitespace')
		&& ($sib_content = $_[1]->next_sibling()->next_sibling->content())
	);
	return 0 unless $matched;

	my @name = grep($sib_content =~ m/^\b$_\b/, @package_methods);
	return 0 unless scalar(@name) == 1;

	push @ms_methods, {'name' => $name[0], 'line' => $_[1]->line_number};

	return $matched;
});

foreach my $method ( @ms_methods ) {
	say $method->{'name'}, ' declared at ', $method->{'line'};
}
