Code-ART
view release on metacpan or search on metacpan
lib/Code/ART/API/Vim.pm view on Meta::CPAN
}
sub refactor_to_sub {
# Unpack any options...
my $opt_ref = shift // {};
# Grab the source code, which will be sent through the input filestream...
my $source = do{ local $/; readline(*ARGV) };
# Ask Code::ART to do the actual refactoring...
my $refactoring = Code::ART::refactor_to_sub($source, $opt_ref);
# if ($refactoring->{failed}) {
# $refactoring->{reason} = $refactoring->{failed};
# $refactoring->{failed} = 1;
# }
say _Perl_to_VimScript( $refactoring );
}
sub analyze_code {
# Load code to be analyzed...
my $source = do { local $/; readline(*ARGV); };
# Do the full classification...
my $classification = Code::ART::classify_all_vars_in($source);
print _Perl_to_VimScript($classification) and return if $classification->{failed};
# Generate a pattern to match all variables with various interesting properties...
my (@cacograms, @undeclared_vars, @unused_vars);
for my $var (values %{$classification->{vars}}) {
# Collect cacograms (names that don't help you understand)...
if ($var->{is_cacogram} && $var->{declared_at}) {
push @cacograms, _line_and_column_from_ID($source, [$var->{declared_at}])
. $var->{sigil} . $var->{raw_name};
}
# Collect undeclared variables...
if ($var->{declared_at} < 0 && !$var->{is_builtin} && $var->{raw_name} !~ /[:']/) {
push @undeclared_vars, _line_and_column_from_ID($source, [keys %{ $var->{used_at}}])
. $var->{sigil} . $var->{raw_name};
}
# Collect unused variables...
elsif (!keys %{$var->{used_at}}) {
push @unused_vars, _line_and_column_from_ID($source, [$var->{declared_at}])
. $var->{sigil} . $var->{raw_name};
}
}
# Output all the gathered information...
print _Perl_to_VimScript({
cacograms => join('\|', @cacograms),
undeclared_vars => join('\|', @undeclared_vars),
unused_vars => join('\|', @unused_vars),
});
}
my $VimOWS = '\%(\_s*\%(#.*\_s*\)*\)';
sub classify_var_at {
# Unpack the specified variable position (i.e. the byte number in the buffer)
my ($cursor_byte) = @_;
# Grab the source code, which will be sent through the input filestream...
my $source = do { local $/; readline(*ARGV); };
# Ask Code::ART to do the actual classification
# (making allowance for the fact that Vim byte numbers start at 1,
# but Perl string indexes start at zero)...
my $info = Code::ART::_classify_var_at($source, $cursor_byte - 1);
# Make sure the resulting information has valid 'sigil' entry...
$info->{sigil} //= q{};
# Convert the various locations found to Vim line/column coordinates...
$info->{matchloc} = _line_and_column_from_ID($source,
[$info->{declared_at}, keys %{$info->{used_at}}]);
$info->{declloc} = _line_and_column_from_ID($source, [$info->{declared_at}]);
# Convert scope details to Vim formats...
my $min_scope
= $info->{declared_at} >= 0 ? _linenum_from_ID($source, $info->{declared_at})
: 1;
my $max_scope = _linenum_from_ID($source, $info->{end_of_scope});
$info->{scopeloc} = '\%>' . ($min_scope-1) . 'l'
. '\%<' . ($max_scope+1) . 'l';
$info->{scope_size} = $max_scope - $min_scope + 1;
# Work out the correct Vim regex to match the valid sigils
# of the various declinations of the variable...
my $sigil_matcher = $info->{sigil} eq '@' ? '\%(\$#\|[@$%]\)'
: $info->{sigil} eq '%' ? '[%$@]'
: $info->{sigil} eq '$' ? '\$#\@!'
: '';
# Build the complete Vim regex for matching any instance of the variable...
$info->{matchname}
= $info->{failed}
? q{}
: $sigil_matcher.$VimOWS.'\%('.$info->{raw_name}
.'\|{'.$VimOWS.$info->{raw_name}.$VimOWS.'}\)'
;
# Build the complete Vim regex for matching just the name of any instance of the variable...
$info->{matchnameonly}
= $info->{failed}
? q{}
: $sigil_matcher.$VimOWS.'\%(\zs'.$info->{raw_name}
.'\ze\|{'.$VimOWS.'\zs'.$info->{raw_name}.'\ze'.$VimOWS.'}\)'
;
# Convert homogram and parogram data to searchable regexes...
for my $gram_type (qw< homograms parograms >) {
my $grams = $info->{$gram_type};
use Data::Dump 'ddx';
$info->{$gram_type}
= join('\|', map { my $gram = $grams->{$_};
my $from = _linenum_from_ID($source, $gram->{from}) - 1;
my $to = _linenum_from_ID($source, $gram->{to} ) + 1;
'\%>'.$from.'l\%<'.$to.'l\%($#\?\|[%@]\)'.$VimOWS.$_;
}
keys %{$grams});
}
# Convert all that information to a Vim dictionary, and output it...
say _Perl_to_VimScript($info);
}
sub find_expr_scope {
my ($from, $to, $match_all) = @_;
( run in 1.553 second using v1.01-cache-2.11-cpan-cdf2f3d4e48 )