Skip to content

Commit 877d74b

Browse files
committed
Rewrite find-definition correctly
1 parent f6fdcdd commit 877d74b

File tree

2 files changed

+78
-68
lines changed

2 files changed

+78
-68
lines changed

htmlify.p6

Lines changed: 78 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -258,68 +258,96 @@ multi write-type-source($doc) {
258258
spurt "html/$what/$podname.html", p2h($pod, $what);
259259
}
260260

261-
sub find-definitions (:$pod, :$origin, :$dr) {
262-
my @chunks = chunks-grep($pod.content,
263-
:from({
264-
$_ ~~ Pod::Heading and
265-
.content[0].content[0] ~~ { $_ ~~ Str and .words.elems == 2 }
266-
}),
267-
:to({ $^b ~~ Pod::Heading and $^b.level <= $^a.level}),
268-
);
269-
for @chunks -> $chunk {
270-
my ($what, $name) = $chunk[0].content[0].content[0].words;
271-
my $created;
272-
my &add-new = { $created = $dr.add-new(
273-
:$name,
274-
:subkinds($what),
275-
:pod($chunk),
276-
:$origin,
261+
sub find-definitions (:$pod, :$*origin, :$dr) {
262+
my $*old-level = Inf;
263+
my $*created;
264+
265+
my sub add-new (*%_) {
266+
$*created = $dr.add-new(
267+
:$*name,
268+
:subkinds($*what),
269+
:$*origin,
270+
:pod[],
277271
:!pod-is-complete,
278272
|%_
279-
)}
280-
given $what {
281-
when / ^ [in | pre | post | circum | postcircum ] fix | listop / {
282-
add-new :kind<routine>
283-
:categories<operator>
284-
}
285-
when 'sub'|'method'|'term' {
286-
add-new :kind<routine>
287-
:categories($what)
288-
}
289-
when 'routine' {
290-
my Str @subkinds = first-code-block($chunk)\
291-
.match(:g,
292-
/:s ^ 'multi'? (sub|method)»/
293-
)>>[0]>>.Str.Set.list;
294-
if !@subkinds {
295-
note "The subkinds of routine $name in $origin.name() cannot be determined."
273+
);
274+
}
275+
276+
# Run through the pod content, and look for headings.
277+
# If a heading is a definition, like "class FooBar", process
278+
# the class and slurp up the pod until the next heading at
279+
# the same or lower level.
280+
for $pod ~~ Positional ?? @$pod !! $pod.content -> $c {
281+
if $c ~~ Pod::Heading and $c.level <= $*old-level {
282+
# Finalize our new definition
283+
chunk-finished if $*created;
284+
285+
# Is this new header a definition?
286+
# If so, begin processing it.
287+
# If not, skip to the next heading.
288+
next unless $c.content[0].content[0] ~~ Str
289+
and 2 == my @words = $c.content[0].content[0].words;
290+
my ($*what, $*name) = @words;
291+
given $*what {
292+
when / ^ [in | pre | post | circum | postcircum ] fix | listop / {
293+
add-new :kind<routine>
294+
:categories<operator>
295+
}
296+
when 'sub'|'method'|'term'|'routine' {
297+
add-new :kind<routine>
298+
:categories($*what)
299+
}
300+
when 'class'|'role' {
301+
add-new :kind<type>;
302+
}
303+
default {
304+
next
296305
}
297-
add-new :kind<routine>
298-
:@subkinds
299-
:categories(@subkinds)
300-
}
301-
when / class | role / {
302-
add-new :kind<type>;
303-
find-definitions :pod(pod-block($chunk[1..*])), :origin($created), :$dr;
304-
}
305-
default {
306-
next
307306
}
307+
# We made it this far, so it's a valid definition
308+
say " Found definition of $*what $*name in $*origin.name().";
309+
$*old-level = $c.level;
310+
311+
$c.content[0] = pod-link "$*what $*name",
312+
$*created.url ~ "#$*origin.human-kind() $*origin.name()".subst(:g, /\s+/, '_');
313+
314+
$*created.pod.push: $c;
315+
} elsif $*created {
316+
# Slurp up pod content within the same level as our definition
317+
$*created.pod.push: $c;
308318
}
319+
}
320+
# Finalize our new definition if we haven't already
321+
chunk-finished if $*created;
309322

310-
say " Found definition of $what $name in $origin.name().";
323+
my sub chunk-finished () {
324+
my $chunk = $*created.pod;
311325

312-
if $created.subkinds 'method' {
313-
%methods-by-type{$origin.name}.push: $chunk;
326+
if $*created.subkinds eq 'routine' {
327+
# Determine proper subkinds
328+
my Str @subkinds = first-code-block($chunk)\
329+
.match(:g, /:s ^ 'multi'? (sub|method)»/)\
330+
.>>[0]>>.Str.Set.list;
331+
332+
note "The subkinds of routine $*created.name() in $*origin.name() cannot be determined."
333+
unless @subkinds;
334+
335+
$*created.subkinds = @subkinds;
336+
$*created.categories = @subkinds;
337+
}
338+
if $*created.subkinds 'method' {
339+
%methods-by-type{$*origin.name}.push: $chunk;
314340
write-qualified-method-call(
315-
:$name,
341+
:name($*created.name),
316342
:pod($chunk),
317-
:type($origin.name),
343+
:type($*origin.name),
318344
);
319345
}
320346

321-
$chunk[0].content[0] = pod-link "$what $name",
322-
$created.url ~ "#$origin.human-kind() $origin.name()".subst(:g, /\s+/, '_');
347+
find-definitions :pod($chunk[1..*]), :origin($*created), :$dr;
348+
349+
$*old-level = Inf;
350+
undefine $*created;
323351
}
324352
}
325353

lib/Pod/Convenience.pm6

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -37,24 +37,6 @@ sub first-code-block(@pod) is export {
3737
'';
3838
}
3939

40-
sub chunks-grep(:$from!, :&to!, *@elems) is export {
41-
my @current;
42-
43-
gather {
44-
for @elems -> $c {
45-
if @current && to(@current[0], $c) {
46-
take [@current];
47-
@current = ();
48-
@current.push: $c if $c ~~ $from;
49-
}
50-
elsif @current or $c ~~ $from {
51-
@current.push: $c;
52-
}
53-
}
54-
take [@current] if @current;
55-
}
56-
}
57-
5840
sub pod-with-title($title, *@blocks) is export {
5941
Pod::Block::Named.new(
6042
name => "pod",

0 commit comments

Comments
 (0)