inlining for overloaded object isa/coerce
[gitmo/Moo.git] / lib / Method / Inliner.pm
CommitLineData
f537c364 1package Method::Inliner;
2
3use strictures 1;
4use Text::Balanced qw(extract_bracketed);
5use Sub::Quote ();
6
7sub slurp { do { local (@ARGV, $/) = $_[0]; <> } }
8sub splat {
9 open my $out, '>', $_[1] or die "can't open $_[1]: $!";
10 print $out $_[0] or die "couldn't write to $_[1]: $!";
11}
12
13sub inlinify {
14 my $file = $_[0];
15 my @chunks = split /(^sub.*?^}$)/sm, slurp $file;
16 warn join "\n--\n", @chunks;
17 my %code;
18 foreach my $chunk (@chunks) {
19 if (my ($name, $body) =
20 $chunk =~ /^sub (\S+) {\n(.*)\n}$/s
21 ) {
22 $code{$name} = $body;
23 }
24 }
25 foreach my $chunk (@chunks) {
26 my ($me) = $chunk =~ /^sub.*{\n my \((\$\w+).*\) = \@_;\n/ or next;
27 my $meq = quotemeta $me;
28 #warn $meq, $chunk;
29 my $copy = $chunk;
30 my ($fixed, $rest);
31 while ($copy =~ s/^(.*?)${meq}->(\S+)(?=\()//s) {
32 my ($front, $name) = ($1, $2);
33 ((my $body), $rest) = extract_bracketed($copy, '()');
34 warn "spotted ${name} - ${body}";
35 if ($code{$name}) {
36 warn "replacing";
37 s/^\(//, s/\)$// for $body;
38 $body = "${me}, ".$body;
39 $fixed .= $front.Sub::Quote::inlinify($code{$name}, $body);
40 } else {
41 $fixed .= $front.$me.'->'.$name.$body;
42 }
43 #warn $fixed; warn $rest;
44 $copy = $rest;
45 }
46 $fixed .= $rest if $fixed;
47 warn $fixed if $fixed;
48 $chunk = $fixed if $fixed;
49 }
50 print join '', @chunks;
51}
52
531;