use v6.e.PREVIEW; use nqp; use NQPP6QRegex:from; use NQPHLL:from; use Perl6::Compiler:from; use Raku::Grammar:from; use Raku::Actions:from; use lib $?FILE.IO.parent(2).add('packages'); use Test; use Test::Helpers; plan 2; subtest "Locations" => { my $origins; my $target = q:to/ORIG/; my $line = 1; for ^10 { #line 10 test.raku say "line ", ($line = 2), "+++", "---", "###", "^^^"; } exit(0); ORIG my $comp := Perl6::Compiler.new(); $comp.language('Raku'); $comp.parsegrammar(Raku::Grammar); $comp.parseactions(Raku::Actions); $comp.addstage('syntaxcheck', :before); $comp.addstage('qast', :after); my $root := $comp.compile($target, :target, :source-name, :compunit_ok); multi sub tp(Str:D $needle) { $target.index($needle) } multi sub tp(Regex:D $needle) { ($target ~~ $needle).from } my @tests = (tp('my $line') + 3, %( :line(1), :orig-line(1), :file("foo.raku"), :from(tp('my $line') + 3), # Non-key node :WHAT(RakuAST::VarDeclaration::Simple) ), %( :line(1), :orig-line(1), :file("foo.raku"), :from(tp('my $line')), # Key node :WHAT(RakuAST::Statement::Expression) )), (tp('for ^10'), %( :line(2), :orig-line(2), :file("foo.raku"), from => tp('for ^10'), :WHAT(RakuAST::Statement::For) ), %( :line(2), :orig-line(2), :file("foo.raku"), from => tp('for ^10'), :WHAT(RakuAST::Statement::For) )), (tp('^10 {'), %( :line(2), :orig-line(2), :file("foo.raku"), from => tp('^10 {'), :WHAT(RakuAST::Prefix) ), %( :line(2), :orig-line(2), :file("foo.raku"), from => tp('for ^10 {'), :WHAT(RakuAST::Statement::For) )), (tp('ine ",'), %( :line(10), :orig-line(4), :file("test.raku"), from => tp('"line ",') + 1, :WHAT(RakuAST::QuotedString) ), %( :line(10), :orig-line(4), :file("test.raku"), from => tp('say "line'), :WHAT(RakuAST::Statement::Expression) )), (tp(', ($line'), # The comma belongs to arglist which starts with the first space after `say` %( :line(10), :orig-line(4), :file("test.raku"), from => tp('"line ",'), :WHAT(RakuAST::ArgList) ), %( :line(10), :orig-line(4), :file("test.raku"), from => tp('say "line'), :WHAT(RakuAST::Statement::Expression) )), (tp('$line = 2'), %( :line(10), :orig-line(4), :file("test.raku"), from => tp('$line = 2'), :WHAT(RakuAST::Statement::Expression) ), %( :line(10), :orig-line(4), :file("test.raku"), from => tp('say "line'), :WHAT(RakuAST::Statement::Expression) )), (tp('++",'), %( :line(11), :orig-line(5), :file("test.raku"), from => tp('+++",'), :WHAT(RakuAST::QuotedString) ), %( :line(10), :orig-line(4), :file("test.raku"), from => tp('say "line'), :WHAT(RakuAST::Statement::Expression) )), (tp(/',' \n \s+ '"---'/), %( :line(10), :orig-line(4), :file("test.raku"), from => tp('"line ",'), :WHAT(RakuAST::ArgList) ), %( :line(10), :orig-line(4), :file("test.raku"), from => tp('say "line'), :WHAT(RakuAST::Statement::Expression) )), (tp('--",'), %( :line(12), :orig-line(6), :file("test.raku"), from => tp('---",'), :WHAT(RakuAST::QuotedString) ), %( :line(10), :orig-line(4), :file("test.raku"), from => tp('say "line'), :WHAT(RakuAST::Statement::Expression) )), (tp('##",'), %( :line(13), :orig-line(7), :file("test.raku"), from => tp('###",'), :WHAT(RakuAST::QuotedString) ), %( :line(10), :orig-line(4), :file("test.raku"), from => tp('say "line'), :WHAT(RakuAST::Statement::Expression) )), (tp(";\n}"), %( :line(2), :orig-line(2), :file("foo.raku"), from => tp(/\n '#line 10'/), :WHAT(RakuAST::StatementList) ), %( :line(2), :orig-line(2), :file("foo.raku"), from => tp(/\n '#line 10'/), :WHAT(RakuAST::StatementList) )), (tp('exit(0)'), %( :line(16), :orig-line(10), :file("test.raku"), from => tp('exit(0)'), :WHAT(RakuAST::Call::Name) ), %( :line(16), :orig-line(10), :file("test.raku"), from => tp('exit(0)'), :WHAT(RakuAST::Statement::Expression) )), ; plan +@tests; for ^@tests -> $test-idx { my Int:D $pos = @tests[$test-idx][0]; subtest "Position " ~ $pos => { plan 2; for 0,1 -> $key { next unless @tests[$test-idx][$key + 1]; subtest ($key ?? "Key" !! "Non-key") ~ " node" => { my %attrs = @tests[$test-idx][$key + 1]; plan %attrs.elems; my $node := $root.locate-node($pos, :$key); my $node-match := $node.origin.as-match; for %attrs.pairs.sort -> (:key($attr), Mu :$value) { given $attr { when 'WHAT' { cmp-ok $node.WHAT, &[~~], $value, "node type"; } default { is-deeply $node-match."$attr"(), $value, "attribute $attr"; } } } } } } } } if $*DISTRO.is-win { todo "is-run is having problems on Windows with multi-line code"; } subtest "Backtrace with line directive" => { plan 1; temp %*ENV = 1; is-run q:to/SCRIPT/, say "ok yet"; sub bad { die "and here we die..." } #line 10 "test.raku" # Intentionally skip a line of code bad(); SCRIPT "die after a line directive", :exitcode(1), :out("ok yet\n"), :err("and here we die...\n in sub bad at -e line 2\n in block at \"test.raku\" line 11\n\n"); } # vim: expandtab shiftwidth=4