From d5f41b04ceccf0dfab95d7a6e9d3cc2c1ea9f696 Mon Sep 17 00:00:00 2001 From: Christopher Jefferson Date: Wed, 1 Jul 2026 12:27:44 +0100 Subject: [PATCH] WriteChunks: write all chunks before checking insertion status Writing a chunk whose body contains a nested @InsertChunk marks the inserted chunk as inserted. Previously the "defined but never inserted" and "inserted but never defined" checks were interleaved with writing, so a chunk that was only inserted from within a later-written chunk could be spuriously reported, depending on iteration order. Split the loop: write every chunk first, then run the checks once all insertions have been resolved. Found while fixing the vole package. AI disclosure: this change was prepared with the assistance of Claude Code (Anthropic), which diagnosed the ordering issue and drafted the fix. Co-authored-by: Claude --- gap/DocumentationTree.gi | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/gap/DocumentationTree.gi b/gap/DocumentationTree.gi index d190dd38..8af53b2f 100644 --- a/gap/DocumentationTree.gi +++ b/gap/DocumentationTree.gi @@ -479,6 +479,29 @@ BindGlobal( "WriteChunks", chunks_stream := AUTODOC_OutputTextFile( path_to_xmlfiles, filename ); chunk_names := RecNames( tree!.chunks ); + # Write out every chunk first. Writing a chunk whose body contains a + # nested @InsertChunk marks the inserted chunk as inserted, so all chunk + # bodies must be written before we can decide which chunks were never + # inserted -- otherwise a chunk used only from within a later-written + # chunk is spuriously flagged, depending on iteration order. + for current_chunk_name in chunk_names do + current_chunk := tree!.chunks.( current_chunk_name ); + AppendTo( chunks_stream, "<#GAPDoc Label=\"", current_chunk_name, "\">\n" ); + if IsBound( current_chunk!.content ) then + AUTODOC_WriteDocumentationListWithSource( + current_chunk!.content, + current_chunk!.content_source_positions, + chunks_stream + ); + fi; + AppendTo( chunks_stream, "\n<#/GAPDoc>\n" ); + od; + + CloseStream( chunks_stream ); + + # Now that every insertion (including those nested inside other chunks) + # has been resolved, warn about chunks that are defined but never inserted, + # or inserted but never defined. for current_chunk_name in chunk_names do current_chunk := tree!.chunks.( current_chunk_name ); if current_chunk!.is_defined = true and current_chunk!.is_inserted = false then @@ -498,19 +521,8 @@ BindGlobal( "WriteChunks", " was inserted but never defined" ); fi; - AppendTo( chunks_stream, "<#GAPDoc Label=\"", current_chunk_name, "\">\n" ); - if IsBound( current_chunk!.content ) then - AUTODOC_WriteDocumentationListWithSource( - current_chunk!.content, - current_chunk!.content_source_positions, - chunks_stream - ); - fi; - AppendTo( chunks_stream, "\n<#/GAPDoc>\n" ); od; - CloseStream( chunks_stream ); - end ); ##