001
002package gudusoft.gsqlparser.pp.utils;
003
004import gudusoft.gsqlparser.ETokenStatus;
005import gudusoft.gsqlparser.ETokenType;
006import gudusoft.gsqlparser.TSourceToken;
007import gudusoft.gsqlparser.TSourceTokenList;
008
009public class SourceTokenSearcher
010{
011
012        /**
013         * search the source token in the source token list from the top
014         * 
015         * @param list
016         * @param startPos
017         * @param endPos
018         * @param text
019         * @return position
020         */
021        public static int indexOf( TSourceTokenList list, int startPos, int endPos,
022                        String text )
023        {
024                if ( text == null )
025                {
026                        return -1;
027                }
028
029                for ( int i = startPos; i < endPos; i++ )
030                {
031                        if ( i >= 0 && i < list.size( ) )
032                        {
033                                if (list.get(i).tokenstatus == ETokenStatus.tsdeleted) {
034                                        continue;
035                                }
036
037                                if ( list.get(i).getAstext() != null
038                                                && list.get(i).getAstext().trim( ).equalsIgnoreCase( text ) )
039                                {
040                                        return i;
041                                }
042                        }
043                        else
044                        {
045                                return -1;
046                        }
047                }
048
049                return -1;
050        }
051
052        /**
053         * search the source token in the source token list from the top
054         * 
055         * @param list
056         * @param startPos
057         * @param endPos
058         * @param type
059         * @return
060         */
061        public static int indexOf( TSourceTokenList list, int startPos, int endPos,
062                        ETokenType type )
063        {
064                for ( int i = startPos; i < endPos; i++ )
065                {
066                        if ( i >= 0 && i < list.size( ) )
067                        {
068                                if(list.get(i).tokenstatus == ETokenStatus.tsdeleted) {
069                                        continue;
070                                }
071
072                                if ( type == list.get( i ).tokentype )
073                                {
074                                        return i;
075                                }
076                        }
077                        else
078                        {
079                                return -1;
080                        }
081                }
082
083                return -1;
084        }
085
086        /**
087         * search the source token in the source token list from the top
088         * 
089         * @param list
090         * @param startPos
091         * @param text
092         * @return
093         */
094        public static int indexOf( TSourceTokenList list, int startPos, String text )
095        {
096                return indexOf( list, startPos, list.size( ) - 1, text );
097        }
098
099        /**
100         * backward search the source token
101         * 
102         * @param backsearchSize
103         * @param text
104         * @return
105         */
106        public static TSourceToken backforwardSearch( TSourceToken token,
107                        int backsearchSize, String text )
108        {
109                int pos = SourceTokenSearcher.lastIndexOf( token.container,
110                                token.posinlist - backsearchSize,
111                                token.posinlist,
112                                text );
113                if ( pos == -1 )
114                {
115                        return null;
116                }
117                return token.container.get( pos );
118        }
119
120        /**
121         * forward search the source token
122         * 
123         * @param token
124         * @param forwardSearchSize
125         * @param text
126         * @return
127         */
128        public static TSourceToken forwardSearch( TSourceToken token,
129                        int forwardSearchSize, String text )
130        {
131                int pos = SourceTokenSearcher.indexOf( token.container,
132                                token.posinlist,
133                                token.posinlist + forwardSearchSize,
134                                text );
135                if ( pos == -1 )
136                {
137                        return null;
138                }
139                return token.container.get( pos );
140        }
141
142        /**
143         * search the source token in the source token list from the end
144         * 
145         * @param list
146         * @param startPos
147         * @param endPos
148         * @param text
149         * @return position
150         */
151        public static int lastIndexOf( TSourceTokenList list, int startPos,
152                        int endPos, String text )
153        {
154                if ( text == null )
155                {
156                        return -1;
157                }
158                if ( startPos < 0 )
159                {
160                        startPos = 0;
161                }
162                if ( endPos - 1 > list.size( ) )
163                {
164                        endPos = list.size( );
165                }
166
167                for ( int i = endPos - 1; i >= startPos; i-- )
168                {
169                        if ( i >= 0 && i < list.size( ) )
170                        {
171                                if ( list.get(i).getAstext() != null
172                                                && list.get(i).getAstext().trim( ).equalsIgnoreCase( text ) )
173                                {
174                                        return i;
175                                }
176                        }
177                        else
178                        {
179                                return -1;
180                        }
181                }
182
183                return -1;
184        }
185
186        /**
187         * search the source token in the source token list from the end
188         * 
189         * @param list
190         * @param endPos
191         * @param text
192         * @return
193         */
194        public static int lastIndexOf( TSourceTokenList list, int endPos,
195                        String text )
196        {
197                return lastIndexOf( list, 0, endPos, text );
198        }
199
200        /**
201         * get last token which is not whitespace and return token
202         * 
203         * @param list
204         * @param startPos
205         * @param endPos
206         * @return
207         */
208        public static TSourceToken lastNotWhitespaceAndReturnToken(
209                        TSourceTokenList list, int startPos, int endPos )
210        {
211
212                for ( int i = endPos - 1; i >= startPos; i-- )
213                {
214                        if ( i >= 0 && i < list.size( ) )
215                        {
216                                if(list.get(i).tokenstatus == ETokenStatus.tsdeleted) {
217                                        continue;
218                                }
219
220                                if ( list.get( i ).tokentype == ETokenType.ttwhitespace
221                                                || list.get( i ).tokentype == ETokenType.ttreturn
222                                                || list.get( i ).tokentype == ETokenType.ttsimplecomment
223                                                || list.get( i ).tokentype == ETokenType.ttbracketedcomment )
224                                {
225                                        continue;
226                                }
227                                else
228                                {
229                                        return list.get( i );
230                                }
231                        }
232                        else
233                        {
234                                return null;
235                        }
236                }
237
238                return null;
239        }
240
241        /**
242         * get last token which is not whitespace and return token
243         * 
244         * @param list
245         * @param endPos
246         * @return
247         */
248        public static TSourceToken lastNotWhitespaceAndReturnToken(
249                        TSourceTokenList list, int endPos )
250        {
251                return lastNotWhitespaceAndReturnToken( list, 0, endPos );
252        }
253
254        /**
255         * backward search the token which is the first not whitespace or return
256         * token, and its value is a fixed text
257         * 
258         * @param list
259         * @param endPos
260         *            the fixed value
261         * @return
262         */
263        public static TSourceToken lastSelectedNotWhitespaceAndReturnToken(
264                        TSourceTokenList list, int endPos, String text )
265        {
266                TSourceToken token = lastNotWhitespaceAndReturnToken( list, endPos );
267                if ( token != null
268                                && token.getAstext() != null
269                                && token.getAstext().trim( ).equalsIgnoreCase( text ) )
270                {
271                        return token;
272                }
273                return null;
274        }
275
276        /**
277         * get first token which is not whitespace and return token
278         * 
279         * @param list
280         * @param startPos
281         * @param endPos
282         * @return
283         */
284        public static TSourceToken firstNotWhitespaceAndReturnToken(
285                        TSourceTokenList list, int startPos, int endPos )
286        {
287
288                for ( int i = startPos; i < endPos; i++ )
289                {
290                        if ( i >= 0 && i < list.size( ) )
291                        {
292                                if(list.get(i).tokenstatus == ETokenStatus.tsdeleted) {
293                                        continue;
294                                }
295
296                                if ( list.get( i ).tokentype == ETokenType.ttwhitespace
297                                                || list.get( i ).tokentype == ETokenType.ttreturn
298                                                || list.get( i ).tokentype == ETokenType.ttsimplecomment
299                                                || list.get( i ).tokentype == ETokenType.ttbracketedcomment )
300                                {
301                                        continue;
302                                }
303                                else
304                                {
305                                        return list.get( i );
306                                }
307                        }
308                        else
309                        {
310                                return null;
311                        }
312                }
313
314                return null;
315        }
316
317        /**
318         * forward search the token which is the first not whitespace or return
319         * token, and its value is a fixed text
320         * 
321         * @param list
322         * @param startPos
323         * @param text
324         * @return
325         */
326        public static TSourceToken firstSelectNotWhitespaceAndReturnToken(
327                        TSourceTokenList list, int startPos, String text )
328        {
329                for ( int i = startPos; i < list.size( ); i++ )
330                {
331                        if ( i >= 0 && i < list.size( ) )
332                        {
333                                if(list.get(i).tokenstatus == ETokenStatus.tsdeleted) {
334                                        continue;
335                                }
336
337                                TSourceToken token = list.get( i );
338                                if ( token.tokentype == ETokenType.ttwhitespace
339                                                || token.tokentype == ETokenType.ttreturn
340                                                || list.get( i ).tokentype == ETokenType.ttsimplecomment
341                                                || list.get( i ).tokentype == ETokenType.ttbracketedcomment )
342                                {
343                                        continue;
344                                }
345                                else
346                                {
347                                        if ( token.getAstext() != null
348                                                        && token.getAstext().trim( ).equalsIgnoreCase( text ) )
349                                        {
350                                                return token;
351                                        }
352                                        else
353                                        {
354                                                return null;
355                                        }
356                                }
357                        }
358                }
359
360                return null;
361        }
362
363        /**
364         * backward search the token which is the first not whitespace or return
365         * token, and its value is a fixed text
366         * 
367         * @param token
368         * @param text
369         * @return
370         */
371        public static TSourceToken lastSelectedNotWhitespaceAndReturnToken(
372                        TSourceToken token, String text )
373        {
374                if ( token == null )
375                {
376                        return null;
377                }
378                return lastSelectedNotWhitespaceAndReturnToken( token.container,
379                                token.posinlist,
380                                text );
381        }
382
383        public static boolean isNewLineToken( TSourceToken token )
384        {
385                if ( token == null || token.tokentype != ETokenType.ttreturn )
386                {
387                        return false;
388                }
389                else
390                {
391                        return true;
392                }
393        }
394
395        public static boolean isSimpleComment( TSourceToken token )
396        {
397                if ( token == null || token.tokentype != ETokenType.ttsimplecomment )
398                {
399                        return false;
400                }
401                else
402                {
403                        return true;
404                }
405        }
406
407        /**
408         * Search backward from {@code token} for the token whose text is
409         * {@code text}, counting only solid tokens: whitespace, line breaks and
410         * comments do not consume a step. {@link #backforwardSearch} counts every
411         * token, so a comment sitting between the searched keyword and its
412         * anchor pushed the keyword out of the window and the caller received
413         * {@code null} (NullPointerException in CTEProcessor and
414         * AppendLineAfterInsertTableNameProcessor on real-world scripts).
415         */
416        public static TSourceToken backforwardSearchSolid( TSourceToken token,
417                        int solidSteps, String text )
418        {
419                if ( token == null || token.container == null || text == null )
420                {
421                        return null;
422                }
423                TSourceTokenList list = token.container;
424                int steps = 0;
425                for ( int i = token.posinlist - 1; i >= 0 && steps < solidSteps; i-- )
426                {
427                        TSourceToken t = list.get( i );
428                        if ( t.tokenstatus == ETokenStatus.tsdeleted || isTrivia( t ) )
429                        {
430                                continue;
431                        }
432                        if ( t.getAstext( ) != null && t.getAstext( ).trim( ).equalsIgnoreCase( text ) )
433                        {
434                                return t;
435                        }
436                        steps++;
437                }
438                return null;
439        }
440
441        /** Forward twin of {@link #backforwardSearchSolid}. */
442        public static TSourceToken forwardSearchSolid( TSourceToken token,
443                        int solidSteps, String text )
444        {
445                if ( token == null || token.container == null || text == null )
446                {
447                        return null;
448                }
449                TSourceTokenList list = token.container;
450                int steps = 0;
451                for ( int i = token.posinlist; i < list.size( ) && steps < solidSteps; i++ )
452                {
453                        TSourceToken t = list.get( i );
454                        if ( t.tokenstatus == ETokenStatus.tsdeleted || isTrivia( t ) )
455                        {
456                                continue;
457                        }
458                        if ( t.getAstext( ) != null && t.getAstext( ).trim( ).equalsIgnoreCase( text ) )
459                        {
460                                return t;
461                        }
462                        steps++;
463                }
464                return null;
465        }
466
467        private static boolean isTrivia( TSourceToken t )
468        {
469                return t.tokentype == ETokenType.ttwhitespace
470                                || t.tokentype == ETokenType.ttreturn
471                                || t.tokentype == ETokenType.ttsimplecomment
472                                || t.tokentype == ETokenType.ttbracketedcomment
473                                || t.tokentype == ETokenType.ttCPPComment;
474        }
475
476        public static TSourceToken backforwardSearchNotWhitespaceAndReturnToken(
477                        TSourceToken endToken, int backforwardSearchSize, String text )
478        {
479                TSourceToken currentToken = endToken;
480                while ( backforwardSearchSize > 0 )
481                {
482                        currentToken = lastNotWhitespaceAndReturnToken( currentToken.container,
483                                        currentToken.posinlist );
484                        if ( currentToken != null
485                                        && currentToken.getAstext() != null
486                                        && currentToken.getAstext().trim( ).equalsIgnoreCase( text ) )
487                        {
488                                return currentToken;
489                        }
490
491                        backforwardSearchSize--;
492                }
493                return null;
494        }
495
496        public static TSourceToken lastSelectedToken( TSourceTokenList list,
497                        int startPos, int endPos, String text )
498        {
499                for ( int i = endPos; i >= startPos; i-- )
500                {
501                        if ( i >= 0 && i < list.size( ) )
502                        {
503                                if(list.get(i).tokenstatus == ETokenStatus.tsdeleted) {
504                                        continue;
505                                }
506
507                                TSourceToken token = list.get( i );
508                                if ( token.toString( ).equalsIgnoreCase( text ) )
509                                {
510                                        return token;
511                                }
512                        }
513                        else
514                        {
515                                return null;
516                        }
517                }
518                return null;
519        }
520
521        public static TSourceToken firstSelectedToken( TSourceTokenList list,
522                        int startPos, int endPos, String text )
523        {
524                for ( int i = startPos; i <= endPos; i++ )
525                {
526                        if ( i >= 0 && i < list.size( ) )
527                        {
528                                if(list.get(i).tokenstatus == ETokenStatus.tsdeleted) {
529                                        continue;
530                                }
531
532                                TSourceToken token = list.get( i );
533                                if ( token.toString( ).equalsIgnoreCase( text ) )
534                                {
535                                        return token;
536                                }
537                        }
538                        else
539                        {
540                                return null;
541                        }
542                }
543                return null;
544        }
545
546        // public static boolean isStartWithReturnToken(TSourceToken token) {
547        // if (token == null) {
548        // return false;
549        // }
550        // if (token.astext.startsWith("\n") || token.astext.startsWith("\r\n")) {
551        // return true;
552        // } else {
553        // return false;
554        // }
555        // }
556
557}