@@ -66,7 +66,24 @@ function renderFixture(
6666 rangeType : RangeType ,
6767 renderWhitespace : boolean ,
6868) {
69+ const highlights = getHighlights ( fixture , rangeType ) ;
70+ return (
71+ < div key = { fixture . name } >
72+ { fixture . facet }
73+ < Code
74+ languageId = { fixture . languageId }
75+ renderWhitespace = { renderWhitespace }
76+ highlights = { highlights }
77+ >
78+ { fixture . code }
79+ </ Code >
80+ </ div >
81+ ) ;
82+ }
83+
84+ function getHighlights ( fixture : Fixture , rangeType : RangeType ) : Highlight [ ] {
6985 const highlights : Highlight [ ] = [ ] ;
86+ const domainRanges : Range [ ] = [ ] ;
7087 let previousRange : Range | undefined ;
7188
7289 for ( const scope of fixture . scopes ) {
@@ -76,27 +93,23 @@ function renderFixture(
7693 : scope . targets . map ( ( t ) => t . removal ?? t . content ) ;
7794 const ranges = conciseRanges . map ( ( r ) => Range . fromConcise ( r ) ) ;
7895
79- if ( scope . domain != null && conciseRanges . some ( ( r ) => r !== scope . domain ) ) {
80- highlights . push ( {
81- type : "domain" ,
82- range : Range . fromConcise ( scope . domain ) ,
83- } ) ;
96+ if ( scope . domain != null && ! conciseRanges . includes ( scope . domain ) ) {
97+ domainRanges . push ( Range . fromConcise ( scope . domain ) ) ;
8498 }
8599
86100 for ( const r of ranges ) {
87101 let range = r ;
88102
89- if ( previousRange != null ) {
90- const intersection = previousRange . intersection ( range ) ;
103+ const overlap = highlights
104+ . map ( ( h ) => getOverlap ( h . range , range ) )
105+ . find ( ( o ) => o != null ) ;
91106
92- if ( intersection != null && ! intersection . isEmpty ) {
93- highlights . push ( {
94- type : rangeType ,
95- range : intersection ,
96- } ) ;
97-
98- range = new Range ( intersection . end , range . end ) ;
99- }
107+ if ( overlap != null ) {
108+ highlights . push ( {
109+ type : rangeType ,
110+ range : overlap ,
111+ } ) ;
112+ range = new Range ( overlap . end , range . end ) ;
100113 }
101114
102115 highlights . push ( {
@@ -108,16 +121,35 @@ function renderFixture(
108121 }
109122 }
110123
111- return (
112- < div key = { fixture . name } >
113- { fixture . facet }
114- < Code
115- languageId = { fixture . languageId }
116- renderWhitespace = { renderWhitespace }
117- highlights = { highlights }
118- >
119- { fixture . code }
120- </ Code >
121- </ div >
122- ) ;
124+ for ( const range of domainRanges ) {
125+ if ( highlights . every ( ( h ) => ! hasOverlap ( h . range , range ) ) ) {
126+ highlights . push ( {
127+ type : "domain" ,
128+ range,
129+ } ) ;
130+ }
131+ }
132+
133+ if (
134+ highlights . some ( ( h ) => highlights . some ( ( o ) => hasOverlap ( h . range , o . range ) ) )
135+ ) {
136+ console . error ( "Overlapping highlights detected:" ) ;
137+ console . error ( fixture . name ) ;
138+ console . error ( highlights ) ;
139+ }
140+
141+ return highlights ;
142+ }
143+
144+ function hasOverlap ( a : Range , b : Range ) : boolean {
145+ return getOverlap ( a , b ) != null ;
146+ }
147+
148+ function getOverlap ( a : Range , b : Range ) : Range | null {
149+ const intersection = a . intersection ( b ) ;
150+ return intersection != null && ! intersection . isEmpty && ! a . contains ( b )
151+ ? ! b . contains ( a )
152+ ? intersection
153+ : null
154+ : null ;
123155}
0 commit comments