99} from "../codec.ts" ;
1010import type { GeneratedRange , OriginalScope , ScopeInfo } from "../scopes.d.ts" ;
1111import { encodeSigned , encodeUnsigned } from "../vlq.ts" ;
12+ import { comparePositions } from "../util.ts" ;
1213
1314const DEFAULT_SCOPE_STATE = {
1415 line : 0 ,
@@ -147,6 +148,7 @@ export class Encoder {
147148 #encodeGeneratedRange( range : GeneratedRange ) : void {
148149 this . #encodeGeneratedRangeStart( range ) ;
149150 this . #encodeGeneratedRangeBindings( range ) ;
151+ this . #encodeGeneratedRangeSubRangeBindings( range ) ;
150152 this . #encodeGeneratedRangeCallSite( range ) ;
151153 range . children . forEach ( ( child ) => this . #encodeGeneratedRange( child ) ) ;
152154 this . #encodeGeneratedRangeEnd( range ) ;
@@ -190,6 +192,49 @@ export class Encoder {
190192 this . #finishItem( ) ;
191193 }
192194
195+ #encodeGeneratedRangeSubRangeBindings( range : GeneratedRange ) {
196+ if ( range . values . length === 0 ) return ;
197+
198+ for ( let i = 0 ; i < range . values . length ; ++ i ) {
199+ const value = range . values [ i ] ;
200+ if ( ! Array . isArray ( value ) || value . length <= 1 ) {
201+ continue ;
202+ }
203+
204+ this . #encodeTag( EncodedTag . GENERATED_RANGE_SUBRANGE_BINDING )
205+ . #encodeUnsigned( i ) ;
206+
207+ let lastLine = range . start . line ;
208+ let lastColumn = range . start . column ;
209+ for ( let j = 1 ; j < value . length ; ++ j ) {
210+ const subRange = value [ j ] ;
211+ const prevSubRange = value [ j - 1 ] ;
212+
213+ if ( comparePositions ( prevSubRange . to , subRange . from ) !== 0 ) {
214+ throw new Error ( "Sub-range bindings must not have gaps" ) ;
215+ }
216+
217+ const encodedLine = subRange . from . line - lastLine ;
218+ const encodedColumn = encodedLine === 0
219+ ? subRange . from . column - lastColumn
220+ : subRange . from . column ;
221+ if ( encodedLine < 0 || encodedColumn < 0 ) {
222+ throw new Error ( "Sub-range bindings must be sorted" ) ;
223+ }
224+
225+ lastLine = subRange . from . line ;
226+ lastColumn = subRange . from . column ;
227+
228+ const binding = subRange . value === undefined
229+ ? 0
230+ : this . #resolveNamesIdx( subRange . value ) + 1 ;
231+ this . #encodeUnsigned( binding ) . #encodeUnsigned( encodedLine )
232+ . #encodeUnsigned( encodedColumn ) ;
233+ }
234+ this . #finishItem( ) ;
235+ }
236+ }
237+
193238 #encodeGeneratedRangeBindings( range : GeneratedRange ) {
194239 if ( range . values . length === 0 ) return ;
195240
@@ -203,12 +248,16 @@ export class Encoder {
203248
204249 this . #encodeTag( EncodedTag . GENERATED_RANGE_BINDINGS ) ;
205250 for ( const val of range . values ) {
206- if ( val === null || val == undefined ) {
251+ if ( val === null || val === undefined ) {
207252 this . #encodeUnsigned( 0 ) ;
208253 } else if ( typeof val === "string" ) {
209254 this . #encodeUnsigned( this . #resolveNamesIdx( val ) + 1 ) ;
210255 } else {
211- throw new Error ( "Sub-range bindings not implemented yet!" ) ;
256+ const initialValue = val [ 0 ] ;
257+ const binding = initialValue . value === undefined
258+ ? 0
259+ : this . #resolveNamesIdx( initialValue . value ) + 1 ;
260+ this . #encodeUnsigned( binding ) ;
212261 }
213262 }
214263 this . #finishItem( ) ;
0 commit comments