@@ -22,70 +22,69 @@ function getLineFromRange(range: any): number {
2222}
2323
2424function processStartEndMarkers ( annotations : Annotation [ ] ) : Annotation [ ] {
25- const regular : Annotation [ ] = [ ]
26- const starts : { name : string ; query : string ; line : number } [ ] = [ ]
27- const ends : { name : string ; query : string ; line : number } [ ] = [ ]
25+ const stacks = new Map <
26+ string ,
27+ { name : string ; query : string ; line : number ; order : number } [ ]
28+ > ( )
29+ const orderedAnnotations : { order : number ; annotation : Annotation } [ ] = [ ]
2830
29- for ( const a of annotations ) {
31+ for ( const [ order , a ] of annotations . entries ( ) ) {
3032 const q = a . query ?? ""
3133 if ( q . startsWith ( START_MARKER ) ) {
32- starts . push ( {
34+ const start = {
3335 name : a . name ,
3436 query : q . slice ( START_MARKER . length ) ,
3537 line : getLineFromRange ( a . ranges [ 0 ] ) ,
36- } )
38+ order,
39+ }
40+ const stack = stacks . get ( a . name ) ?? [ ]
41+ stack . push ( start )
42+ stacks . set ( a . name , stack )
3743 } else if ( q . startsWith ( END_MARKER ) ) {
38- ends . push ( {
39- name : a . name ,
40- query : q . slice ( END_MARKER . length ) ,
41- line : getLineFromRange ( a . ranges [ 0 ] ) ,
44+ const stack = stacks . get ( a . name )
45+ const start = stack ?. pop ( )
46+ if ( ! start ) {
47+ console . warn (
48+ `Code Hike warning: Unmatched !${ a . name } (end) annotation` ,
49+ )
50+ continue
51+ }
52+
53+ const endLine = getLineFromRange ( a . ranges [ 0 ] ) - 1
54+ if ( endLine < start . line ) {
55+ console . warn (
56+ `Code Hike warning: Empty !${ a . name } start/end annotation range` ,
57+ )
58+ continue
59+ }
60+
61+ orderedAnnotations . push ( {
62+ order : start . order ,
63+ annotation : {
64+ name : start . name ,
65+ query : start . query ,
66+ ranges : [ { fromLineNumber : start . line , toLineNumber : endLine } ] ,
67+ } ,
4268 } )
4369 } else {
44- regular . push ( a )
70+ orderedAnnotations . push ( { order , annotation : a } )
4571 }
4672 }
4773
48- if ( starts . length === 0 && ends . length === 0 ) {
74+ if ( orderedAnnotations . length === annotations . length ) {
4975 return annotations
5076 }
5177
52- const paired : Annotation [ ] = [ ]
53- const usedEnds = new Set < number > ( )
54-
55- for ( const start of starts ) {
56- // find the first unused end with the same name that comes after the start
57- const endIndex = ends . findIndex (
58- ( e , i ) =>
59- ! usedEnds . has ( i ) &&
60- e . name === start . name &&
61- e . line >= start . line ,
62- )
63- if ( endIndex === - 1 ) {
78+ for ( const stack of stacks . values ( ) ) {
79+ for ( const start of stack ) {
6480 console . warn (
6581 `Code Hike warning: Unmatched !${ start . name } (start) annotation` ,
6682 )
67- continue
68- }
69- usedEnds . add ( endIndex )
70- const end = ends [ endIndex ]
71- paired . push ( {
72- name : start . name ,
73- query : start . query ,
74- ranges : [
75- { fromLineNumber : start . line , toLineNumber : end . line - 1 } ,
76- ] ,
77- } )
78- }
79-
80- for ( let i = 0 ; i < ends . length ; i ++ ) {
81- if ( ! usedEnds . has ( i ) ) {
82- console . warn (
83- `Code Hike warning: Unmatched !${ ends [ i ] . name } (end) annotation` ,
84- )
8583 }
8684 }
8785
88- return [ ...regular , ...paired ]
86+ orderedAnnotations . sort ( ( a , b ) => a . order - b . order )
87+ return orderedAnnotations . map ( ( entry ) => entry . annotation )
8988}
9089
9190async function extractCommentAnnotations (
0 commit comments