From c55455d73dc40912023056d817a0e0a97fab1197 Mon Sep 17 00:00:00 2001 From: Elizabeth Mattijsen Date: Tue, 2 May 2023 13:29:11 +0200 Subject: [PATCH] RakuAST: fix rules for determing implied code blocks Previously, it was assumed that the indentation level of the =begin pod would be taken as a base to determine an implied code block. But it turns out it is indentation level of the last seen doc block. =begin pod =head1 Foo This is *not* an implied code block =end pod This moves the indentation of abbreviated doc blocks into its contents so that there is no difference between: =head1 Foo and =begin head1 Foo with regards to contents. This also eliminates the :spaces argument to the RakuAST::Doc::Block.from-paragraphs method, as this is no longer needed. --- src/Raku/Actions.nqp | 10 ++++----- src/core.c/RakuAST/Fixups.pm6 | 39 ++++++++++++++++++++++++++--------- 2 files changed, 34 insertions(+), 15 deletions(-) diff --git a/src/Raku/Actions.nqp b/src/Raku/Actions.nqp index cac1da86c0a..335f40e6c4e 100644 --- a/src/Raku/Actions.nqp +++ b/src/Raku/Actions.nqp @@ -2770,7 +2770,7 @@ class Raku::Actions is HLL::Actions does Raku::CommonActions { } $SEEN{$/.from} := RakuAST::Doc::Block.from-paragraphs: - :spaces(~$), :$type, :$level, :$config, :@paragraphs; + :$type, :$level, :$config, :@paragraphs; } method doc-block:sym($/) { @@ -2787,7 +2787,7 @@ class Raku::Actions is HLL::Actions does Raku::CommonActions { nqp::push(@paragraphs,~$lines); } $*SEEN{$/.from} := RakuAST::Doc::Block.from-paragraphs: - :spaces(~$), :$type, :$level, :$config, :@paragraphs; + :$type, :$level, :$config, :@paragraphs; } method doc-block:sym($/) { @@ -2800,12 +2800,12 @@ class Raku::Actions is HLL::Actions does Raku::CommonActions { my $level := extract-level($/); my @paragraphs := nqp::list( - ($
?? ~$
!! "") ~ ($ ?? ~$ !! "") + ($
?? $ ~ $
!! "") + ~ ($ ?? ~$ !! "") ); $*SEEN{$/.from} := RakuAST::Doc::Block.from-paragraphs: - :spaces(~$), :$type, :$level, :$config, :abbreviated, - :@paragraphs; + :$type, :$level, :$config, :abbreviated, :@paragraphs; } } diff --git a/src/core.c/RakuAST/Fixups.pm6 b/src/core.c/RakuAST/Fixups.pm6 index 151ef5f880a..0f2db081beb 100644 --- a/src/core.c/RakuAST/Fixups.pm6 +++ b/src/core.c/RakuAST/Fixups.pm6 @@ -91,6 +91,13 @@ augment class RakuAST::Doc::Markup { augment class RakuAST::Doc::Paragraph { + # conceptual leading whitespace of first element + method leading-whitespace() { + nqp::istype((my $first := self.atoms.head),Str) + ?? $first.leading-whitespace + !! "" + } + # easy integer checks my int32 $A = nqp::ord('A'); my int32 $Z = nqp::ord('Z'); @@ -198,10 +205,14 @@ augment class RakuAST::Doc::Paragraph { augment class RakuAST::Doc::Block { + # conceptual leading whitespace of first element + method leading-whitespace() { + self.paragraphs.head.leading-whitespace; + } + # create block with type/paragraph introspection - method from-paragraphs(:$spaces, :$type, :@paragraphs, *%_) { + method from-paragraphs(:$type, :@paragraphs, *%_) { my $block := self.new(:$type, |%_); - my $offset := $spaces.chars; # these need verbatim stuff if $type eq 'comment' { @@ -210,12 +221,21 @@ augment class RakuAST::Doc::Block { # these need to be handled as code elsif $type eq 'code' | 'input' | 'output' { + my int $offset = @paragraphs.head.leading-whitespace.chars; $block.add-paragraph(@paragraphs.map(*.substr($offset)).join) } # potentially need introspection elsif $type eq 'pod' | 'doc' { + my str $last-leading-ws; + my int $offset; + my sub set-leading-ws($leading-ws) { + $last-leading-ws = $leading-ws // ""; + $offset = nqp::chars($last-leading-ws); + } + + set-leading-ws(@paragraphs.head.leading-whitespace); for @paragraphs -> $paragraph { # need further introspection @@ -245,15 +265,12 @@ augment class RakuAST::Doc::Block { @codes = (); } - my str $last-leading-ws = - $paragraph.leading-whitespace.substr($offset); for $paragraph.lines(:!chomp) { if .is-whitespace { if @codes { - my int $ws-offset = $last-leading-ws.chars; @codes.push(( - .chars >= $ws-offset ?? .substr($ws-offset) !! "" + .chars >= $offset ?? .substr($offset) !! "" ).chomp); } else { @@ -263,7 +280,7 @@ augment class RakuAST::Doc::Block { # not just whitespace else { - my $line := (.starts-with($spaces) + my $line := (.starts-with($last-leading-ws) ?? .substr($offset) !! .trim-leading ).chomp; @@ -273,10 +290,11 @@ augment class RakuAST::Doc::Block { if $leading-ws ne $last-leading-ws { add-codes if @codes; $last-leading-ws = $leading-ws; - @codes = $line.substr($leading-ws.chars); + $offset = nqp::chars($leading-ws); + @codes = $line.substr($offset); } else { - @codes.push: $line.substr($leading-ws.chars); + @codes.push: $line.substr($offset); } } else { @@ -291,6 +309,7 @@ augment class RakuAST::Doc::Block { # already introspected else { + set-leading-ws($paragraph.leading-whitespace); $block.add-paragraph($paragraph); } } @@ -300,7 +319,7 @@ augment class RakuAST::Doc::Block { else { $block.add-paragraph( nqp::istype($_,Str) - ?? RakuAST::Doc::Paragraph.from-string(.substr($offset)) + ?? RakuAST::Doc::Paragraph.from-string($_) !! $_ ) for @paragraphs; }