diff options
author | David Mitchell <davem@iabyn.com> | 2016-07-22 10:08:50 +0100 |
---|---|---|
committer | David Mitchell <davem@iabyn.com> | 2016-08-03 20:54:41 +0100 |
commit | 9fe5784b4a7b013263f10dbe4fa029d61b9a1b60 (patch) | |
tree | d54f34356215d6ab98d95e0ad9e489cee7ba2572 /lib | |
parent | e276dec7f3a8b7912cc237d41056ee43ff1c634d (diff) | |
download | perl-9fe5784b4a7b013263f10dbe4fa029d61b9a1b60.tar.gz |
handle deparsing of sub prototypes with sigs
when 'use feature "signatures"' is in scope, subroutine prototypes
should be deparsed as ':prototype($$)' rather than '($$)'
I've also tweaked the sub in question slightly to make adding
signature deparsing easier later on.
Diffstat (limited to 'lib')
-rw-r--r-- | lib/B/Deparse.pm | 33 |
1 files changed, 23 insertions, 10 deletions
diff --git a/lib/B/Deparse.pm b/lib/B/Deparse.pm index d314c7418d..16b813a4bd 100644 --- a/lib/B/Deparse.pm +++ b/lib/B/Deparse.pm @@ -1195,19 +1195,28 @@ sub pad_subs { sub deparse_sub { my $self = shift; my $cv = shift; - my $proto = ""; + my @attrs; + my $protosig; # prototype or signature (what goes in the (....)) + Carp::confess("NULL in deparse_sub") if !defined($cv) || $cv->isa("B::NULL"); Carp::confess("SPECIAL in deparse_sub") if $cv->isa("B::SPECIAL"); local $self->{'curcop'} = $self->{'curcop'}; + + my $has_sig = $self->{hinthash}{feature_signatures}; if ($cv->FLAGS & SVf_POK) { - $proto = "(". $cv->PV . ") "; + my $proto = $cv->PV; + if ($has_sig) { + push @attrs, "prototype($proto)"; + } + else { + $protosig = $proto; + } } if ($cv->CvFLAGS & (CVf_METHOD|CVf_LOCKED|CVf_LVALUE|CVf_ANONCONST)) { - $proto .= ": "; - $proto .= "lvalue " if $cv->CvFLAGS & CVf_LVALUE; - $proto .= "locked " if $cv->CvFLAGS & CVf_LOCKED; - $proto .= "method " if $cv->CvFLAGS & CVf_METHOD; - $proto .= "const " if $cv->CvFLAGS & CVf_ANONCONST; + push @attrs, "lvalue" if $cv->CvFLAGS & CVf_LVALUE; + push @attrs, "locked" if $cv->CvFLAGS & CVf_LOCKED; + push @attrs, "method" if $cv->CvFLAGS & CVf_METHOD; + push @attrs, "const" if $cv->CvFLAGS & CVf_ANONCONST; } local($self->{'curcv'}) = $cv; @@ -1241,17 +1250,21 @@ Carp::confess("SPECIAL in deparse_sub") if $cv->isa("B::SPECIAL"); else { $body = $self->deparse($root->first, 0); } + $body = "{\n\t$body\n\b}"; } else { my $sv = $cv->const_sv; if ($$sv) { # uh-oh. inlinable sub... format it differently - return $proto . "{ " . $self->const($sv, 0) . " }\n"; + $body = "{ " . $self->const($sv, 0) . " }\n"; } else { # XSUB? (or just a declaration) - return "$proto;\n"; + $body = ';' } } - return $proto ."{\n\t$body\n\b}" ."\n"; + $protosig = defined $protosig ? "($protosig) " : ""; + my $attrs = ''; + $attrs = ': ' . join('', map "$_ ", @attrs) if @attrs; + return "$protosig$attrs$body\n"; } sub deparse_format { |