Upgrade to Attribute::Handlers 0.81
[p5sagit/p5-mst-13.2.git] / ext / B / t / deparse.t
CommitLineData
87a42246 1#!./perl
2
3BEGIN {
5638aaac 4 if ($ENV{PERL_CORE}){
5 chdir('t') if -d 't';
6 if ($^O eq 'MacOS') {
7 @INC = qw(: ::lib ::macos:lib);
8 } else {
9 @INC = '.';
10 push @INC, '../lib';
11 }
87a42246 12 } else {
5638aaac 13 unshift @INC, 't';
87a42246 14 }
9cd8f857 15 require Config;
16 if (($Config::Config{'extensions'} !~ /\bB\b/) ){
17 print "1..0 # Skip -- Perl configured without B module\n";
18 exit 0;
19 }
87a42246 20}
21
87a42246 22use warnings;
23use strict;
e9c69003 24BEGIN {
25 # BEGIN block is acutally a subroutine :-)
26 return unless $] > 5.009;
27 require feature;
28 feature->import(':5.10');
29}
2990415a 30use Test::More tests => 74;
87a42246 31
32use B::Deparse;
09d856fb 33my $deparse = B::Deparse->new();
34ok($deparse);
87a42246 35
36# Tell B::Deparse about our ambient pragmas
0ced6c29 37{ my ($hint_bits, $warning_bits, $hinthash);
38 BEGIN { ($hint_bits, $warning_bits, $hinthash) = ($^H, ${^WARNING_BITS}, \%^H); }
87a42246 39 $deparse->ambient_pragmas (
40 hint_bits => $hint_bits,
41 warning_bits => $warning_bits,
0ced6c29 42 '$[' => 0 + $[,
43 '%^H' => $hinthash,
87a42246 44 );
45}
46
ad46c0be 47$/ = "\n####\n";
48while (<DATA>) {
49 chomp;
e9c69003 50 # This code is pinched from the t/lib/common.pl for TODO.
51 # It's not clear how to avoid duplication
52 my ($skip, $skip_reason);
53 s/^#\s*SKIP\s*(.*)\n//m and $skip_reason = $1;
54 # If the SKIP reason starts ? then it's taken as a code snippet to evaluate
55 # This provides the flexibility to have conditional SKIPs
56 if ($skip_reason && $skip_reason =~ s/^\?//) {
57 my $temp = eval $skip_reason;
58 if ($@) {
59 die "# In SKIP code reason:\n# $skip_reason\n$@";
60 }
61 $skip_reason = $temp;
62 }
63
ec59cdf2 64 s/#\s*(.*)$//mg;
65 my ($num, $testname) = $1 =~ m/(\d+)\s*(.*)/;
e9c69003 66
67 if ($skip_reason) {
68 # Like this to avoid needing a label SKIP:
69 Test::More->builder->skip($skip_reason);
70 next;
71 }
72
ad46c0be 73 my ($input, $expected);
74 if (/(.*)\n>>>>\n(.*)/s) {
75 ($input, $expected) = ($1, $2);
76 }
77 else {
78 ($input, $expected) = ($_, $_);
79 }
87a42246 80
ad46c0be 81 my $coderef = eval "sub {$input}";
87a42246 82
ad46c0be 83 if ($@) {
ec59cdf2 84 diag("$num deparsed: $@");
85 ok(0, $testname);
ad46c0be 86 }
87 else {
88 my $deparsed = $deparse->coderef2text( $coderef );
31c6271a 89 my $regex = $expected;
90 $regex =~ s/(\S+)/\Q$1/g;
91 $regex =~ s/\s+/\\s+/g;
92 $regex = '^\{\s*' . $regex . '\s*\}$';
ec59cdf2 93 like($deparsed, qr/$regex/, $testname);
87a42246 94 }
87a42246 95}
96
87a42246 97use constant 'c', 'stuff';
09d856fb 98is((eval "sub ".$deparse->coderef2text(\&c))->(), 'stuff');
87a42246 99
09d856fb 100my $a = 0;
101is("{\n (-1) ** \$a;\n}", $deparse->coderef2text(sub{(-1) ** $a }));
87a42246 102
d989cdac 103use constant cr => ['hello'];
104my $string = "sub " . $deparse->coderef2text(\&cr);
0707d6cc 105my $val = (eval $string)->() or diag $string;
106is(ref($val), 'ARRAY');
107is($val->[0], 'hello');
87a42246 108
87a42246 109my $Is_VMS = $^O eq 'VMS';
110my $Is_MacOS = $^O eq 'MacOS';
111
112my $path = join " ", map { qq["-I$_"] } @INC;
be708cc0 113$path .= " -MMac::err=unix" if $Is_MacOS;
87a42246 114my $redir = $Is_MacOS ? "" : "2>&1";
115
d2bc402e 116$a = `$^X $path "-MO=Deparse" -anlwi.bak -e 1 $redir`;
e69a2255 117$a =~ s/-e syntax OK\n//g;
d2bc402e 118$a =~ s/.*possible typo.*\n//; # Remove warning line
87a42246 119$a =~ s{\\340\\242}{\\s} if (ord("\\") == 224); # EBCDIC, cp 1047 or 037
120$a =~ s{\\274\\242}{\\s} if (ord("\\") == 188); # $^O eq 'posix-bc'
121$b = <<'EOF';
d2bc402e 122BEGIN { $^I = ".bak"; }
123BEGIN { $^W = 1; }
124BEGIN { $/ = "\n"; $\ = "\n"; }
87a42246 125LINE: while (defined($_ = <ARGV>)) {
126 chomp $_;
f86ea535 127 our(@F) = split(' ', $_, 0);
87a42246 128 '???';
129}
87a42246 130EOF
e69a2255 131$b =~ s/(LINE:)/sub BEGIN {
132 'MacPerl'->bootstrap;
133 'OSA'->bootstrap;
134 'XL'->bootstrap;
135}
136$1/ if $Is_MacOS;
09d856fb 137is($a, $b);
87a42246 138
579a54dc 139#Re: perlbug #35857, patch #24505
b3980c39 140#handle warnings::register-ed packages properly.
141package B::Deparse::Wrapper;
142use strict;
143use warnings;
144use warnings::register;
145sub getcode {
579a54dc 146 my $deparser = B::Deparse->new();
b3980c39 147 return $deparser->coderef2text(shift);
148}
149
2990415a 150package Moo;
151use overload '0+' => sub { 42 };
152
b3980c39 153package main;
154use strict;
155use warnings;
71c4dbc3 156use constant GLIPP => 'glipp';
2990415a 157use constant PI => 4;
158use constant OVERLOADED_NUMIFICATION => bless({}, 'Moo');
159use Fcntl qw/O_NONBLOCK O_SYNC O_EXCL/;
160BEGIN { delete $::Fcntl::{O_SYNC}; }
161use POSIX qw/O_CREAT/;
b3980c39 162sub test {
579a54dc 163 my $val = shift;
164 my $res = B::Deparse::Wrapper::getcode($val);
09d856fb 165 like( $res, qr/use warnings/);
b3980c39 166}
167my ($q,$p);
168my $x=sub { ++$q,++$p };
169test($x);
170eval <<EOFCODE and test($x);
171 package bar;
172 use strict;
173 use warnings;
174 use warnings::register;
175 package main;
176 1
177EOFCODE
178
ad46c0be 179__DATA__
14a55f98 180# 2
ad46c0be 1811;
182####
14a55f98 183# 3
ad46c0be 184{
185 no warnings;
186 '???';
187 2;
188}
189####
14a55f98 190# 4
ad46c0be 191my $test;
192++$test and $test /= 2;
193>>>>
194my $test;
195$test /= 2 if ++$test;
196####
14a55f98 197# 5
ad46c0be 198-((1, 2) x 2);
199####
14a55f98 200# 6
ad46c0be 201{
202 my $test = sub : lvalue {
203 my $x;
204 }
205 ;
206}
207####
14a55f98 208# 7
ad46c0be 209{
210 my $test = sub : method {
211 my $x;
212 }
213 ;
214}
215####
14a55f98 216# 8
ad46c0be 217{
218 my $test = sub : locked method {
219 my $x;
220 }
221 ;
222}
223####
14a55f98 224# 9
87a42246 225{
ad46c0be 226 234;
f99a63a2 227}
ad46c0be 228continue {
229 123;
87a42246 230}
ce4e655d 231####
14a55f98 232# 10
ce4e655d 233my $x;
234print $main::x;
235####
14a55f98 236# 11
ce4e655d 237my @x;
238print $main::x[1];
14a55f98 239####
240# 12
241my %x;
242$x{warn()};
ad8caead 243####
244# 13
245my $foo;
246$_ .= <ARGV> . <$foo>;
cef22867 247####
248# 14
249my $foo = "Ab\x{100}\200\x{200}\377Cd\000Ef\x{1000}\cA\x{2000}\cZ";
4ae52e81 250####
251# 15
252s/x/'y';/e;
241416b8 253####
254# 16 - various lypes of loop
255{ my $x; }
256####
257# 17
258while (1) { my $k; }
259####
260# 18
261my ($x,@a);
262$x=1 for @a;
263>>>>
264my($x, @a);
0bb5f065 265$x = 1 foreach (@a);
241416b8 266####
267# 19
268for (my $i = 0; $i < 2;) {
269 my $z = 1;
270}
271####
272# 20
273for (my $i = 0; $i < 2; ++$i) {
274 my $z = 1;
275}
276####
277# 21
278for (my $i = 0; $i < 2; ++$i) {
279 my $z = 1;
280}
281####
282# 22
283my $i;
284while ($i) { my $z = 1; } continue { $i = 99; }
285####
286# 23
09d856fb 287foreach my $i (1, 2) {
241416b8 288 my $z = 1;
289}
290####
291# 24
292my $i;
293foreach $i (1, 2) {
294 my $z = 1;
295}
296####
297# 25
298my $i;
299foreach my $i (1, 2) {
300 my $z = 1;
301}
302####
303# 26
304foreach my $i (1, 2) {
305 my $z = 1;
306}
307####
308# 27
309foreach our $i (1, 2) {
310 my $z = 1;
311}
312####
313# 28
314my $i;
315foreach our $i (1, 2) {
316 my $z = 1;
317}
3ac6e0f9 318####
319# 29
320my @x;
321print reverse sort(@x);
322####
323# 30
324my @x;
325print((sort {$b cmp $a} @x));
326####
327# 31
328my @x;
329print((reverse sort {$b <=> $a} @x));
36d57d93 330####
331# 32
332our @a;
333print $_ foreach (reverse @a);
aae53c41 334####
579a54dc 335# 33
aae53c41 336our @a;
337print $_ foreach (reverse 1, 2..5);
f86ea535 338####
339# 34 (bug #38684)
340our @ary;
341@ary = split(' ', 'foo', 0);
31c6271a 342####
343# 35 (bug #40055)
344do { () };
345####
346# 36 (ibid.)
347do { my $x = 1; $x };
d9002312 348####
349# 37 <20061012113037.GJ25805@c4.convolution.nl>
350my $f = sub {
351 +{[]};
352} ;
8b2d6640 353####
354# 38 (bug #43010)
355'!@$%'->();
356####
357# 39 (ibid.)
358::();
359####
360# 40 (ibid.)
361'::::'->();
362####
363# 41 (ibid.)
364&::::;
09d856fb 365####
366# 42
367my $bar;
368'Foo'->$bar('orz');
369####
370# 43
371'Foo'->bar('orz');
372####
373# 44
374'Foo'->bar;
0ced6c29 375####
e9c69003 376# SKIP ?$] < 5.010 && "say not implemented on this Perl version"
7ddd1a01 377# 45 say
378say 'foo';
379####
e9c69003 380# SKIP ?$] < 5.010 && "state vars not implemented on this Perl version"
7ddd1a01 381# 46 state vars
0ced6c29 382state $x = 42;
383####
e9c69003 384# SKIP ?$] < 5.010 && "state vars not implemented on this Perl version"
7ddd1a01 385# 47 state var assignment
386{
387 my $y = (state $x = 42);
388}
389####
e9c69003 390# SKIP ?$] < 5.010 && "state vars not implemented on this Perl version"
7ddd1a01 391# 48 state vars in anoymous subroutines
392$a = sub {
393 state $x;
394 return $x++;
395}
396;
644741fd 397####
398# SKIP ?$] < 5.011 && 'each @array not implemented on this Perl version'
399# 49 each @array;
400each @ARGV;
401each @$a;
402####
403# SKIP ?$] < 5.011 && 'each @array not implemented on this Perl version'
404# 50 keys @array; values @array
405keys @$a if keys @ARGV;
406values @ARGV if values @$a;
35925e80 407####
43b09ad7 408# 51 Anonymous arrays and hashes, and references to them
35925e80 409my $a = {};
410my $b = \{};
411my $c = [];
412my $d = \[];
9210de83 413####
414# SKIP ?$] < 5.010 && "smartmatch and given/when not implemented on this Perl version"
43b09ad7 415# 52 implicit smartmatch in given/when
9210de83 416given ('foo') {
417 when ('bar') { continue; }
418 when ($_ ~~ 'quux') { continue; }
419 default { 0; }
420}
7ecdd211 421####
422# 53 conditions in elsifs (regression in change #33710 which fixed bug #37302)
423if ($a) { x(); }
424elsif ($b) { x(); }
425elsif ($a and $b) { x(); }
426elsif ($a or $b) { x(); }
427else { x(); }
03b22f1b 428####
429# 54 interpolation in regexps
430my($y, $t);
431/x${y}z$t/;
227375e1 432####
2990415a 433# SKIP ?$B::Deparse::VERSION <= 0.88 && "TODO new undocumented cpan-bug #33708"
227375e1 434# 55 (cpan-bug #33708)
435%{$_ || {}}
436####
2990415a 437# SKIP ?$B::Deparse::VERSION <= 0.88 && "TODO hash constants not yet fixed"
227375e1 438# 56 (cpan-bug #33708)
439use constant H => { "#" => 1 }; H->{"#"}
440####
2990415a 441# SKIP ?$B::Deparse::VERSION <= 0.88 && "TODO optimized away 0 not yet fixed"
227375e1 442# 57 (cpan-bug #33708)
443foreach my $i (@_) { 0 }
edbe35ea 444####
445# 58 tests with not, not optimized
07f3cdf5 446my $c;
edbe35ea 447x() unless $a;
448x() if not $a and $b;
449x() if $a and not $b;
450x() unless not $a and $b;
451x() unless $a and not $b;
452x() if not $a or $b;
453x() if $a or not $b;
454x() unless not $a or $b;
455x() unless $a or not $b;
07f3cdf5 456x() if $a and not $b and $c;
457x() if not $a and $b and not $c;
458x() unless $a and not $b and $c;
459x() unless not $a and $b and not $c;
460x() if $a or not $b or $c;
461x() if not $a or $b or not $c;
462x() unless $a or not $b or $c;
463x() unless not $a or $b or not $c;
edbe35ea 464####
465# 59 tests with not, optimized
07f3cdf5 466my $c;
edbe35ea 467x() if not $a;
468x() unless not $a;
469x() if not $a and not $b;
470x() unless not $a and not $b;
471x() if not $a or not $b;
472x() unless not $a or not $b;
07f3cdf5 473x() if not $a and not $b and $c;
474x() unless not $a and not $b and $c;
475x() if not $a or not $b or $c;
476x() unless not $a or not $b or $c;
477x() if not $a and not $b and not $c;
478x() unless not $a and not $b and not $c;
479x() if not $a or not $b or not $c;
480x() unless not $a or not $b or not $c;
481x() unless not $a or not $b or not $c;
edbe35ea 482>>>>
07f3cdf5 483my $c;
edbe35ea 484x() unless $a;
485x() if $a;
486x() unless $a or $b;
487x() if $a or $b;
488x() unless $a and $b;
07f3cdf5 489x() if $a and $b;
490x() if not $a || $b and $c;
491x() unless not $a || $b and $c;
492x() if not $a && $b or $c;
493x() unless not $a && $b or $c;
494x() unless $a or $b or $c;
495x() if $a or $b or $c;
496x() unless $a and $b and $c;
497x() if $a and $b and $c;
498x() unless not $a && $b && $c;
71c4dbc3 499####
500# 60 tests that should be constant folded
501x() if 1;
502x() if GLIPP;
503x() if !GLIPP;
504x() if GLIPP && GLIPP;
505x() if !GLIPP || GLIPP;
506x() if do { GLIPP };
507x() if do { no warnings 'void'; 5; GLIPP };
508x() if do { !GLIPP };
509if (GLIPP) { x() } else { z() }
510if (!GLIPP) { x() } else { z() }
511if (GLIPP) { x() } elsif (GLIPP) { z() }
512if (!GLIPP) { x() } elsif (GLIPP) { z() }
513if (GLIPP) { x() } elsif (!GLIPP) { z() }
514if (!GLIPP) { x() } elsif (!GLIPP) { z() }
515if (!GLIPP) { x() } elsif (!GLIPP) { z() } elsif (GLIPP) { t() }
516if (!GLIPP) { x() } elsif (!GLIPP) { z() } elsif (!GLIPP) { t() }
517if (!GLIPP) { x() } elsif (!GLIPP) { z() } elsif (!GLIPP) { t() }
518>>>>
519x();
520x();
521'???';
522x();
523x();
524x();
525x();
526do {
527 '???'
528};
529do {
530 x()
531};
532do {
533 z()
534};
535do {
536 x()
537};
538do {
539 z()
540};
541do {
542 x()
543};
544'???';
545do {
546 t()
547};
548'???';
549!1;
550####
551# 61 tests that shouldn't be constant folded
552x() if $a;
553if ($a == 1) { x() } elsif ($b == 2) { z() }
554if (do { foo(); GLIPP }) { x() }
555if (do { $a++; GLIPP }) { x() }
556>>>>
557x() if $a;
558if ($a == 1) { x(); } elsif ($b == 2) { z(); }
2990415a 559if (do { foo(); GLIPP }) { x(); }
560if (do { ++$a; GLIPP }) { x(); }
561####
562# 62 tests for deparsing constants
563warn PI;
564####
565# 63 tests for deparsing imported constants
566warn O_NONBLOCK;
567####
568# 64 tests for deparsing re-exported constants
569warn O_CREAT;
570####
571# 65 tests for deparsing imported constants that got deleted from the original namespace
572warn O_SYNC;
573####
574# 66 tests for deparsing constants which got turned into full typeglobs
575warn O_EXCL;
576eval '@Fcntl::O_EXCL = qw/affe tiger/;';
577warn O_EXCL;
578####
579# 67 tests for deparsing of blessed constant with overloaded numification
580warn OVERLOADED_NUMIFICATION;