Initial Commit
This commit is contained in:
@@ -0,0 +1,57 @@
|
||||
package Perl::PrereqScanner::NotQuiteLite::Parser::Aliased;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Perl::PrereqScanner::NotQuiteLite::Util;
|
||||
|
||||
sub register { return {
|
||||
use => {
|
||||
aliased => 'parse_aliased_args',
|
||||
},
|
||||
}}
|
||||
|
||||
sub parse_aliased_args {
|
||||
my ($class, $c, $used_module, $raw_tokens) = @_;
|
||||
|
||||
my $tokens = convert_string_tokens($raw_tokens);
|
||||
|
||||
if (is_version($tokens->[0])) {
|
||||
$c->add($used_module => shift @$tokens);
|
||||
}
|
||||
my $module = $tokens->[0];
|
||||
if (ref $module) {
|
||||
$module = $module->[0];
|
||||
}
|
||||
if (is_module_name($module)) {
|
||||
$c->add($module => 0);
|
||||
}
|
||||
|
||||
# TODO: support alias keyword?
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=encoding utf-8
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Perl::PrereqScanner::NotQuiteLite::Parser::Aliased
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This parser is to deal with a module loaded (aliased) by L<aliased>.
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Kenichi Ishigaki, E<lt>ishigaki@cpan.orgE<gt>
|
||||
|
||||
=head1 COPYRIGHT AND LICENSE
|
||||
|
||||
This software is copyright (c) 2015 by Kenichi Ishigaki.
|
||||
|
||||
This is free software; you can redistribute it and/or modify it under
|
||||
the same terms as the Perl 5 programming language system itself.
|
||||
|
||||
=cut
|
||||
@@ -0,0 +1,133 @@
|
||||
package Perl::PrereqScanner::NotQuiteLite::Parser::AnyMoose;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Perl::PrereqScanner::NotQuiteLite::Util;
|
||||
|
||||
sub register {{
|
||||
use => {
|
||||
'Any::Moose' => 'parse_any_moose_args',
|
||||
},
|
||||
no => {
|
||||
'Any::Moose' => 'remove_extends_and_with',
|
||||
},
|
||||
}}
|
||||
|
||||
sub parse_any_moose_args {
|
||||
my ($class, $c, $used_module, $raw_tokens) = @_;
|
||||
|
||||
my $tokens = convert_string_tokens($raw_tokens);
|
||||
if (is_version($tokens->[0])) {
|
||||
$c->add($used_module => shift @$tokens);
|
||||
}
|
||||
while(my $token = shift @$tokens) {
|
||||
next if ref $token;
|
||||
|
||||
# As Any::Moose falls back to Mouse, it's nice to have
|
||||
# a Mouse variant, but that should not be required.
|
||||
my $module = "Mouse$token";
|
||||
$c->add_recommendation($module => 0) if is_module_name($module);
|
||||
}
|
||||
|
||||
$c->register_keyword_parser(
|
||||
'extends',
|
||||
[$class, 'parse_extends_args', $used_module],
|
||||
);
|
||||
$c->register_keyword_parser(
|
||||
'with',
|
||||
[$class, 'parse_with_args', $used_module],
|
||||
);
|
||||
}
|
||||
|
||||
sub remove_extends_and_with {
|
||||
my ($class, $c, $used_module, $raw_tokens) = @_;
|
||||
|
||||
$c->remove_keyword('extends');
|
||||
$c->remove_keyword('with');
|
||||
}
|
||||
|
||||
sub parse_extends_args { shift->_parse_loader_args(@_) }
|
||||
sub parse_with_args { shift->_parse_loader_args(@_) }
|
||||
|
||||
sub _parse_loader_args {
|
||||
my ($class, $c, $used_module, $raw_tokens) = @_;
|
||||
|
||||
my $tokens = convert_string_tokens($raw_tokens);
|
||||
shift @$tokens; # discard extends, with;
|
||||
|
||||
my $prev;
|
||||
my $saw_any_moose;
|
||||
while(my $token = shift @$tokens) {
|
||||
if (!ref $token) {
|
||||
if ($saw_any_moose) {
|
||||
my $module = "Mouse$token";
|
||||
$c->add_recommendation($module => 0);
|
||||
$prev = $module;
|
||||
} else {
|
||||
$c->add($token => 0);
|
||||
$prev = $token;
|
||||
}
|
||||
next;
|
||||
}
|
||||
if ($token->[0] eq 'any_moose') {
|
||||
$saw_any_moose = 1;
|
||||
next;
|
||||
}
|
||||
my $desc = $token->[1] || '';
|
||||
if ($desc eq '{}') {
|
||||
my @hash_tokens = @{$token->[0] || []};
|
||||
for(my $i = 0, my $len = @hash_tokens; $i < $len; $i++) {
|
||||
if ($hash_tokens[$i][0] eq '-version' and $i < $len - 2) {
|
||||
my $maybe_version_token = $hash_tokens[$i + 2];
|
||||
my $maybe_version = $maybe_version_token->[0];
|
||||
if (ref $maybe_version) {
|
||||
$maybe_version = $maybe_version->[0];
|
||||
}
|
||||
if ($prev and is_version($maybe_version)) {
|
||||
if ($saw_any_moose) {
|
||||
$c->add_recommendation($prev => $maybe_version);
|
||||
} else {
|
||||
$c->add($prev => $maybe_version);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($saw_any_moose and $desc eq '()') {
|
||||
my $tokens_in_parentheses = convert_string_tokens($token->[0]);
|
||||
for my $token_in_parentheses (@$tokens_in_parentheses) {
|
||||
next if ref $token_in_parentheses;
|
||||
my $module = "Mouse$token_in_parentheses";
|
||||
$c->add_recommendation($module => 0) if is_module_name($module);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=encoding utf-8
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Perl::PrereqScanner::NotQuiteLite::Parser::AnyMoose
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This parser is to deal with modules loaded by C<extends>
|
||||
from L<Any::Moose> and its friends.
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Kenichi Ishigaki, E<lt>ishigaki@cpan.orgE<gt>
|
||||
|
||||
=head1 COPYRIGHT AND LICENSE
|
||||
|
||||
This software is copyright (c) 2017 by Kenichi Ishigaki.
|
||||
|
||||
This is free software; you can redistribute it and/or modify it under
|
||||
the same terms as the Perl 5 programming language system itself.
|
||||
|
||||
=cut
|
||||
@@ -0,0 +1,54 @@
|
||||
package Perl::PrereqScanner::NotQuiteLite::Parser::Autouse;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Perl::PrereqScanner::NotQuiteLite::Util;
|
||||
|
||||
sub register { return {
|
||||
use => {
|
||||
'autouse' => 'parse_autouse_args',
|
||||
},
|
||||
}}
|
||||
|
||||
sub parse_autouse_args {
|
||||
my ($class, $c, $used_module, $raw_tokens) = @_;
|
||||
|
||||
my $tokens = convert_string_tokens($raw_tokens);
|
||||
if (is_version($tokens->[0])) {
|
||||
$c->add($used_module => shift @$tokens);
|
||||
}
|
||||
my $module = $tokens->[0];
|
||||
if (ref $module) {
|
||||
$module = $module->[0];
|
||||
}
|
||||
if (is_module_name($module)) {
|
||||
$c->add_recommendation($module => 0);
|
||||
}
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=encoding utf-8
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Perl::PrereqScanner::NotQuiteLite::Parser::Autouse
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This parser is to deal with lazy module loading by C<autouse>.
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Kenichi Ishigaki, E<lt>ishigaki@cpan.orgE<gt>
|
||||
|
||||
=head1 COPYRIGHT AND LICENSE
|
||||
|
||||
This software is copyright (c) 2017 by Kenichi Ishigaki.
|
||||
|
||||
This is free software; you can redistribute it and/or modify it under
|
||||
the same terms as the Perl 5 programming language system itself.
|
||||
|
||||
=cut
|
||||
@@ -0,0 +1,67 @@
|
||||
package Perl::PrereqScanner::NotQuiteLite::Parser::Catalyst;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Perl::PrereqScanner::NotQuiteLite::Util;
|
||||
|
||||
sub register { return {
|
||||
use => {
|
||||
Catalyst => 'parse_catalyst_args',
|
||||
},
|
||||
}}
|
||||
|
||||
sub parse_catalyst_args {
|
||||
my ($class, $c, $used_module, $raw_tokens) = @_;
|
||||
|
||||
my @copied_tokens = @$raw_tokens;
|
||||
if (($copied_tokens[0][1] || '') eq '()') {
|
||||
my $token = shift @copied_tokens;
|
||||
unshift @copied_tokens, @{$token->[0]};
|
||||
}
|
||||
if (is_version($copied_tokens[0])) {
|
||||
$c->add($used_module => shift @copied_tokens);
|
||||
}
|
||||
|
||||
my @plugins;
|
||||
for my $token (@copied_tokens) {
|
||||
my $desc = $token->[1] or next;
|
||||
if ($desc eq 'STRING') {
|
||||
push @plugins, $token->[0][0];
|
||||
} elsif ($desc eq 'QUOTED_WORD_LIST') {
|
||||
push @plugins, split /\s/, $token->[0][0];
|
||||
}
|
||||
}
|
||||
|
||||
for my $plugin (@plugins) {
|
||||
next if $plugin =~ /^\-/;
|
||||
$plugin = "Catalyst::Plugin::$plugin" unless $plugin =~ s/^\+//;
|
||||
$c->add($plugin => 0) if is_module_name($plugin);
|
||||
}
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=encoding utf-8
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Perl::PrereqScanner::NotQuiteLite::Parser::Catalyst
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This parser is to deal with module inheritance by C<Catalyst>.
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Kenichi Ishigaki, E<lt>ishigaki@cpan.orgE<gt>
|
||||
|
||||
=head1 COPYRIGHT AND LICENSE
|
||||
|
||||
This software is copyright (c) 2017 by Kenichi Ishigaki.
|
||||
|
||||
This is free software; you can redistribute it and/or modify it under
|
||||
the same terms as the Perl 5 programming language system itself.
|
||||
|
||||
=cut
|
||||
@@ -0,0 +1,92 @@
|
||||
package Perl::PrereqScanner::NotQuiteLite::Parser::ClassAccessor;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Perl::PrereqScanner::NotQuiteLite::Util;
|
||||
|
||||
sub register {{
|
||||
use => {
|
||||
'Class::Accessor' => 'parse_class_accessor_args',
|
||||
'Class::Accessor::Fast' => 'parse_class_accessor_args',
|
||||
'Class::Accessor::Faster' => 'parse_class_accessor_args',
|
||||
'Class::XSAccessor::Compat' => 'parse_class_accessor_args',
|
||||
}
|
||||
}}
|
||||
|
||||
sub parse_class_accessor_args {
|
||||
my ($class, $c, $used_module, $raw_tokens) = @_;
|
||||
|
||||
my $tokens = convert_string_tokens($raw_tokens);
|
||||
if (is_version($tokens->[0])) {
|
||||
$c->add($used_module => shift @$tokens);
|
||||
}
|
||||
while(my $token = shift @$tokens) {
|
||||
if ($token =~ /^(?:antlers|moose-?like)$/i) {
|
||||
$c->register_keyword_parser(
|
||||
'extends',
|
||||
[$class, 'parse_extends_args', $used_module],
|
||||
);
|
||||
last;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sub parse_extends_args {
|
||||
my ($class, $c, $used_module, $raw_tokens) = @_;
|
||||
|
||||
my $tokens = convert_string_tokens($raw_tokens);
|
||||
shift @$tokens; # discard extends, with;
|
||||
|
||||
my $prev;
|
||||
for my $token (@$tokens) {
|
||||
if (!ref $token) {
|
||||
$c->add($token => 0);
|
||||
$prev = $token;
|
||||
next;
|
||||
}
|
||||
my $desc = $token->[1] || '';
|
||||
if ($desc eq '{}') {
|
||||
my @hash_tokens = @{$token->[0] || []};
|
||||
for(my $i = 0, my $len = @hash_tokens; $i < $len; $i++) {
|
||||
if ($hash_tokens[$i][0] eq '-version' and $i < $len - 2) {
|
||||
my $maybe_version_token = $hash_tokens[$i + 2];
|
||||
my $maybe_version = $maybe_version_token->[0];
|
||||
if (ref $maybe_version) {
|
||||
$maybe_version = $maybe_version->[0];
|
||||
}
|
||||
if ($prev and is_version($maybe_version)) {
|
||||
$c->add($prev => $maybe_version);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=encoding utf-8
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Perl::PrereqScanner::NotQuiteLite::Parser::ClassAccessor
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This parser is to deal with modules loaded by C<extends>
|
||||
from L<Class::Accessor> and its friends.
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Kenichi Ishigaki, E<lt>ishigaki@cpan.orgE<gt>
|
||||
|
||||
=head1 COPYRIGHT AND LICENSE
|
||||
|
||||
This software is copyright (c) 2017 by Kenichi Ishigaki.
|
||||
|
||||
This is free software; you can redistribute it and/or modify it under
|
||||
the same terms as the Perl 5 programming language system itself.
|
||||
|
||||
=cut
|
||||
@@ -0,0 +1,76 @@
|
||||
package Perl::PrereqScanner::NotQuiteLite::Parser::ClassAutouse;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Perl::PrereqScanner::NotQuiteLite::Util;
|
||||
|
||||
sub register { return {
|
||||
use => {
|
||||
'Class::Autouse' => 'parse_class_autouse_args',
|
||||
},
|
||||
}}
|
||||
|
||||
sub parse_class_autouse_args {
|
||||
my ($class, $c, $used_module, $raw_tokens) = @_;
|
||||
|
||||
my $tokens = convert_string_tokens($raw_tokens);
|
||||
if (is_version($tokens->[0])) {
|
||||
$c->add($used_module => shift @$tokens);
|
||||
}
|
||||
while(my $token = shift @$tokens) {
|
||||
my $module = $token;
|
||||
if (ref $module) {
|
||||
$module = $module->[0];
|
||||
}
|
||||
if (is_module_name($module)) {
|
||||
$c->add_recommendation($module => 0);
|
||||
}
|
||||
}
|
||||
|
||||
$c->register_method_parser(
|
||||
'autouse',
|
||||
[$class, 'parse_autouse_method_args', $used_module],
|
||||
);
|
||||
}
|
||||
|
||||
sub parse_autouse_method_args {
|
||||
my ($class, $c, $used_module, $raw_tokens) = @_;
|
||||
my $tokens = convert_string_tokens($raw_tokens);
|
||||
|
||||
# Check class
|
||||
my ($klass, $arrow, $method, @args) = @$tokens;
|
||||
return unless $klass and ref $klass and $klass->[0] eq $used_module;
|
||||
return unless $method and ref $method and $method->[0] eq 'autouse';
|
||||
for my $arg (@args) {
|
||||
next if ref $arg;
|
||||
$c->add_recommendation($arg => 0);
|
||||
}
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=encoding utf-8
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Perl::PrereqScanner::NotQuiteLite::Parser::ClassAutouse
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This parser is to deal with modules loaded dynamically by
|
||||
C<Class::Autouse>.
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Kenichi Ishigaki, E<lt>ishigaki@cpan.orgE<gt>
|
||||
|
||||
=head1 COPYRIGHT AND LICENSE
|
||||
|
||||
This software is copyright (c) 2017 by Kenichi Ishigaki.
|
||||
|
||||
This is free software; you can redistribute it and/or modify it under
|
||||
the same terms as the Perl 5 programming language system itself.
|
||||
|
||||
=cut
|
||||
@@ -0,0 +1,146 @@
|
||||
package Perl::PrereqScanner::NotQuiteLite::Parser::ClassLoad;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Perl::PrereqScanner::NotQuiteLite::Util;
|
||||
|
||||
my %known_functions = map {$_ => 1} qw/
|
||||
load_class try_load_class load_optional_class
|
||||
load_first_existing_class
|
||||
/;
|
||||
|
||||
sub register { return {
|
||||
use => {
|
||||
'Class::Load' => 'parse_class_load_args',
|
||||
},
|
||||
}}
|
||||
|
||||
sub register_fqfn { return {
|
||||
map { "Class::Load::".$_ => "parse_".$_."_args" }
|
||||
keys %known_functions
|
||||
}}
|
||||
|
||||
sub parse_class_load_args {
|
||||
my ($class, $c, $used_module, $raw_tokens) = @_;
|
||||
|
||||
my $tokens = convert_string_tokens($raw_tokens);
|
||||
if (is_version($tokens->[0])) {
|
||||
$c->add($used_module => shift @$tokens);
|
||||
}
|
||||
|
||||
for my $token (@$tokens) {
|
||||
next if ref $token;
|
||||
|
||||
if ($known_functions{$token}) {
|
||||
$c->register_keyword_parser(
|
||||
$token,
|
||||
[$class, 'parse_'.$token.'_args', $used_module],
|
||||
);
|
||||
} elsif ($token eq ':all') {
|
||||
for my $func (keys %known_functions) {
|
||||
$c->register_keyword_parser(
|
||||
$func,
|
||||
[$class, 'parse_'.$func.'_args', $used_module],
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sub parse_load_class_args {
|
||||
my ($class, $c, $used_module, $raw_tokens) = @_;
|
||||
|
||||
my $tokens = convert_string_tokens($raw_tokens);
|
||||
shift @$tokens; # function
|
||||
my ($module, undef, $options) = @$tokens;
|
||||
my $version = 0;
|
||||
if (ref $options and $options->[1] eq '{}') {
|
||||
my $tokens_in_hashref = convert_string_tokens($options->[0]);
|
||||
while(my ($key, undef, $value, undef) = splice @$tokens_in_hashref, 0, 4) {
|
||||
if (ref $key and $key->[0] eq '-version' and is_version($value)) {
|
||||
$version = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
$c->add_conditional($module => $version);
|
||||
}
|
||||
|
||||
sub parse_try_load_class_args {
|
||||
my ($class, $c, $used_module, $raw_tokens) = @_;
|
||||
|
||||
my $tokens = convert_string_tokens($raw_tokens);
|
||||
shift @$tokens; # function
|
||||
my ($module, undef, $options) = @$tokens;
|
||||
my $version = 0;
|
||||
if (ref $options and $options->[1] eq '{}') {
|
||||
my $tokens_in_hashref = convert_string_tokens($options->[0]);
|
||||
while(my ($key, undef, $value, undef) = splice @$tokens_in_hashref, 0, 4) {
|
||||
if (ref $key and $key->[0] eq '-version' and is_version($value)) {
|
||||
$version = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
$c->add_suggestion($module => $version);
|
||||
}
|
||||
|
||||
sub parse_load_optional_class_args {
|
||||
my ($class, $c, $used_module, $raw_tokens) = @_;
|
||||
|
||||
$class->parse_try_load_class_args($c, $used_module, $raw_tokens);
|
||||
}
|
||||
|
||||
sub parse_load_first_existing_class_args {
|
||||
my ($class, $c, $used_module, $raw_tokens) = @_;
|
||||
|
||||
my $tokens = convert_string_tokens($raw_tokens);
|
||||
shift @$tokens; # function
|
||||
my ($module, $version);
|
||||
for my $token (@$tokens) {
|
||||
if (is_module_name($token)) {
|
||||
if ($module) {
|
||||
$c->add_suggestion($module => $version);
|
||||
}
|
||||
$module = $token;
|
||||
$version = 0;
|
||||
next;
|
||||
}
|
||||
if (ref $token and ($token->[1] || '') eq '{}') {
|
||||
my $tokens_in_hashref = convert_string_tokens($token->[0]);
|
||||
while(my ($key, undef, $value, undef) = splice @$tokens_in_hashref, 0, 4) {
|
||||
if (ref $key and $key->[0] eq '-version' and is_version($value)) {
|
||||
$version = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($module) {
|
||||
$c->add_suggestion($module => $version);
|
||||
}
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=encoding utf-8
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Perl::PrereqScanner::NotQuiteLite::Parser::ClassLoad
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This parser is to deal with module loading by C<Class::Load>.
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Kenichi Ishigaki, E<lt>ishigaki@cpan.orgE<gt>
|
||||
|
||||
=head1 COPYRIGHT AND LICENSE
|
||||
|
||||
This software is copyright (c) 2017 by Kenichi Ishigaki.
|
||||
|
||||
This is free software; you can redistribute it and/or modify it under
|
||||
the same terms as the Perl 5 programming language system itself.
|
||||
|
||||
=cut
|
||||
198
database/perl/lib/Perl/PrereqScanner/NotQuiteLite/Parser/Core.pm
Normal file
198
database/perl/lib/Perl/PrereqScanner/NotQuiteLite/Parser/Core.pm
Normal file
@@ -0,0 +1,198 @@
|
||||
package Perl::PrereqScanner::NotQuiteLite::Parser::Core;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Perl::PrereqScanner::NotQuiteLite::Util;
|
||||
|
||||
my %feature_since = (
|
||||
say => '5.010',
|
||||
state => '5.010',
|
||||
switch => '5.010',
|
||||
unicode_strings => '5.012',
|
||||
current_sub => '5.016',
|
||||
evalbytes => '5.016',
|
||||
fc => '5.016',
|
||||
arybase => '5.016',
|
||||
unicode_eval => '5.016',
|
||||
lexical_subs => '5.018',
|
||||
postderef => '5.020',
|
||||
postderef_qq => '5.020',
|
||||
signatures => '5.020',
|
||||
bitwise => '5.022',
|
||||
refaliasing => '5.022',
|
||||
declared_refs => '5.026',
|
||||
);
|
||||
|
||||
sub register { return {
|
||||
use => {
|
||||
if => 'parse_if_args',
|
||||
base => 'parse_base_args',
|
||||
parent => 'parse_parent_args',
|
||||
feature => 'parse_feature_args',
|
||||
},
|
||||
keyword => {
|
||||
package => 'parse_package',
|
||||
exit => 'parse_begin_exit',
|
||||
},
|
||||
}}
|
||||
|
||||
sub parse_if_args {
|
||||
my ($class, $c, $used_module, $raw_tokens) = @_;
|
||||
|
||||
while(my $token = shift @$raw_tokens) {
|
||||
last if $token->[1] eq 'COMMA';
|
||||
}
|
||||
|
||||
my $tokens = convert_string_tokens($raw_tokens);
|
||||
my $module = shift @$tokens;
|
||||
if (ref $module and ($module->[1] eq 'WORD' or $module->[1] eq 'KEYWORD')) {
|
||||
$module = $module->[0];
|
||||
}
|
||||
if (is_module_name($module)) {
|
||||
if (is_version($tokens->[0])) {
|
||||
my $version = shift @$tokens;
|
||||
$c->add_recommendation($module => $version);
|
||||
} else {
|
||||
$c->add_recommendation($module => 0);
|
||||
}
|
||||
} else {
|
||||
push @{$c->{errors}}, "use if module not found";
|
||||
}
|
||||
}
|
||||
|
||||
sub parse_base_args {
|
||||
my ($class, $c, $used_module, $raw_tokens) = @_;
|
||||
|
||||
my $tokens = convert_string_tokens($raw_tokens);
|
||||
if (is_version($tokens->[0])) {
|
||||
$c->add($used_module => shift @$tokens);
|
||||
}
|
||||
while(my $token = shift @$tokens) {
|
||||
my $module = $token;
|
||||
if (ref $module and ($module->[1] || '') eq 'WORD') {
|
||||
# allow bareword, but disallow function()
|
||||
$module = $module->[0];
|
||||
next if @$tokens and ref $tokens->[0] and ($tokens->[0][1] || '') eq '()';
|
||||
}
|
||||
# bareword in parentheses
|
||||
if (ref $module and ref $module->[0]) {
|
||||
$module = $module->[0][0];
|
||||
}
|
||||
if (is_module_name($module)) {
|
||||
$c->add($module => 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sub parse_parent_args {
|
||||
my ($class, $c, $used_module, $raw_tokens) = @_;
|
||||
|
||||
my $tokens = convert_string_tokens($raw_tokens);
|
||||
if (is_version($tokens->[0])) {
|
||||
$c->add($used_module => shift @$tokens);
|
||||
}
|
||||
while(my $token = shift @$tokens) {
|
||||
last if $token eq '-norequire';
|
||||
my $module = $token;
|
||||
if (ref $token) {
|
||||
last if $token->[0] eq '-norequire';
|
||||
}
|
||||
if (ref $module and ($module->[1] || '') eq 'WORD') {
|
||||
# allow bareword, but disallow function()
|
||||
$module = $module->[0];
|
||||
next if @$tokens and ref $tokens->[0] and ($tokens->[0][1] || '') eq '()';
|
||||
}
|
||||
# bareword in parentheses
|
||||
if (ref $module and ref $module->[0]) {
|
||||
$module = $module->[0][0];
|
||||
}
|
||||
$c->add($module => 0) if is_module_name($module);
|
||||
}
|
||||
}
|
||||
|
||||
sub parse_feature_args {
|
||||
my ($class, $c, $used_module, $raw_tokens) = @_;
|
||||
|
||||
$c->add_perl('5.010', 'feature');
|
||||
my $tokens = convert_string_tokens($raw_tokens);
|
||||
if (is_version($tokens->[0])) {
|
||||
$c->add($used_module => shift @$tokens);
|
||||
}
|
||||
while(my $token = shift @$tokens) {
|
||||
next if ref $token;
|
||||
if (exists $feature_since{$token}) {
|
||||
$c->add_perl($feature_since{$token} => "feature $token");
|
||||
next;
|
||||
}
|
||||
if ($token =~ /^:5\.([0-9]+)(\.\[0-9]+)?/) {
|
||||
my $version = sprintf '5.%03d', $1;
|
||||
$c->add_perl($version, $token);
|
||||
next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sub parse_begin_exit {
|
||||
my ($class, $c, $raw_tokens) = @_;
|
||||
|
||||
my @stack = @{$c->{stack} || []};
|
||||
if (grep {$_->[0] eq '{' and $_->[2] eq 'BEGIN'} @stack) {
|
||||
if (grep {$c->token_is_conditional($_->[0])} @$raw_tokens) {
|
||||
$c->{force_cond} = 1;
|
||||
} elsif (grep {$_->[0] eq '{' and $c->token_is_conditional($_->[2])} @stack) {
|
||||
$c->{force_cond} = 1;
|
||||
} else {
|
||||
$c->{ended} = 1;
|
||||
@{$c->{stack}} = ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sub parse_package {
|
||||
my ($class, $c, $raw_tokens) = @_;
|
||||
|
||||
my $tokens = convert_string_tokens($raw_tokens);
|
||||
shift @$tokens; # drop "package"
|
||||
my $token = shift @$tokens;
|
||||
if (ref $token && $token->[1] && $token->[1] eq 'WORD') {
|
||||
$c->add_package($token->[0]);
|
||||
}
|
||||
if (@$tokens) {
|
||||
$token = shift @$tokens;
|
||||
if (is_version($token)) {
|
||||
$c->add_perl("5.012", "package PACKAGE VERSION");
|
||||
$token = shift @$tokens;
|
||||
}
|
||||
if (ref $token && $token->[1] && $token->[1] =~ /^\{/) {
|
||||
$c->add_perl("5.014", "package PACKAGE (VERSION) {}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=encoding utf-8
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Perl::PrereqScanner::NotQuiteLite::Parser::Core
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This parser is to deal with module inheritance by C<base> and
|
||||
C<parent> modules, and conditional loading by C<if> module.
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Kenichi Ishigaki, E<lt>ishigaki@cpan.orgE<gt>
|
||||
|
||||
=head1 COPYRIGHT AND LICENSE
|
||||
|
||||
This software is copyright (c) 2015 by Kenichi Ishigaki.
|
||||
|
||||
This is free software; you can redistribute it and/or modify it under
|
||||
the same terms as the Perl 5 programming language system itself.
|
||||
|
||||
=cut
|
||||
@@ -0,0 +1,61 @@
|
||||
package Perl::PrereqScanner::NotQuiteLite::Parser::Inline;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Perl::PrereqScanner::NotQuiteLite::Util;
|
||||
|
||||
sub register { return {
|
||||
use => {
|
||||
Inline => 'parse_inline_args',
|
||||
},
|
||||
}}
|
||||
|
||||
sub parse_inline_args {
|
||||
my ($class, $c, $used_module, $raw_tokens) = @_;
|
||||
|
||||
my $tokens = convert_string_tokens($raw_tokens);
|
||||
|
||||
if (is_version($tokens->[0])) {
|
||||
$c->add($used_module => shift @$tokens);
|
||||
}
|
||||
if (ref $tokens->[0] and is_module_name($tokens->[0][0])) {
|
||||
my $module = (shift @$tokens)->[0];
|
||||
if ($module eq 'with') {
|
||||
$module = $tokens->[1];
|
||||
if (is_module_name($module)) {
|
||||
$c->add($module => 0);
|
||||
}
|
||||
} elsif ($module eq 'Config') {
|
||||
# Configuration only
|
||||
} else {
|
||||
$c->add("Inline::".$module => 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=encoding utf-8
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Perl::PrereqScanner::NotQuiteLite::Parser::Inline
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This parser is to deal with a module loaded by L<Inline>.
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Kenichi Ishigaki, E<lt>ishigaki@cpan.orgE<gt>
|
||||
|
||||
=head1 COPYRIGHT AND LICENSE
|
||||
|
||||
This software is copyright (c) 2017 by Kenichi Ishigaki.
|
||||
|
||||
This is free software; you can redistribute it and/or modify it under
|
||||
the same terms as the Perl 5 programming language system itself.
|
||||
|
||||
=cut
|
||||
@@ -0,0 +1,77 @@
|
||||
package Perl::PrereqScanner::NotQuiteLite::Parser::KeywordDeclare;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Perl::PrereqScanner::NotQuiteLite::Util;
|
||||
|
||||
sub register { return {
|
||||
use => {
|
||||
'Keyword::Declare' => 'parse_keyword_declare_args',
|
||||
},
|
||||
}}
|
||||
|
||||
sub parse_keyword_declare_args {
|
||||
my ($class, $c, $used_module, $raw_tokens) = @_;
|
||||
|
||||
$c->register_sub_keywords(qw/keyword/);
|
||||
$c->register_keywords(qw/keytype is unkeyword/);
|
||||
$c->register_op_keywords(qw/is/);
|
||||
|
||||
$c->register_sub_parser(
|
||||
'keyword',
|
||||
[$class, 'parse_keyword_args', $used_module],
|
||||
);
|
||||
$c->register_keyword_parser(
|
||||
'unkeyword',
|
||||
[$class, 'parse_unkeyword_args', $used_module],
|
||||
);
|
||||
}
|
||||
|
||||
sub parse_keyword_args {
|
||||
my ($class, $c, $used_module, $raw_tokens) = @_;
|
||||
|
||||
my $tokens = convert_string_tokens($raw_tokens);
|
||||
shift @$tokens; # discard keyword
|
||||
|
||||
if (ref $tokens->[0] and $tokens->[0][1]) {
|
||||
$c->register_keywords($tokens->[0][1]);
|
||||
}
|
||||
}
|
||||
|
||||
sub parse_unkeyword_args {
|
||||
my ($class, $c, $used_module, $raw_tokens) = @_;
|
||||
|
||||
my $tokens = convert_string_tokens($raw_tokens);
|
||||
shift @$tokens; # discard unkeyword
|
||||
|
||||
if (ref $tokens->[0] and $tokens->[0][1]) {
|
||||
$c->remove_keywords($tokens->[0][0]);
|
||||
}
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=encoding utf-8
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Perl::PrereqScanner::NotQuiteLite::Parser::KeywordDeclare
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This parser is to deal with keywords imported from L<Keyword::Declare>.
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Kenichi Ishigaki, E<lt>ishigaki@cpan.orgE<gt>
|
||||
|
||||
=head1 COPYRIGHT AND LICENSE
|
||||
|
||||
This software is copyright (c) 2018 by Kenichi Ishigaki.
|
||||
|
||||
This is free software; you can redistribute it and/or modify it under
|
||||
the same terms as the Perl 5 programming language system itself.
|
||||
|
||||
=cut
|
||||
@@ -0,0 +1,54 @@
|
||||
package Perl::PrereqScanner::NotQuiteLite::Parser::Later;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Perl::PrereqScanner::NotQuiteLite::Util;
|
||||
|
||||
sub register { return {
|
||||
use => {
|
||||
'later' => 'parse_later_args',
|
||||
},
|
||||
}}
|
||||
|
||||
sub parse_later_args {
|
||||
my ($class, $c, $used_module, $raw_tokens) = @_;
|
||||
|
||||
my $tokens = convert_string_tokens($raw_tokens);
|
||||
if (is_version($tokens->[0])) {
|
||||
$c->add($used_module => shift @$tokens);
|
||||
}
|
||||
my $module = $tokens->[0];
|
||||
if (ref $module) {
|
||||
$module = $module->[0];
|
||||
}
|
||||
if (is_module_name($module)) {
|
||||
$c->add_recommendation($module => 0);
|
||||
}
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=encoding utf-8
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Perl::PrereqScanner::NotQuiteLite::Parser::Later
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This parser is to deal with lazy module loading by C<later>.
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Kenichi Ishigaki, E<lt>ishigaki@cpan.orgE<gt>
|
||||
|
||||
=head1 COPYRIGHT AND LICENSE
|
||||
|
||||
This software is copyright (c) 2017 by Kenichi Ishigaki.
|
||||
|
||||
This is free software; you can redistribute it and/or modify it under
|
||||
the same terms as the Perl 5 programming language system itself.
|
||||
|
||||
=cut
|
||||
@@ -0,0 +1,48 @@
|
||||
package Perl::PrereqScanner::NotQuiteLite::Parser::Mixin;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Perl::PrereqScanner::NotQuiteLite::Util;
|
||||
|
||||
sub register { return {
|
||||
use => {
|
||||
mixin => 'parse_mixin_args',
|
||||
},
|
||||
}}
|
||||
|
||||
sub parse_mixin_args {
|
||||
my ($class, $c, $used_module, $raw_tokens) = @_;
|
||||
|
||||
my $tokens = convert_string_tokens($raw_tokens);
|
||||
if (is_version($tokens->[0])) {
|
||||
$c->add($used_module => shift @$tokens);
|
||||
}
|
||||
$c->add($_ => 0) for grep {!ref $_} @$tokens;
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=encoding utf-8
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Perl::PrereqScanner::NotQuiteLite::Parser::Mixin
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This parser is to deal with module loading by C<mixin> module.
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Kenichi Ishigaki, E<lt>ishigaki@cpan.orgE<gt>
|
||||
|
||||
=head1 COPYRIGHT AND LICENSE
|
||||
|
||||
This software is copyright (c) 2017 by Kenichi Ishigaki.
|
||||
|
||||
This is free software; you can redistribute it and/or modify it under
|
||||
the same terms as the Perl 5 programming language system itself.
|
||||
|
||||
=cut
|
||||
@@ -0,0 +1,97 @@
|
||||
package Perl::PrereqScanner::NotQuiteLite::Parser::ModuleRuntime;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Perl::PrereqScanner::NotQuiteLite::Util;
|
||||
|
||||
my %known_functions = map {$_ => 1} qw/
|
||||
require_module use_module use_package_optimistically
|
||||
/;
|
||||
|
||||
sub register { return {
|
||||
use => {
|
||||
'Module::Runtime' => 'parse_module_runtime_args',
|
||||
},
|
||||
}}
|
||||
|
||||
sub register_fqfn { return {
|
||||
map { "Module::Runtime::".$_ => "parse_".$_."_args" }
|
||||
keys %known_functions
|
||||
}}
|
||||
|
||||
sub parse_module_runtime_args {
|
||||
my ($class, $c, $used_module, $raw_tokens) = @_;
|
||||
|
||||
my $tokens = convert_string_tokens($raw_tokens);
|
||||
if (is_version($tokens->[0])) {
|
||||
$c->add($used_module => shift @$tokens);
|
||||
}
|
||||
|
||||
for my $token (@$tokens) {
|
||||
next if ref $token;
|
||||
|
||||
if ($known_functions{$token}) {
|
||||
$c->register_keyword_parser(
|
||||
$token,
|
||||
[$class, 'parse_'.$token.'_args', $used_module],
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sub parse_require_module_args {
|
||||
my ($class, $c, $used_module, $raw_tokens) = @_;
|
||||
|
||||
my $tokens = convert_string_tokens($raw_tokens);
|
||||
shift @$tokens; # function
|
||||
my $module = shift @$tokens;
|
||||
return unless is_module_name($module);
|
||||
$c->add_conditional($module => 0);
|
||||
}
|
||||
|
||||
sub parse_use_module_args {
|
||||
my ($class, $c, $used_module, $raw_tokens) = @_;
|
||||
|
||||
my $tokens = convert_string_tokens($raw_tokens);
|
||||
shift @$tokens; # function
|
||||
my ($module, undef, $version) = @$tokens;
|
||||
$version = 0 unless $version and is_version($version);
|
||||
$c->add_conditional($module => $version);
|
||||
}
|
||||
|
||||
sub parse_use_package_optimistically_args {
|
||||
my ($class, $c, $used_module, $raw_tokens) = @_;
|
||||
|
||||
my $tokens = convert_string_tokens($raw_tokens);
|
||||
shift @$tokens; # function
|
||||
my ($module, undef, $version) = @$tokens;
|
||||
$version = 0 unless $version and is_version($version);
|
||||
$c->add_conditional($module => $version);
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=encoding utf-8
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Perl::PrereqScanner::NotQuiteLite::Parser::ModuleRuntime
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This parser is to deal with module loading by C<Module::Runtime>.
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Kenichi Ishigaki, E<lt>ishigaki@cpan.orgE<gt>
|
||||
|
||||
=head1 COPYRIGHT AND LICENSE
|
||||
|
||||
This software is copyright (c) 2017 by Kenichi Ishigaki.
|
||||
|
||||
This is free software; you can redistribute it and/or modify it under
|
||||
the same terms as the Perl 5 programming language system itself.
|
||||
|
||||
=cut
|
||||
@@ -0,0 +1,65 @@
|
||||
package Perl::PrereqScanner::NotQuiteLite::Parser::MojoBase;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Perl::PrereqScanner::NotQuiteLite::Util;
|
||||
|
||||
my @MojoBaseLike = qw/
|
||||
Mojo::Base
|
||||
Mojo::Weixin::Base Mojo::Webqq::Base
|
||||
Kelp::Base Rethinkdb::Base PMLTQ::Base
|
||||
/;
|
||||
|
||||
sub register {
|
||||
my ($class, %args) = @_;
|
||||
my %mojo_base_like = map {$_ => 1} (@MojoBaseLike, @{$args{mojo_base_like} || []});
|
||||
my %mapping;
|
||||
for my $module (keys %mojo_base_like) {
|
||||
$mapping{use}{$module} = 'parse_mojo_base_args';
|
||||
}
|
||||
return \%mapping;
|
||||
}
|
||||
|
||||
sub parse_mojo_base_args {
|
||||
my ($class, $c, $used_module, $raw_tokens) = @_;
|
||||
|
||||
my $tokens = convert_string_tokens($raw_tokens);
|
||||
if (is_version($tokens->[0])) {
|
||||
$c->add($used_module => shift @$tokens);
|
||||
}
|
||||
my $module = $tokens->[0];
|
||||
if (ref $module) {
|
||||
$module = $module->[0];
|
||||
}
|
||||
if (is_module_name($module)) {
|
||||
$module =~ s|'|::|g;
|
||||
$c->add($module => 0);
|
||||
}
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=encoding utf-8
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Perl::PrereqScanner::NotQuiteLite::Parser::MojoBase
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This parser is to deal with module inheritance by C<Mojo::Base>.
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Kenichi Ishigaki, E<lt>ishigaki@cpan.orgE<gt>
|
||||
|
||||
=head1 COPYRIGHT AND LICENSE
|
||||
|
||||
This software is copyright (c) 2017 by Kenichi Ishigaki.
|
||||
|
||||
This is free software; you can redistribute it and/or modify it under
|
||||
the same terms as the Perl 5 programming language system itself.
|
||||
|
||||
=cut
|
||||
@@ -0,0 +1,200 @@
|
||||
package Perl::PrereqScanner::NotQuiteLite::Parser::Moose;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Perl::PrereqScanner::NotQuiteLite::Util;
|
||||
|
||||
# There are so many Moose-like variants
|
||||
|
||||
# Like Moose; modules that are not listed here but have Moose
|
||||
# in their name are implicitly treated like these as well
|
||||
my @ExportsExtendsAndWith = qw/
|
||||
Moose Moo Mouse MooX Moo::Lax Moos
|
||||
MooseX::App MooseX::Singleton MooseX::SingletonMethod
|
||||
|
||||
HTML::FormHandler::Moose Test::Class::Moose
|
||||
|
||||
App::GHPT::Wrapper::OurMoose App::wmiirc::Plugin Ark
|
||||
Bot::Backbone::Service Bubblegum::Class CatalystX::Declare
|
||||
Cogwheel CPAN::Testers::Backend::Base Dancer2::Plugin
|
||||
Data::Object::Class DBICx::Modeler::Model Digital::Driver
|
||||
Elastic::Doc Fey::ORM::Table Form::Factory::Processor
|
||||
Jedi::App Momo Moonshine::Magic Moxie Nile::Base
|
||||
Parse::FixedRecord Pcore Reaction::Class Reaction::UI::WidgetClass
|
||||
Squirrel Statocles::Base TAEB::OO Test::Able Test::Roo
|
||||
Web::Simple XML::Rabbit
|
||||
/;
|
||||
|
||||
# Like Moose::Role; modules that are not listed here but have Role
|
||||
# in their name are implicitly treated like these as well
|
||||
|
||||
my @ExportsWith = qw/
|
||||
Moose::Role Moo::Role Mouse::Role
|
||||
MooseX::Role::Parameterized
|
||||
Mason::PluginRole Mojo::RoleTiny MooX::Cmd
|
||||
Role::Basic Role::Tiny Role::Tiny::With Reflex::Role
|
||||
Template::Caribou Test::Routine App::SimulateReads::Base
|
||||
/;
|
||||
|
||||
# Like Mo
|
||||
my @ExportsExtends = qw/
|
||||
Mo
|
||||
Lingy::Base OptArgs2::Mo Parse::SAMGov::Mo Pegex::Base
|
||||
Sub::Mage TestML::Base Type::Utils VSO
|
||||
/;
|
||||
|
||||
sub register {
|
||||
my ($class, %args) = @_;
|
||||
|
||||
# Make sure everything is unique
|
||||
my %exports_extends_and_with = map {$_ => 1} (@ExportsExtendsAndWith, @{$args{exports_extends_and_with} || []});
|
||||
my %exports_extends = map {$_ => 1} (@ExportsExtends, @{$args{exports_extends} || []});
|
||||
my %exports_with = map {$_ => 1} (@ExportsWith, @{$args{exports_with} || []});
|
||||
|
||||
for my $module (keys %exports_with) {
|
||||
if (exists $exports_extends_and_with{$module}) {
|
||||
delete $exports_with{$module};
|
||||
next;
|
||||
}
|
||||
if (exists $exports_extends{$module}) {
|
||||
$exports_extends_and_with{$module} = 1;
|
||||
delete $exports_with{$module};
|
||||
next;
|
||||
}
|
||||
}
|
||||
for my $module (keys %exports_extends) {
|
||||
if (exists $exports_extends_and_with{$module}) {
|
||||
delete $exports_extends{$module};
|
||||
next;
|
||||
}
|
||||
}
|
||||
|
||||
my %mapping;
|
||||
for my $module (keys %exports_with) {
|
||||
$mapping{use}{$module} = 'register_with';
|
||||
$mapping{no}{$module} = 'remove_with';
|
||||
}
|
||||
for my $module (keys %exports_extends) {
|
||||
$mapping{use}{$module} = 'register_extends';
|
||||
$mapping{no}{$module} = 'remove_extends';
|
||||
}
|
||||
for my $module (keys %exports_extends_and_with) {
|
||||
$mapping{use}{$module} = 'register_extends_and_with';
|
||||
$mapping{no}{$module} = 'remove_extends_and_with';
|
||||
}
|
||||
|
||||
return \%mapping;
|
||||
}
|
||||
|
||||
sub register_extends_and_with {
|
||||
my ($class, $c, $used_module, $raw_tokens) = @_;
|
||||
|
||||
$c->register_keyword_parser(
|
||||
'extends',
|
||||
[$class, 'parse_extends_args', $used_module],
|
||||
);
|
||||
$c->register_keyword_parser(
|
||||
'with',
|
||||
[$class, 'parse_with_args', $used_module],
|
||||
);
|
||||
}
|
||||
|
||||
sub register_with {
|
||||
my ($class, $c, $used_module, $raw_tokens) = @_;
|
||||
|
||||
$c->register_keyword_parser(
|
||||
'with',
|
||||
[$class, 'parse_with_args', $used_module],
|
||||
);
|
||||
}
|
||||
|
||||
sub register_extends {
|
||||
my ($class, $c, $used_module, $raw_tokens) = @_;
|
||||
|
||||
$c->register_keyword_parser(
|
||||
'extends',
|
||||
[$class, 'parse_extends_args', $used_module],
|
||||
);
|
||||
}
|
||||
|
||||
sub remove_extends_and_with {
|
||||
my ($class, $c, $used_module, $raw_tokens) = @_;
|
||||
|
||||
$c->remove_keyword('extends');
|
||||
$c->remove_keyword('with');
|
||||
}
|
||||
|
||||
sub remove_with {
|
||||
my ($class, $c, $used_module, $raw_tokens) = @_;
|
||||
|
||||
$c->remove_keyword('with');
|
||||
}
|
||||
|
||||
sub remove_extends {
|
||||
my ($class, $c, $used_module, $raw_tokens) = @_;
|
||||
|
||||
$c->remove_keyword('extends');
|
||||
}
|
||||
|
||||
sub parse_extends_args { shift->_parse_loader_args(@_) }
|
||||
sub parse_with_args { shift->_parse_loader_args(@_) }
|
||||
|
||||
sub _parse_loader_args {
|
||||
my ($class, $c, $used_module, $raw_tokens) = @_;
|
||||
|
||||
my $tokens = convert_string_tokens($raw_tokens);
|
||||
shift @$tokens; # discard extends, with;
|
||||
|
||||
my $prev;
|
||||
for my $token (@$tokens) {
|
||||
if (!ref $token) {
|
||||
$c->add($token => 0);
|
||||
$prev = $token;
|
||||
next;
|
||||
}
|
||||
my $desc = $token->[1] || '';
|
||||
if ($desc eq '{}') {
|
||||
my @hash_tokens = @{$token->[0] || []};
|
||||
for(my $i = 0, my $len = @hash_tokens; $i < $len; $i++) {
|
||||
if ($hash_tokens[$i][0] eq '-version' and $i < $len - 2) {
|
||||
my $maybe_version_token = $hash_tokens[$i + 2];
|
||||
my $maybe_version = $maybe_version_token->[0];
|
||||
if (ref $maybe_version) {
|
||||
$maybe_version = $maybe_version->[0];
|
||||
}
|
||||
if ($prev and is_version($maybe_version)) {
|
||||
$c->add($prev => $maybe_version);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=encoding utf-8
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Perl::PrereqScanner::NotQuiteLite::Parser::Moose
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This parser is to deal with modules loaded by C<extends> and/or
|
||||
C<with> from L<Moose> and its friends.
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Kenichi Ishigaki, E<lt>ishigaki@cpan.orgE<gt>
|
||||
|
||||
=head1 COPYRIGHT AND LICENSE
|
||||
|
||||
This software is copyright (c) 2015 by Kenichi Ishigaki.
|
||||
|
||||
This is free software; you can redistribute it and/or modify it under
|
||||
the same terms as the Perl 5 programming language system itself.
|
||||
|
||||
=cut
|
||||
@@ -0,0 +1,189 @@
|
||||
package Perl::PrereqScanner::NotQuiteLite::Parser::MooseXDeclare;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Perl::PrereqScanner::NotQuiteLite::Util;
|
||||
|
||||
sub register { return {
|
||||
use => {
|
||||
'MooseX::Declare' => 'parse_moosex_declare_args',
|
||||
},
|
||||
}}
|
||||
|
||||
sub parse_moosex_declare_args {
|
||||
my ($class, $c, $used_module, $raw_tokens) = @_;
|
||||
|
||||
$c->register_sub_parser(
|
||||
'class',
|
||||
[$class, 'parse_class_args', $used_module],
|
||||
);
|
||||
$c->register_sub_parser(
|
||||
'role',
|
||||
[$class, 'parse_role_args', $used_module],
|
||||
);
|
||||
|
||||
$c->register_keyword_parser(
|
||||
'extends',
|
||||
[$class, 'parse_extends_args', $used_module],
|
||||
);
|
||||
$c->register_keyword_parser(
|
||||
'with',
|
||||
[$class, 'parse_with_args', $used_module],
|
||||
);
|
||||
|
||||
$c->register_keyword_parser(
|
||||
'namespace',
|
||||
[$class, 'parse_namespace_args', $used_module],
|
||||
);
|
||||
|
||||
$c->register_sub_keywords(qw/
|
||||
class method role
|
||||
before after around override augment
|
||||
/);
|
||||
|
||||
$c->prototype_re(qr{\G(\((?:[^\\\(\)]*(?:\\.[^\\\(\)]*)*)\))});
|
||||
}
|
||||
|
||||
sub parse_class_args {
|
||||
my ($class, $c, $used_module, $raw_tokens) = @_;
|
||||
|
||||
my $namespace = $c->stash->{moosex_declare}{namespace} || '';
|
||||
|
||||
my $tokens = convert_string_tokens($raw_tokens);
|
||||
shift @$tokens; # discard class
|
||||
|
||||
my $class_name = (shift @$tokens || [])->[0] or return;
|
||||
if ($class_name eq '::') {
|
||||
my $name = (shift @$tokens || [])->[0];
|
||||
$class_name = $namespace . '::' . $name;
|
||||
}
|
||||
|
||||
my $prev = '';
|
||||
while(my $token = shift @$tokens) {
|
||||
if ($token->[0] eq 'extends' or $token->[0] eq 'with') {
|
||||
while(1) {
|
||||
my $name = (shift @$tokens || [])->[0];
|
||||
if ($name eq '::') {
|
||||
$name = $namespace . '::' . (shift @$tokens || [])->[0];
|
||||
}
|
||||
$c->add($name => 0) if is_module_name($name);
|
||||
last if !@$tokens;
|
||||
my $next_token = $tokens->[0];
|
||||
last if $next_token->[0] ne ',';
|
||||
shift @$tokens;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sub parse_role_args {
|
||||
my ($class, $c, $used_module, $raw_tokens) = @_;
|
||||
|
||||
my $namespace = $c->stash->{moosex_declare}{namespace} || '';
|
||||
|
||||
my $tokens = convert_string_tokens($raw_tokens);
|
||||
shift @$tokens; # discard role
|
||||
|
||||
my $class_name = (shift @$tokens)->[0];
|
||||
if ($class_name eq '::') {
|
||||
my $name = (shift @$tokens)->[0];
|
||||
$class_name = $namespace . '::' . $name;
|
||||
}
|
||||
|
||||
my $prev = '';
|
||||
while(my $token = shift @$tokens) {
|
||||
if ($token->[0] eq 'with') {
|
||||
while(1) {
|
||||
my $name = (shift @$tokens)->[0];
|
||||
if ($name eq '::') {
|
||||
$name = $namespace . '::' . (shift @$tokens)->[0];
|
||||
}
|
||||
$c->add($name => 0) if is_module_name($name);
|
||||
last if !@$tokens;
|
||||
my $next_token = $tokens->[0];
|
||||
last if $next_token->[0] ne ',';
|
||||
shift @$tokens;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sub parse_namespace_args {
|
||||
my ($class, $c, $used_module, $raw_tokens) = @_;
|
||||
|
||||
my $tokens = convert_string_tokens($raw_tokens);
|
||||
shift @$tokens; # discard namespace
|
||||
|
||||
my $first_token = (shift @$tokens)->[0];
|
||||
if (is_module_name($first_token)) {
|
||||
$c->stash->{moosex_declare}{namespace} = $first_token;
|
||||
}
|
||||
}
|
||||
|
||||
sub parse_extends_args { shift->_parse_loader_args(@_) }
|
||||
sub parse_with_args { shift->_parse_loader_args(@_) }
|
||||
|
||||
sub _parse_loader_args {
|
||||
my ($class, $c, $used_module, $raw_tokens) = @_;
|
||||
|
||||
my $namespace = $c->stash->{moosex_declare}{namespace} || '';
|
||||
|
||||
my $tokens = convert_string_tokens($raw_tokens);
|
||||
shift @$tokens; # discard extends, with;
|
||||
|
||||
my $prev;
|
||||
while(my $token = shift @$tokens) {
|
||||
if (!ref $token) {
|
||||
if ($token =~ /^::/) {
|
||||
$token = $namespace . $token;
|
||||
}
|
||||
$c->add($token => 0);
|
||||
$prev = $token;
|
||||
next;
|
||||
}
|
||||
my $desc = $token->[1] || '';
|
||||
if ($desc eq '{}') {
|
||||
my @hash_tokens = @{$token->[0] || []};
|
||||
for(my $i = 0, my $len = @hash_tokens; $i < $len; $i++) {
|
||||
if ($hash_tokens[$i][0] eq '-version' and $i < $len - 2) {
|
||||
my $maybe_version_token = $hash_tokens[$i + 2];
|
||||
my $maybe_version = $maybe_version_token->[0];
|
||||
if (ref $maybe_version) {
|
||||
$maybe_version = $maybe_version->[0];
|
||||
}
|
||||
if ($prev and is_version($maybe_version)) {
|
||||
$c->add($prev => $maybe_version);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=encoding utf-8
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Perl::PrereqScanner::NotQuiteLite::Parser::MooseXDeclare
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This parser is to deal with modules loaded by C<extends> and/or
|
||||
C<with> from L<MooseX::Declare>.
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Kenichi Ishigaki, E<lt>ishigaki@cpan.orgE<gt>
|
||||
|
||||
=head1 COPYRIGHT AND LICENSE
|
||||
|
||||
This software is copyright (c) 2017 by Kenichi Ishigaki.
|
||||
|
||||
This is free software; you can redistribute it and/or modify it under
|
||||
the same terms as the Perl 5 programming language system itself.
|
||||
|
||||
=cut
|
||||
@@ -0,0 +1,63 @@
|
||||
package Perl::PrereqScanner::NotQuiteLite::Parser::Only;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Perl::PrereqScanner::NotQuiteLite::Util;
|
||||
|
||||
sub register { return {
|
||||
use => {
|
||||
only => 'parse_only_args',
|
||||
},
|
||||
}}
|
||||
|
||||
sub parse_only_args {
|
||||
my ($class, $c, $used_module, $raw_tokens) = @_;
|
||||
|
||||
my $tokens = convert_string_tokens($raw_tokens);
|
||||
|
||||
if (is_version($tokens->[0])) {
|
||||
$c->add($used_module => shift @$tokens);
|
||||
}
|
||||
while(my $token = shift @$tokens) {
|
||||
my $module = $token;
|
||||
if (ref $module) {
|
||||
$module = $module->[0];
|
||||
}
|
||||
next unless is_module_name($module);
|
||||
my $version = shift @$tokens;
|
||||
$version = shift @$tokens if ref $version;
|
||||
if (is_version($version)) {
|
||||
$c->add($module => $version);
|
||||
} else {
|
||||
$c->add($module => 0); # Can't determine a version
|
||||
}
|
||||
last;
|
||||
}
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=encoding utf-8
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Perl::PrereqScanner::NotQuiteLite::Parser::Only
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This parser is to deal with a module loaded by L<only>.
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Kenichi Ishigaki, E<lt>ishigaki@cpan.orgE<gt>
|
||||
|
||||
=head1 COPYRIGHT AND LICENSE
|
||||
|
||||
This software is copyright (c) 2017 by Kenichi Ishigaki.
|
||||
|
||||
This is free software; you can redistribute it and/or modify it under
|
||||
the same terms as the Perl 5 programming language system itself.
|
||||
|
||||
=cut
|
||||
@@ -0,0 +1,47 @@
|
||||
package Perl::PrereqScanner::NotQuiteLite::Parser::POE;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Perl::PrereqScanner::NotQuiteLite::Util;
|
||||
|
||||
sub register { return {
|
||||
use => {
|
||||
POE => 'parse_poe_args',
|
||||
},
|
||||
}}
|
||||
|
||||
sub parse_poe_args {
|
||||
my ($class, $c, $used_module, $raw_tokens) = @_;
|
||||
my $tokens = convert_string_tokens($raw_tokens);
|
||||
if (is_version($tokens->[0])) {
|
||||
$c->add($used_module => shift @$tokens);
|
||||
}
|
||||
$c->add($_ eq "POE" ? $_ : "POE::".$_ => 0) for grep {!ref $_} @$tokens;
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=encoding utf-8
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Perl::PrereqScanner::NotQuiteLite::Parser::POE
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This parser is to deal with modules loaded by L<POE>.
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Kenichi Ishigaki, E<lt>ishigaki@cpan.orgE<gt>
|
||||
|
||||
=head1 COPYRIGHT AND LICENSE
|
||||
|
||||
This software is copyright (c) 2015 by Kenichi Ishigaki.
|
||||
|
||||
This is free software; you can redistribute it and/or modify it under
|
||||
the same terms as the Perl 5 programming language system itself.
|
||||
|
||||
=cut
|
||||
@@ -0,0 +1,85 @@
|
||||
package Perl::PrereqScanner::NotQuiteLite::Parser::PackageVariant;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Perl::PrereqScanner::NotQuiteLite::Util;
|
||||
|
||||
sub register {{
|
||||
use => {
|
||||
'Package::Variant' => 'parse_package_variant_args',
|
||||
},
|
||||
}}
|
||||
|
||||
sub parse_package_variant_args {
|
||||
my ($class, $c, $used_module, $raw_tokens) = @_;
|
||||
|
||||
my $tokens = convert_string_tokens($raw_tokens);
|
||||
|
||||
while(my $token = shift @$tokens) {
|
||||
if (ref $token and $token->[0] eq 'importing') {
|
||||
shift @$tokens if @$tokens && $tokens->[0][1] eq 'COMMA';
|
||||
my $next_token = shift @$tokens or last;
|
||||
if (!ref $next_token) {
|
||||
my $module = $next_token;
|
||||
if (is_module_name($module)) {
|
||||
$c->add($module);
|
||||
if ($c->has_callback_for(use => $module)) {
|
||||
$c->run_callback_for('use', $module, [["use", "KEYWORD"], [$module, "WORD"], [";", ";"]]);
|
||||
}
|
||||
}
|
||||
}
|
||||
elsif ($next_token->[1] eq '[]') {
|
||||
my $modules = convert_string_token_list($next_token->[0]);
|
||||
while(my $module = shift @$modules) {
|
||||
next unless is_module_name($module);
|
||||
$c->add($module);
|
||||
if ($c->has_callback_for(use => $module)) {
|
||||
$c->run_callback_for('use', $module, [["use", "KEYWORD"], [$module, "WORD"], [";", ";"]]);
|
||||
}
|
||||
}
|
||||
} elsif ($next_token->[1] eq '{}') {
|
||||
my $hash_tokens = convert_string_token_list($next_token->[0]);
|
||||
while(my $module = shift @$hash_tokens) {
|
||||
my $arg = shift @$hash_tokens;
|
||||
my @args = $arg->[1] eq '[]' ? @{$arg->[0]} : $arg;
|
||||
$c->add($module);
|
||||
if ($c->has_callback_for(use => $module)) {
|
||||
$c->run_callback_for('use', $module, [["use", "KEYWORD"], [$module, "WORD"], @args, [";", ";"]]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
elsif (ref $token && !ref $token->[0] && $token->[1] eq 'WORD') {
|
||||
shift @$tokens if @$tokens && $tokens->[0][1] eq 'COMMA';
|
||||
shift @$tokens if @$tokens;
|
||||
}
|
||||
shift @$tokens if @$tokens && ref $tokens->[0] && $tokens->[0][1] eq 'COMMA';
|
||||
}
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=encoding utf-8
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Perl::PrereqScanner::NotQuiteLite::Parser::PackageVariant
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This parser is to deal with modules loaded by L<Package::Variant>.
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Kenichi Ishigaki, E<lt>ishigaki@cpan.orgE<gt>
|
||||
|
||||
=head1 COPYRIGHT AND LICENSE
|
||||
|
||||
This software is copyright (c) 2018 by Kenichi Ishigaki.
|
||||
|
||||
This is free software; you can redistribute it and/or modify it under
|
||||
the same terms as the Perl 5 programming language system itself.
|
||||
|
||||
=cut
|
||||
@@ -0,0 +1,87 @@
|
||||
package Perl::PrereqScanner::NotQuiteLite::Parser::Plack;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Perl::PrereqScanner::NotQuiteLite::Util;
|
||||
|
||||
sub register { return {
|
||||
use => {
|
||||
'Plack::Builder' => 'parse_plack_builder_args',
|
||||
},
|
||||
}}
|
||||
|
||||
sub parse_plack_builder_args {
|
||||
my ($class, $c, $used_module, $raw_tokens) = @_;
|
||||
|
||||
# TODO: support add_middleware(_if) methods?
|
||||
|
||||
$c->register_keyword_parser(
|
||||
'enable',
|
||||
[$class, 'parse_enable_args', $used_module],
|
||||
);
|
||||
$c->register_keyword_parser(
|
||||
'enable_if',
|
||||
[$class, 'parse_enable_if_args', $used_module],
|
||||
);
|
||||
}
|
||||
|
||||
sub parse_enable_args {
|
||||
my ($class, $c, $used_module, $raw_tokens) = @_;
|
||||
|
||||
my $tokens = convert_string_tokens($raw_tokens);
|
||||
shift @$tokens; # discard 'enable' itself
|
||||
|
||||
my $module = shift @$tokens or return;
|
||||
if ($module =~ s/^\+//) {
|
||||
$c->add($module => 0);
|
||||
} else {
|
||||
$module =~ s/^Plack::Middleware:://;
|
||||
$c->add("Plack::Middleware::".$module => 0);
|
||||
}
|
||||
}
|
||||
|
||||
sub parse_enable_if_args {
|
||||
my ($class, $c, $used_module, $raw_tokens) = @_;
|
||||
|
||||
while(my $token = shift @$raw_tokens) {
|
||||
last if $token->[1] eq 'COMMA' or ref $token->[0];
|
||||
}
|
||||
shift @$raw_tokens if $raw_tokens->[0][1] eq 'COMMA';
|
||||
|
||||
my $tokens = convert_string_tokens($raw_tokens);
|
||||
|
||||
my $module = shift @$tokens or return;
|
||||
if ($module =~ s/^\+//) {
|
||||
$c->add($module => 0);
|
||||
} else {
|
||||
$module =~ s/^Plack::Middleware:://;
|
||||
$c->add("Plack::Middleware::".$module => 0);
|
||||
}
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=encoding utf-8
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Perl::PrereqScanner::NotQuiteLite::Parser::Plack
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This parser is to deal with Plack middlewares loaded by L<Plack::Builder>.
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Kenichi Ishigaki, E<lt>ishigaki@cpan.orgE<gt>
|
||||
|
||||
=head1 COPYRIGHT AND LICENSE
|
||||
|
||||
This software is copyright (c) 2015 by Kenichi Ishigaki.
|
||||
|
||||
This is free software; you can redistribute it and/or modify it under
|
||||
the same terms as the Perl 5 programming language system itself.
|
||||
|
||||
=cut
|
||||
@@ -0,0 +1,54 @@
|
||||
package Perl::PrereqScanner::NotQuiteLite::Parser::Prefork;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Perl::PrereqScanner::NotQuiteLite::Util;
|
||||
|
||||
sub register { return {
|
||||
use => {
|
||||
prefork => 'parse_prefork_args',
|
||||
},
|
||||
}}
|
||||
|
||||
sub parse_prefork_args {
|
||||
my ($class, $c, $used_module, $raw_tokens) = @_;
|
||||
|
||||
my $tokens = convert_string_tokens($raw_tokens);
|
||||
if (is_version($tokens->[0])) {
|
||||
$c->add($used_module => shift @$tokens);
|
||||
}
|
||||
my $module = $tokens->[0];
|
||||
if (ref $module) {
|
||||
$module = $module->[0];
|
||||
}
|
||||
if (is_module_name($module)) {
|
||||
$c->add($module => 0);
|
||||
}
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=encoding utf-8
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Perl::PrereqScanner::NotQuiteLite::Parser::Prefork
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This parser is to deal with module loaded by C<prefork>.
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Kenichi Ishigaki, E<lt>ishigaki@cpan.orgE<gt>
|
||||
|
||||
=head1 COPYRIGHT AND LICENSE
|
||||
|
||||
This software is copyright (c) 2017 by Kenichi Ishigaki.
|
||||
|
||||
This is free software; you can redistribute it and/or modify it under
|
||||
the same terms as the Perl 5 programming language system itself.
|
||||
|
||||
=cut
|
||||
@@ -0,0 +1,73 @@
|
||||
package Perl::PrereqScanner::NotQuiteLite::Parser::Superclass;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Perl::PrereqScanner::NotQuiteLite::Util;
|
||||
|
||||
sub register { return {
|
||||
use => {
|
||||
superclass => 'parse_superclass_args',
|
||||
},
|
||||
}}
|
||||
|
||||
sub parse_superclass_args {
|
||||
my ($class, $c, $used_module, $raw_tokens) = @_;
|
||||
|
||||
my $tokens = convert_string_tokens($raw_tokens);
|
||||
if (is_version($tokens->[0])) {
|
||||
$c->add($used_module => shift @$tokens);
|
||||
}
|
||||
|
||||
my ($module, $version, $prev);
|
||||
for my $token (@$tokens) {
|
||||
last if $token eq '-norequire';
|
||||
if (ref $token) {
|
||||
last if $token->[0] eq '-norequire';
|
||||
$prev = $token->[0];
|
||||
next;
|
||||
}
|
||||
$prev = $token;
|
||||
|
||||
if (is_module_name($token)) {
|
||||
if ($module) {
|
||||
$c->add($module => $version || 0);
|
||||
}
|
||||
$module = $token;
|
||||
next;
|
||||
}
|
||||
if (is_version($token)) {
|
||||
$c->add($module => $token);
|
||||
}
|
||||
}
|
||||
if ($module) {
|
||||
$c->add($module => 0);
|
||||
}
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=encoding utf-8
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Perl::PrereqScanner::NotQuiteLite::Parser::Superclass
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This parser is to deal with module inheritance managed by
|
||||
L<superclass>.
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Kenichi Ishigaki, E<lt>ishigaki@cpan.orgE<gt>
|
||||
|
||||
=head1 COPYRIGHT AND LICENSE
|
||||
|
||||
This software is copyright (c) 2015 by Kenichi Ishigaki.
|
||||
|
||||
This is free software; you can redistribute it and/or modify it under
|
||||
the same terms as the Perl 5 programming language system itself.
|
||||
|
||||
=cut
|
||||
@@ -0,0 +1,79 @@
|
||||
package Perl::PrereqScanner::NotQuiteLite::Parser::Syntax;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Perl::PrereqScanner::NotQuiteLite::Util;
|
||||
|
||||
my %Unsupported = map {$_ => 1} qw(
|
||||
);
|
||||
|
||||
|
||||
sub register { return {
|
||||
use => {
|
||||
syntax => 'parse_syntax_args',
|
||||
},
|
||||
}}
|
||||
|
||||
sub parse_syntax_args {
|
||||
my ($class, $c, $used_module, $raw_tokens) = @_;
|
||||
|
||||
my $tokens = convert_string_tokens($raw_tokens);
|
||||
|
||||
if (is_version($tokens->[0])) {
|
||||
$c->add($used_module => shift @$tokens);
|
||||
}
|
||||
|
||||
return if ref $tokens->[0];
|
||||
|
||||
my $feature_name = $tokens->[0];
|
||||
|
||||
my $name =
|
||||
join '::',
|
||||
map ucfirst,
|
||||
split m{/},
|
||||
join '',
|
||||
map ucfirst,
|
||||
split qr{_}, $feature_name;
|
||||
|
||||
my $feature_module = "Syntax::Feature::$name";
|
||||
if (is_module_name($feature_module)) {
|
||||
$c->add($feature_module => 0);
|
||||
}
|
||||
|
||||
if ($feature_name =~ /^q[sil]$/) {
|
||||
$c->register_quotelike_keywords($feature_name, 'q'.$feature_name);
|
||||
}
|
||||
|
||||
# Some of the features change syntax too much
|
||||
if ($Unsupported{$feature_name}) {
|
||||
$c->{aborted} = "syntax '$feature_name'";
|
||||
$c->{ended} = 1;
|
||||
}
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=encoding utf-8
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Perl::PrereqScanner::NotQuiteLite::Parser::Syntax
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This parser is to deal with L<syntax> features.
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Kenichi Ishigaki, E<lt>ishigaki@cpan.orgE<gt>
|
||||
|
||||
=head1 COPYRIGHT AND LICENSE
|
||||
|
||||
This software is copyright (c) 2017 by Kenichi Ishigaki.
|
||||
|
||||
This is free software; you can redistribute it and/or modify it under
|
||||
the same terms as the Perl 5 programming language system itself.
|
||||
|
||||
=cut
|
||||
@@ -0,0 +1,89 @@
|
||||
package Perl::PrereqScanner::NotQuiteLite::Parser::SyntaxCollector;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Perl::PrereqScanner::NotQuiteLite::Util;
|
||||
|
||||
sub register { return {
|
||||
use => {
|
||||
'Syntax::Collector' => 'parse_syntax_collector_args',
|
||||
},
|
||||
}}
|
||||
|
||||
sub parse_syntax_collector_args {
|
||||
my ($class, $c, $used_module, $raw_tokens) = @_;
|
||||
|
||||
my $tokens = convert_string_token_list($raw_tokens);
|
||||
|
||||
if (is_version($tokens->[0])) {
|
||||
$c->add($used_module => shift @$tokens);
|
||||
}
|
||||
|
||||
my $spec;
|
||||
if (!(@$tokens % 2)) {
|
||||
while(my ($key, $value) = splice @$tokens, 0, 2) {
|
||||
my $keystr = ref $key ? $key->[0] : $key;
|
||||
if ($keystr eq '-collect') {
|
||||
$spec = $value;
|
||||
last;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$spec = $tokens->[0];
|
||||
}
|
||||
if (ref $spec) {
|
||||
$spec = $spec->[0];
|
||||
}
|
||||
return unless $spec;
|
||||
|
||||
my @features =
|
||||
map {
|
||||
m{^
|
||||
(use|no) \s+ # "use" or "no"
|
||||
(\S+) \s+ # module name
|
||||
([\d\._v]+) # module version
|
||||
(?: # everything else
|
||||
\s* (.+)
|
||||
)? # ... perhaps
|
||||
[;] \s* # semicolon
|
||||
$}x
|
||||
? [$1, $2, $3, [ defined($4) ? eval "($4)" : ()] ]
|
||||
: die("Line q{$_} doesn't conform to 'use MODULE VERSION [ARGS];'")
|
||||
}
|
||||
grep { ! m/^#/ } # not a comment
|
||||
grep { m/[A-Z0-9]/i } # at least one alphanum
|
||||
map { s/(^\s+)|(\s+$)//; $_ } # trim
|
||||
map { split /(\r?\n|\r)/ } # split lines
|
||||
$spec;
|
||||
|
||||
for my $feature (@features) {
|
||||
$c->add($feature->[1], $feature->[2]);
|
||||
}
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=encoding utf-8
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Perl::PrereqScanner::NotQuiteLite::Parser::SyntaxCollector
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This parser is to deal with modules loading by L<Syntax::Collector> module.
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Kenichi Ishigaki, E<lt>ishigaki@cpan.orgE<gt>
|
||||
|
||||
=head1 COPYRIGHT AND LICENSE
|
||||
|
||||
This software is copyright (c) 2017 by Kenichi Ishigaki.
|
||||
|
||||
This is free software; you can redistribute it and/or modify it under
|
||||
the same terms as the Perl 5 programming language system itself.
|
||||
|
||||
=cut
|
||||
@@ -0,0 +1,59 @@
|
||||
package Perl::PrereqScanner::NotQuiteLite::Parser::TestClassMost;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Perl::PrereqScanner::NotQuiteLite::Util;
|
||||
|
||||
sub register { return {
|
||||
use => {
|
||||
'Test::Class::Most' => 'parse_test_class_most_args',
|
||||
},
|
||||
}}
|
||||
|
||||
sub parse_test_class_most_args {
|
||||
my ($class, $c, $used_module, $raw_tokens) = @_;
|
||||
|
||||
my $tokens = convert_string_token_list($raw_tokens);
|
||||
if (is_version($tokens->[0])) {
|
||||
$c->add($used_module => shift @$tokens);
|
||||
}
|
||||
|
||||
while(my ($key, $value) = splice @$tokens, 0, 2) {
|
||||
my $keystr = ref $key ? $key->[0] : $key;
|
||||
if ($keystr eq 'parent') {
|
||||
if (!ref $value) {
|
||||
$c->add($value => 0);
|
||||
} elsif ($value->[1] eq '[]') {
|
||||
my $tokens_inside = convert_string_token_list($value->[0]);
|
||||
$c->add($_ => 0) for @$tokens_inside;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=encoding utf-8
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Perl::PrereqScanner::NotQuiteLite::Parser::TestClassMost
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This parser is to deal with conditional loading by C<Test::Class::Most>.
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Kenichi Ishigaki, E<lt>ishigaki@cpan.orgE<gt>
|
||||
|
||||
=head1 COPYRIGHT AND LICENSE
|
||||
|
||||
This software is copyright (c) 2017 by Kenichi Ishigaki.
|
||||
|
||||
This is free software; you can redistribute it and/or modify it under
|
||||
the same terms as the Perl 5 programming language system itself.
|
||||
|
||||
=cut
|
||||
@@ -0,0 +1,80 @@
|
||||
package Perl::PrereqScanner::NotQuiteLite::Parser::TestMore;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Perl::PrereqScanner::NotQuiteLite::Util;
|
||||
|
||||
sub register { return {
|
||||
use => {
|
||||
'Test::More' => 'parse_test_more_args',
|
||||
},
|
||||
}}
|
||||
|
||||
sub register_fqfn { return +{
|
||||
'Test::More::done_testing' => 'parse_done_testing_args',
|
||||
'Test::More::plan' => 'parse_plan_args',
|
||||
}}
|
||||
|
||||
sub parse_test_more_args {
|
||||
my ($class, $c, $used_module, $raw_tokens) = @_;
|
||||
|
||||
$c->register_keyword_parser(
|
||||
'done_testing',
|
||||
[$class, 'parse_done_testing_args', $used_module],
|
||||
);
|
||||
|
||||
$c->register_keyword_parser(
|
||||
'plan',
|
||||
[$class, 'parse_plan_args', $used_module],
|
||||
);
|
||||
}
|
||||
|
||||
sub parse_done_testing_args {
|
||||
my ($class, $c, $used_module, $raw_tokens) = @_;
|
||||
|
||||
$c->add($used_module => '0.88');
|
||||
}
|
||||
|
||||
sub parse_plan_args {
|
||||
my ($class, $c, $used_module, $raw_tokens) = @_;
|
||||
|
||||
my $tokens = convert_string_tokens($raw_tokens);
|
||||
shift @$tokens; # discard plan
|
||||
|
||||
my $first_token = $tokens->[0] or return;
|
||||
$first_token = $first_token->[0] if ref $first_token;
|
||||
|
||||
if ($first_token eq 'skip_all') {
|
||||
if (grep {$_->[0] eq '{' and $_->[2] eq 'BEGIN'} @{$c->{stack} || []}) {
|
||||
$c->{force_cond} = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=encoding utf-8
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Perl::PrereqScanner::NotQuiteLite::Parser::TestMore
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This parser is to update the minimum version requirement of
|
||||
L<Test::More> to 0.88 if C<done_testing> is found by the scanner.
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Kenichi Ishigaki, E<lt>ishigaki@cpan.orgE<gt>
|
||||
|
||||
=head1 COPYRIGHT AND LICENSE
|
||||
|
||||
This software is copyright (c) 2015 by Kenichi Ishigaki.
|
||||
|
||||
This is free software; you can redistribute it and/or modify it under
|
||||
the same terms as the Perl 5 programming language system itself.
|
||||
|
||||
=cut
|
||||
@@ -0,0 +1,77 @@
|
||||
package Perl::PrereqScanner::NotQuiteLite::Parser::TestRequires;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Perl::PrereqScanner::NotQuiteLite::Util;
|
||||
|
||||
sub register { return {
|
||||
use => {
|
||||
'Test::Requires' => 'parse_test_requires_args',
|
||||
},
|
||||
}}
|
||||
|
||||
sub parse_test_requires_args {
|
||||
my ($class, $c, $used_module, $raw_tokens) = @_;
|
||||
|
||||
$c->register_keyword_parser(
|
||||
'test_requires',
|
||||
[$class, 'parse_test_requires_function_args', $used_module],
|
||||
);
|
||||
|
||||
my $tokens = convert_string_tokens($raw_tokens);
|
||||
if (is_version($tokens->[0])) {
|
||||
$c->add($used_module => shift @$tokens);
|
||||
}
|
||||
|
||||
if (ref $tokens->[0] and $tokens->[0][1] and $tokens->[0][1] eq '{}') {
|
||||
my $tokens_in_hashref = convert_string_tokens($tokens->[0][0]);
|
||||
while(my ($key, undef, $value, undef) = splice @$tokens_in_hashref, 0, 4) {
|
||||
next unless is_module_name($key);
|
||||
next unless is_version($value);
|
||||
$c->add_recommendation($key => $value);
|
||||
}
|
||||
} else {
|
||||
for my $token (@$tokens) {
|
||||
next if ref $token;
|
||||
if ($token =~ /^v?5/) {
|
||||
$c->add_recommendation(perl => $token);
|
||||
} else {
|
||||
$c->add_recommendation($token => 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sub parse_test_requires_function_args {
|
||||
my ($class, $c, $used_module, $raw_tokens) = @_;
|
||||
|
||||
my $tokens = convert_string_tokens($raw_tokens);
|
||||
$c->add_recommendation($_ => 0) for grep {!ref $_} @$tokens;
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=encoding utf-8
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Perl::PrereqScanner::NotQuiteLite::Parser::TestRequires
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This parser is to deal with conditional loading by C<Test::Requires>.
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Kenichi Ishigaki, E<lt>ishigaki@cpan.orgE<gt>
|
||||
|
||||
=head1 COPYRIGHT AND LICENSE
|
||||
|
||||
This software is copyright (c) 2017 by Kenichi Ishigaki.
|
||||
|
||||
This is free software; you can redistribute it and/or modify it under
|
||||
the same terms as the Perl 5 programming language system itself.
|
||||
|
||||
=cut
|
||||
@@ -0,0 +1,62 @@
|
||||
package Perl::PrereqScanner::NotQuiteLite::Parser::UniversalVersion;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Perl::PrereqScanner::NotQuiteLite::Util;
|
||||
|
||||
sub register { return {
|
||||
method => {
|
||||
VERSION => 'parse_version_args',
|
||||
},
|
||||
}}
|
||||
|
||||
sub parse_version_args {
|
||||
my ($class, $c, $raw_tokens) = @_;
|
||||
|
||||
my ($module_token, undef, undef, $args_tokens) = @$raw_tokens;
|
||||
my $module = $module_token->[0];
|
||||
return unless ref $args_tokens->[0];
|
||||
|
||||
my @tokens_in_parens = @{$args_tokens->[0] || []};
|
||||
return if @tokens_in_parens > 1;
|
||||
|
||||
my $version_token = $tokens_in_parens[0];
|
||||
my $module_version;
|
||||
if ($version_token->[1] and $version_token->[1] eq 'NUMBER') {
|
||||
$module_version = $version_token->[0];
|
||||
} elsif (ref $version_token->[0]) {
|
||||
$module_version = $version_token->[0][0];
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
if ($module_version =~ /^v?[0-9._]+$/) {
|
||||
$c->add_conditional($module => $module_version) if $c->has_added_conditional($module);
|
||||
}
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=encoding utf-8
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Perl::PrereqScanner::NotQuiteLite::Parser::UniversalVersion
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This parser is to deal with a VERSION method called by a module.
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Kenichi Ishigaki, E<lt>ishigaki@cpan.orgE<gt>
|
||||
|
||||
=head1 COPYRIGHT AND LICENSE
|
||||
|
||||
This software is copyright (c) 2015 by Kenichi Ishigaki.
|
||||
|
||||
This is free software; you can redistribute it and/or modify it under
|
||||
the same terms as the Perl 5 programming language system itself.
|
||||
|
||||
=cut
|
||||
@@ -0,0 +1,62 @@
|
||||
package Perl::PrereqScanner::NotQuiteLite::Parser::Unless;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Perl::PrereqScanner::NotQuiteLite::Util;
|
||||
|
||||
sub register { return {
|
||||
use => {
|
||||
unless => 'parse_unless_args',
|
||||
},
|
||||
}}
|
||||
|
||||
sub parse_unless_args {
|
||||
my ($class, $c, $used_module, $raw_tokens) = @_;
|
||||
|
||||
while(my $token = shift @$raw_tokens) {
|
||||
last if $token->[1] eq 'COMMA';
|
||||
}
|
||||
|
||||
my $tokens = convert_string_tokens($raw_tokens);
|
||||
my $module = shift @$tokens;
|
||||
if (ref $module and ($module->[1] eq 'WORD' or $module->[1] eq 'KEYWORD')) {
|
||||
$module = $module->[0];
|
||||
}
|
||||
if (is_module_name($module)) {
|
||||
if (is_version($tokens->[0])) {
|
||||
my $version = shift @$tokens;
|
||||
$c->add_recommendation($module => $version);
|
||||
} else {
|
||||
$c->add_recommendation($module => 0);
|
||||
}
|
||||
} else {
|
||||
push @{$c->{errors}}, "use unless module not found";
|
||||
}
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=encoding utf-8
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Perl::PrereqScanner::NotQuiteLite::Parser::Unless
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This parser is to deal with conditional loading by C<unless> module.
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Kenichi Ishigaki, E<lt>ishigaki@cpan.orgE<gt>
|
||||
|
||||
=head1 COPYRIGHT AND LICENSE
|
||||
|
||||
This software is copyright (c) 2017 by Kenichi Ishigaki.
|
||||
|
||||
This is free software; you can redistribute it and/or modify it under
|
||||
the same terms as the Perl 5 programming language system itself.
|
||||
|
||||
=cut
|
||||
Reference in New Issue
Block a user