Perl-Critic / PPI

53 stars 44 forks source link

wordlike operator parsed as Word after method call with no parens #133

Open moregan opened 9 years ago

moregan commented 9 years ago

Regression between 1.220 and the pre-1.221 master:

1.220:

ppidump '$a->dat x 2;'
                    PPI::Document
                      PPI::Statement
[    1,   1,   1 ]     PPI::Token::Symbol       '$a'
[    1,   3,   3 ]     PPI::Token::Operator     '->'
[    1,   5,   5 ]     PPI::Token::Word         'dat'
[    1,   9,   9 ]     PPI::Token::Operator     'x'
[    1,  11,  11 ]     PPI::Token::Number       '2'
[    1,  12,  12 ]     PPI::Token::Structure    ';'

master:

ppidump '$a->dat x 2;'
                    PPI::Document
                      PPI::Statement
[    1,   1,   1 ]     PPI::Token::Symbol       '$a'
[    1,   3,   3 ]     PPI::Token::Operator     '->'
[    1,   5,   5 ]     PPI::Token::Word         'dat'
[    1,   9,   9 ]     PPI::Token::Word         'x'
[    1,  11,  11 ]     PPI::Token::Number       '2'
[    1,  12,  12 ]     PPI::Token::Structure    ';'

but add parens and master parses it as the x operator:

ppidump '$a->dat() x 2;'
                    PPI::Document
                      PPI::Statement
[    1,   1,   1 ]     PPI::Token::Symbol       '$a'
[    1,   3,   3 ]     PPI::Token::Operator     '->'
[    1,   5,   5 ]     PPI::Token::Word         'dat'
                        PPI::Structure::List    ( ... )
[    1,  11,  11 ]     PPI::Token::Operator     'x'
[    1,  13,  13 ]     PPI::Token::Number       '2'
[    1,  14,  14 ]     PPI::Token::Structure    ';'
moregan commented 9 years ago

Doesn't have to be a method call for 'x' to get parsed as a word:

ppidump 'my $line = join(LD_X, map{LD_H x ($_+2)} @$widths);'
                    PPI::Document
                      PPI::Statement::Variable
[    1,   1,   1 ]     PPI::Token::Word         'my'
[    1,   4,   4 ]     PPI::Token::Symbol       '$line'
[    1,  10,  10 ]     PPI::Token::Operator     '='
[    1,  12,  12 ]     PPI::Token::Word         'join'
                        PPI::Structure::List    ( ... )
                          PPI::Statement::Expression
[    1,  17,  17 ]         PPI::Token::Word     'LD_X'
[    1,  21,  21 ]         PPI::Token::Operator         ','
[    1,  23,  23 ]         PPI::Token::Word     'map'
                            PPI::Structure::Block       { ... }
                              PPI::Statement
[    1,  27,  27 ]             PPI::Token::Word         'LD_H'
[    1,  32,  32 ]             PPI::Token::Word         'x'
                                PPI::Structure::List    ( ... )
                                  PPI::Statement::Expression
[    1,  35,  35 ]                 PPI::Token::Magic    '$_'
[    1,  37,  37 ]                 PPI::Token::Operator         '+'
[    1,  38,  38 ]                 PPI::Token::Number   '2'
[    1,  42,  42 ]         PPI::Token::Cast     '@'
[    1,  43,  43 ]         PPI::Token::Symbol   '$widths'
[    1,  51,  51 ]     PPI::Token::Structure    ';'
moregan commented 9 years ago

not limited to the 'x' operator. see 'cmp' below:

ppidump 'sort { $a->package cmp $b->package } ();'
                    PPI::Document
                      PPI::Statement
[    1,   1,   1 ]     PPI::Token::Word         'sort'
                        PPI::Structure::Block   { ... }
                          PPI::Statement
[    1,   8,   8 ]         PPI::Token::Symbol   '$a'
[    1,  10,  10 ]         PPI::Token::Operator         '->'
[    1,  12,  12 ]         PPI::Token::Word     'package'
[    1,  20,  20 ]         PPI::Token::Word     'cmp'
[    1,  24,  24 ]         PPI::Token::Symbol   '$b'
[    1,  26,  26 ]         PPI::Token::Operator         '->'
[    1,  28,  28 ]         PPI::Token::Word     'package'
                        PPI::Structure::List    ( ... )
[    1,  40,  40 ]     PPI::Token::Structure    ';'
wchristian commented 9 years ago

@moregan I tried to fix it and found this:

/\G(?:\d|(?!(=>|[\w\s])))/

It is stopping me from fixing this, since i already fixed _current_x_is_operator to recognize method calls happening before it, but the regex still fails on c->d x 3.

I must admit i have no idea what the hell that regex means, so you get to apply x to it, split it up into lines and put comments on each line of the regex to explain what it does.

moregan commented 9 years ago

The my $line = join(LD_X, map{LD_H x ($_+2)} @$widths); case above simplifies down to bareword x 1