@@ -21,6 +21,8 @@ import type { SplitListener } from './splitListener';
21
21
import type { EntityCollector } from './entityCollector' ;
22
22
import { EntityContext } from './entityCollector' ;
23
23
24
+ const SEPARATOR : string = ';' ;
25
+
24
26
/**
25
27
* Basic SQL class, every sql needs extends it.
26
28
*/
@@ -65,13 +67,11 @@ export abstract class BasicSQL<
65
67
* @param candidates candidate list
66
68
* @param allTokens all tokens from input
67
69
* @param caretTokenIndex tokenIndex of caretPosition
68
- * @param tokenIndexOffset offset of the tokenIndex in the candidates compared to the tokenIndex in allTokens
69
70
*/
70
71
protected abstract processCandidates (
71
72
candidates : CandidatesCollection ,
72
73
allTokens : Token [ ] ,
73
- caretTokenIndex : number ,
74
- tokenIndexOffset : number
74
+ caretTokenIndex : number
75
75
) : Suggestions < Token > ;
76
76
77
77
/**
@@ -251,6 +251,67 @@ export abstract class BasicSQL<
251
251
return res ;
252
252
}
253
253
254
+ /**
255
+ * Get the smaller range of input
256
+ * @param input string
257
+ * @param caretTokenIndex tokenIndex of caretPosition
258
+ * @returns inputSlice: string, caretTokenIndex: number, allTokens: Token[]
259
+ */
260
+ private splitInputBySeparator (
261
+ input : string ,
262
+ caretTokenIndex : number
263
+ ) : { inputSlice : string ; caretTokenIndex : number ; allTokens : Token [ ] } {
264
+ const allTokens = this . getAllTokens ( input ) ;
265
+
266
+ /**
267
+ * set startToken
268
+ */
269
+ let startToken : Token | null = null ;
270
+ for ( let tokenIndex = caretTokenIndex ; tokenIndex >= 0 ; tokenIndex -- ) {
271
+ const token = allTokens [ tokenIndex ] ;
272
+ if ( token ?. text === SEPARATOR ) {
273
+ startToken = allTokens [ tokenIndex + 1 ] ;
274
+ break ;
275
+ }
276
+ }
277
+ if ( startToken === null ) {
278
+ startToken = allTokens [ 0 ] ;
279
+ }
280
+
281
+ /**
282
+ * set stopToken
283
+ */
284
+ let stopToken : Token | null = null ;
285
+ for ( let tokenIndex = caretTokenIndex ; tokenIndex < allTokens . length ; tokenIndex ++ ) {
286
+ const token = allTokens [ tokenIndex ] ;
287
+ if ( token ?. text === SEPARATOR ) {
288
+ stopToken = token ;
289
+ break ;
290
+ }
291
+ }
292
+ if ( stopToken === null ) {
293
+ stopToken = allTokens [ allTokens . length - 1 ] ;
294
+ }
295
+
296
+ let startIndex = startToken ?. start ?? 0 ;
297
+ let stopIndex = stopToken ?. stop + 1 ?? input . length ;
298
+
299
+ /**
300
+ * Save offset of the tokenIndex in the range of input
301
+ * compared to the tokenIndex in the whole input
302
+ */
303
+ const tokenIndexOffset = startToken ?. tokenIndex ?? 0 ;
304
+ const _caretTokenIndex = caretTokenIndex - tokenIndexOffset ;
305
+
306
+ /**
307
+ * Get the smaller range of _input
308
+ */
309
+ const _input = input . slice ( startIndex , stopIndex ) ;
310
+ const _allTokens = this . getAllTokens ( _input ) ;
311
+
312
+ return { inputSlice : _input , caretTokenIndex : _caretTokenIndex , allTokens : _allTokens } ;
313
+ }
314
+
254
315
/**
255
316
* Get suggestions of syntax and token at caretPosition
256
317
* @param input source string
@@ -262,12 +323,13 @@ export abstract class BasicSQL<
262
323
caretPosition : CaretPosition
263
324
) : Suggestions | null {
264
325
const splitListener = this . splitListener ;
326
+ let inputSlice = input ;
265
327
266
- this . parseWithCache ( input ) ;
328
+ this . parseWithCache ( inputSlice ) ;
267
329
if ( ! this . _parseTree ) return null ;
268
330
269
331
let sqlParserIns = this . _parser ;
270
- const allTokens = this . getAllTokens ( input ) ;
332
+ let allTokens = this . getAllTokens ( inputSlice ) ;
271
333
let caretTokenIndex = findCaretTokenIndex ( caretPosition , allTokens ) ;
272
334
let c3Context : ParserRuleContext = this . _parseTree ;
273
335
let tokenIndexOffset : number = 0 ;
@@ -321,22 +383,37 @@ export abstract class BasicSQL<
321
383
}
322
384
323
385
// A boundary consisting of the index of the input.
324
- const startIndex = startStatement ?. start ?. start ?? 0 ;
325
- const stopIndex = stopStatement ?. stop ?. stop ?? input . length - 1 ;
386
+ let startIndex = startStatement ?. start ?. start ?? 0 ;
387
+ let stopIndex = stopStatement ?. stop ?. stop ?? inputSlice . length - 1 ;
326
388
327
389
/**
328
390
* Save offset of the tokenIndex in the range of input
329
391
* compared to the tokenIndex in the whole input
330
392
*/
331
393
tokenIndexOffset = startStatement ?. start ?. tokenIndex ?? 0 ;
332
394
caretTokenIndex = caretTokenIndex - tokenIndexOffset ;
395
+ inputSlice = inputSlice . slice ( startIndex , stopIndex ) ;
396
+ }
333
397
334
- /**
335
- * Reparse the input fragment,
336
- * and c3 will collect candidates in the newly generated parseTree.
337
- */
338
- const inputSlice = input . slice ( startIndex , stopIndex ) ;
398
+ /**
399
+ * Split the inputSlice by separator to get the smaller range of inputSlice.
400
+ */
401
+ if ( inputSlice . includes ( SEPARATOR ) ) {
402
+ const {
403
+ inputSlice : _input ,
404
+ caretTokenIndex : _caretTokenIndex ,
405
+ allTokens : _allTokens ,
406
+ } = this . splitInputBySeparator ( inputSlice , caretTokenIndex ) ;
407
+
408
+ caretTokenIndex = _caretTokenIndex ;
409
+ inputSlice = _input ;
410
+ allTokens = _allTokens ;
411
+ }
339
412
413
+ /**
414
+ * Reparse the input fragment, and c3 will collect candidates in the newly generated parseTree when input changed.
415
+ */
416
+ if ( inputSlice !== input ) {
340
417
const lexer = this . createLexer ( inputSlice ) ;
341
418
lexer . removeErrorListeners ( ) ;
342
419
const tokenStream = new CommonTokenStream ( lexer ) ;
@@ -356,12 +433,7 @@ export abstract class BasicSQL<
356
433
core . preferredRules = this . preferredRules ;
357
434
358
435
const candidates = core . collectCandidates ( caretTokenIndex , c3Context ) ;
359
- const originalSuggestions = this . processCandidates (
360
- candidates ,
361
- allTokens ,
362
- caretTokenIndex ,
363
- tokenIndexOffset
364
- ) ;
436
+ const originalSuggestions = this . processCandidates ( candidates , allTokens , caretTokenIndex ) ;
365
437
366
438
const syntaxSuggestions : SyntaxSuggestion < WordRange > [ ] = originalSuggestions . syntax . map (
367
439
( syntaxCtx ) => {
0 commit comments