Skip to content

Commit

Permalink
add support for parsing try/catch under Syntax::Keyword::Try
Browse files Browse the repository at this point in the history
  • Loading branch information
wchristian committed Dec 29, 2022
1 parent 48792b6 commit ac8c427
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 4 deletions.
2 changes: 2 additions & 0 deletions Changes
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,11 @@ Revision history for Perl extension PPI
- Framework for recognition of parsing feature activation via:
- `use $PERL_VERSION` in code
- `use feature` in code
- `use $Common::CPAN::Module` in code
- PPI::Document->new( feature_mods => ... )
- Added ability to parse features:
- signatures, as PPI::Token::Signature
- try catch, as PPI::Statement::Compound

1.276 2022-07-19 21:43:50Z
Summary:
Expand Down
23 changes: 22 additions & 1 deletion lib/PPI/Lexer.pm
Original file line number Diff line number Diff line change
Expand Up @@ -440,7 +440,12 @@ sub _statement {
my $is_lexsub = 0;

# Is it a token in our known classes list
my $class = $STATEMENT_CLASSES{$Token->content};
my $class = {
%STATEMENT_CLASSES,
( try => 'PPI::Statement::Compound' ) x
!!( $Parent->schild(-1) || $Parent )->presumed_features->{try},
}->{ $Token->content };

if ( $class ) {
# Is the next significant token a =>
# Read ahead to the next significant token
Expand Down Expand Up @@ -905,6 +910,22 @@ sub _continues {
return $Token->isa('PPI::Token::Structure') && $Token->content eq '{';
}

if ( $type eq 'try' and $LastChild->presumed_features->{try} ) {
return 1 if not $LastChild->isa('PPI::Structure::Block');

my $NextLast = $Statement->schild(-2);
return ''
if $NextLast
and $NextLast->isa('PPI::Token')
and $NextLast->isa('PPI::Token::Word')
and $NextLast->content eq 'catch';

return 1 #
if $Token->isa('PPI::Token::Word') and $Token->content eq 'catch';

return '';
}

# Handle the common continuable block case
if ( $LastChild->isa('PPI::Structure::Block') ) {
# LABEL while (EXPR) BLOCK
Expand Down
6 changes: 5 additions & 1 deletion lib/PPI/Statement/Compound.pm
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,11 @@ sub type {
}
return 'for';
}
return $TYPES{$content} if $Element->isa('PPI::Token::Word');
return {
%TYPES,
( try => 'try' ) x !!$self->presumed_features->{try},
}->{$content}
if $Element->isa('PPI::Token::Word');
return 'continue' if $Element->isa('PPI::Structure::Block');

# Unknown (shouldn't exist?)
Expand Down
4 changes: 3 additions & 1 deletion lib/PPI/Statement/Include.pm
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ sub feature_mods {
return { signatures => 1 } if version::parse($perl_version) >= 5.035;
}

my %known = ( signatures => 1 );
my %known = ( signatures => 1, try => 1 );

if ( $self->module eq "feature" ) {
my @features = grep $known{$_},
Expand All @@ -270,6 +270,8 @@ sub feature_mods {
return { map +( $_ => $on_or_off ), @features } if @features;
}

return { try => 1 } if $self->module eq "Syntax::Keyword::Try";

return;
}

Expand Down
69 changes: 68 additions & 1 deletion t/feature_tracking.t
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

use lib 't/lib';
use PPI::Test::pragmas;
use Test::More tests => 3 + ( $ENV{AUTHOR_TESTING} ? 1 : 0 );
use Test::More tests => 6 + ( $ENV{AUTHOR_TESTING} ? 1 : 0 );

use B 'perlstring';

Expand Down Expand Up @@ -105,6 +105,73 @@ END_PERL
feature_mods => { signatures => 1 };
}

PROTOTYPE_ATTR: {
test_document
<<'END_PERL',
sub meep :prototype(&$) {}
END_PERL
[
'PPI::Statement::Sub' => 'sub meep :prototype(&$) {}',
'PPI::Token::Word' => 'sub',
'PPI::Token::Word' => 'meep',
'PPI::Token::Operator' => ':',
'PPI::Token::Attribute' => 'prototype(&$)',
'PPI::Structure::Block' => '{}',
'PPI::Token::Structure' => '{',
'PPI::Token::Structure' => '}',
],
"prototype attribute";
}

SYNTAX_KEYWORD_TRY: {
test_document
<<'END_PERL',
use Syntax::Keyword::Try;
try{}catch{}
END_PERL
[
'PPI::Statement::Include' => 'use Syntax::Keyword::Try;',
'PPI::Token::Word' => 'use',
'PPI::Token::Word' => 'Syntax::Keyword::Try',
'PPI::Token::Structure' => ';',
'PPI::Statement::Compound' => 'try{}catch{}',
'PPI::Token::Word' => 'try',
'PPI::Structure::Block' => '{}',
'PPI::Token::Structure' => '{',
'PPI::Token::Structure' => '}',
'PPI::Token::Word' => 'catch',
'PPI::Structure::Block' => '{}',
'PPI::Token::Structure' => '{',
'PPI::Token::Structure' => '}',
],
"Syntax::Keyword::Try";
}

CORE_TRY: {
test_document
<<'END_PERL',
use feature "try";
try{}catch{}
END_PERL
[
'PPI::Statement::Include' => 'use feature "try";',
'PPI::Token::Word' => 'use',
'PPI::Token::Word' => 'feature',
'PPI::Token::Quote::Double' => '"try"',
'PPI::Token::Structure' => ';',
'PPI::Statement::Compound' => 'try{}catch{}',
'PPI::Token::Word' => 'try',
'PPI::Structure::Block' => '{}',
'PPI::Token::Structure' => '{',
'PPI::Token::Structure' => '}',
'PPI::Token::Word' => 'catch',
'PPI::Structure::Block' => '{}',
'PPI::Token::Structure' => '{',
'PPI::Token::Structure' => '}',
],
"core try";
}

### TODO from ppi_token_unknown.t , deduplicate

sub one_line_explain {
Expand Down

0 comments on commit ac8c427

Please sign in to comment.