KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > compiler > parser > Scanner


1 /*******************************************************************************
2  * Copyright (c) 2000, 2007 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.jdt.internal.compiler.parser;
12
13 import org.eclipse.jdt.core.compiler.CharOperation;
14 import org.eclipse.jdt.core.compiler.InvalidInputException;
15 import org.eclipse.jdt.internal.compiler.CompilationResult;
16 import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
17 import org.eclipse.jdt.internal.compiler.util.Util;
18
19 /**
20  * IMPORTANT NOTE: Internal Scanner implementation. It is mirrored in
21  * org.eclipse.jdt.core.compiler public package where it is API.
22  * The mirror implementation is using the backward compatible ITerminalSymbols constant
23  * definitions (stable with 2.0), whereas the internal implementation uses TerminalTokens
24  * which constant values reflect the latest parser generation state.
25  */

26 public class Scanner implements TerminalTokens {
27     
28     //public int newIdentCount = 0;
29

30     /* APIs ares
31      - getNextToken() which return the current type of the token
32        (this value is not memorized by the scanner)
33      - getCurrentTokenSource() which provides with the token "REAL" source
34        (aka all unicode have been transformed into a correct char)
35      - sourceStart gives the position into the stream
36      - currentPosition-1 gives the sourceEnd position into the stream
37     */

38     public long sourceLevel;
39     public long complianceLevel;
40
41     // 1.4 feature
42
public boolean useAssertAsAnIndentifier = false;
43     //flag indicating if processed source contains occurrences of keyword assert
44
public boolean containsAssertKeyword = false;
45     
46     // 1.5 feature
47
public boolean useEnumAsAnIndentifier = false;
48     
49     public boolean recordLineSeparator = false;
50     public char currentCharacter;
51     public int startPosition;
52     public int currentPosition;
53     public int initialPosition, eofPosition;
54     // after this position eof are generated instead of real token from the source
55

56     public boolean tokenizeComments = false;
57     public boolean tokenizeWhiteSpace = false;
58
59     //source should be viewed as a window (aka a part)
60
//of a entire very large stream
61
public char source[];
62
63     //unicode support
64
public char[] withoutUnicodeBuffer;
65     public int withoutUnicodePtr; //when == 0 ==> no unicode in the current token
66
public boolean unicodeAsBackSlash = false;
67
68     public boolean scanningFloatLiteral = false;
69
70     //support for /** comments
71
public final static int COMMENT_ARRAYS_SIZE = 30;
72     public int[] commentStops = new int[COMMENT_ARRAYS_SIZE];
73     public int[] commentStarts = new int[COMMENT_ARRAYS_SIZE];
74     public int[] commentTagStarts = new int[COMMENT_ARRAYS_SIZE];
75     public int commentPtr = -1; // no comment test with commentPtr value -1
76
protected int lastCommentLinePosition = -1;
77     
78     // task tag support
79
public char[][] foundTaskTags = null;
80     public char[][] foundTaskMessages;
81     public char[][] foundTaskPriorities = null;
82     public int[][] foundTaskPositions;
83     public int foundTaskCount = 0;
84     public char[][] taskTags = null;
85     public char[][] taskPriorities = null;
86     public boolean isTaskCaseSensitive = true;
87     
88     //diet parsing support - jump over some method body when requested
89
public boolean diet = false;
90
91     //support for the poor-line-debuggers ....
92
//remember the position of the cr/lf
93
public int[] lineEnds = new int[250];
94     public int linePtr = -1;
95     public boolean wasAcr = false;
96
97     public static final String JavaDoc END_OF_SOURCE = "End_Of_Source"; //$NON-NLS-1$
98

99     public static final String JavaDoc INVALID_HEXA = "Invalid_Hexa_Literal"; //$NON-NLS-1$
100
public static final String JavaDoc INVALID_OCTAL = "Invalid_Octal_Literal"; //$NON-NLS-1$
101
public static final String JavaDoc INVALID_CHARACTER_CONSTANT = "Invalid_Character_Constant"; //$NON-NLS-1$
102
public static final String JavaDoc INVALID_ESCAPE = "Invalid_Escape"; //$NON-NLS-1$
103
public static final String JavaDoc INVALID_INPUT = "Invalid_Input"; //$NON-NLS-1$
104
public static final String JavaDoc INVALID_UNICODE_ESCAPE = "Invalid_Unicode_Escape"; //$NON-NLS-1$
105
public static final String JavaDoc INVALID_FLOAT = "Invalid_Float_Literal"; //$NON-NLS-1$
106
public static final String JavaDoc INVALID_LOW_SURROGATE = "Invalid_Low_Surrogate"; //$NON-NLS-1$
107
public static final String JavaDoc INVALID_HIGH_SURROGATE = "Invalid_High_Surrogate"; //$NON-NLS-1$
108

109     public static final String JavaDoc NULL_SOURCE_STRING = "Null_Source_String"; //$NON-NLS-1$
110
public static final String JavaDoc UNTERMINATED_STRING = "Unterminated_String"; //$NON-NLS-1$
111
public static final String JavaDoc UNTERMINATED_COMMENT = "Unterminated_Comment"; //$NON-NLS-1$
112
public static final String JavaDoc INVALID_CHAR_IN_STRING = "Invalid_Char_In_String"; //$NON-NLS-1$
113
public static final String JavaDoc INVALID_DIGIT = "Invalid_Digit"; //$NON-NLS-1$
114
private static final int[] EMPTY_LINE_ENDS = Util.EMPTY_INT_ARRAY;
115
116     //----------------optimized identifier managment------------------
117
static final char[] charArray_a = new char[] {'a'},
118         charArray_b = new char[] {'b'},
119         charArray_c = new char[] {'c'},
120         charArray_d = new char[] {'d'},
121         charArray_e = new char[] {'e'},
122         charArray_f = new char[] {'f'},
123         charArray_g = new char[] {'g'},
124         charArray_h = new char[] {'h'},
125         charArray_i = new char[] {'i'},
126         charArray_j = new char[] {'j'},
127         charArray_k = new char[] {'k'},
128         charArray_l = new char[] {'l'},
129         charArray_m = new char[] {'m'},
130         charArray_n = new char[] {'n'},
131         charArray_o = new char[] {'o'},
132         charArray_p = new char[] {'p'},
133         charArray_q = new char[] {'q'},
134         charArray_r = new char[] {'r'},
135         charArray_s = new char[] {'s'},
136         charArray_t = new char[] {'t'},
137         charArray_u = new char[] {'u'},
138         charArray_v = new char[] {'v'},
139         charArray_w = new char[] {'w'},
140         charArray_x = new char[] {'x'},
141         charArray_y = new char[] {'y'},
142         charArray_z = new char[] {'z'};
143
144     static final char[] initCharArray =
145         new char[] {'\u0000', '\u0000', '\u0000', '\u0000', '\u0000', '\u0000'};
146     static final int TableSize = 30, InternalTableSize = 6; //30*6 =210 entries
147

148     public static final int OptimizedLength = 7;
149     public /*static*/ final char[][][][] charArray_length =
150         new char[OptimizedLength][TableSize][InternalTableSize][];
151     // support for detecting non-externalized string literals
152
public static final char[] TAG_PREFIX= "//$NON-NLS-".toCharArray(); //$NON-NLS-1$
153
public static final int TAG_PREFIX_LENGTH= TAG_PREFIX.length;
154     public static final char TAG_POSTFIX= '$';
155     public static final int TAG_POSTFIX_LENGTH= 1;
156     private NLSTag[] nlsTags = null;
157     protected int nlsTagsPtr;
158     public boolean checkNonExternalizedStringLiterals;
159     
160     // generic support
161
public boolean returnOnlyGreater = false;
162     
163     /*static*/ {
164         for (int i = 0; i < 6; i++) {
165             for (int j = 0; j < TableSize; j++) {
166                 for (int k = 0; k < InternalTableSize; k++) {
167                     this.charArray_length[i][j][k] = initCharArray;
168                 }
169             }
170         }
171     }
172     /*static*/ int newEntry2 = 0,
173         newEntry3 = 0,
174         newEntry4 = 0,
175         newEntry5 = 0,
176         newEntry6 = 0;
177     public boolean insideRecovery = false;
178
179     public static final int RoundBracket = 0;
180     public static final int SquareBracket = 1;
181     public static final int CurlyBracket = 2;
182     public static final int BracketKinds = 3;
183     
184     // extended unicode support
185
public static final int LOW_SURROGATE_MIN_VALUE = 0xDC00;
186     public static final int HIGH_SURROGATE_MIN_VALUE = 0xD800;
187     public static final int HIGH_SURROGATE_MAX_VALUE = 0xDBFF;
188     public static final int LOW_SURROGATE_MAX_VALUE = 0xDFFF;
189
190 public Scanner() {
191     this(false /*comment*/, false /*whitespace*/, false /*nls*/, ClassFileConstants.JDK1_3 /*sourceLevel*/, null/*taskTag*/, null/*taskPriorities*/, true /*taskCaseSensitive*/);
192 }
193
194 public Scanner(
195         boolean tokenizeComments,
196         boolean tokenizeWhiteSpace,
197         boolean checkNonExternalizedStringLiterals,
198         long sourceLevel,
199         long complianceLevel,
200         char[][] taskTags,
201         char[][] taskPriorities,
202         boolean isTaskCaseSensitive) {
203
204     this.eofPosition = Integer.MAX_VALUE;
205     this.tokenizeComments = tokenizeComments;
206     this.tokenizeWhiteSpace = tokenizeWhiteSpace;
207     this.sourceLevel = sourceLevel;
208     this.complianceLevel = complianceLevel;
209     this.checkNonExternalizedStringLiterals = checkNonExternalizedStringLiterals;
210     this.taskTags = taskTags;
211     this.taskPriorities = taskPriorities;
212     this.isTaskCaseSensitive = isTaskCaseSensitive;
213 }
214
215 public Scanner(
216         boolean tokenizeComments,
217         boolean tokenizeWhiteSpace,
218         boolean checkNonExternalizedStringLiterals,
219         long sourceLevel,
220         char[][] taskTags,
221         char[][] taskPriorities,
222         boolean isTaskCaseSensitive) {
223
224     this(
225         tokenizeComments,
226         tokenizeWhiteSpace,
227         checkNonExternalizedStringLiterals,
228         sourceLevel,
229         sourceLevel,
230         taskTags,
231         taskPriorities,
232         isTaskCaseSensitive);
233 }
234
235 public final boolean atEnd() {
236     // This code is not relevant if source is
237
// Only a part of the real stream input
238

239     return this.eofPosition <= this.currentPosition;
240 }
241
242 // chech presence of task: tags
243
// TODO (frederic) see if we need to take unicode characters into account...
244
public void checkTaskTag(int commentStart, int commentEnd) throws InvalidInputException {
245     char[] src = this.source;
246     
247     // only look for newer task: tags
248
if (this.foundTaskCount > 0
249         && this.foundTaskPositions[this.foundTaskCount - 1][0] >= commentStart) {
250         return;
251     }
252     int foundTaskIndex = this.foundTaskCount;
253     char previous = src[commentStart+1]; // should be '*' or '/'
254
for (
255         int i = commentStart + 2; i < commentEnd && i < this.eofPosition; i++) {
256         char[] tag = null;
257         char[] priority = null;
258         // check for tag occurrence only if not ambiguous with javadoc tag
259
if (previous != '@') {
260             nextTag : for (int itag = 0; itag < this.taskTags.length; itag++) {
261                 tag = this.taskTags[itag];
262                 int tagLength = tag.length;
263                 if (tagLength == 0) continue nextTag;
264     
265                 // ensure tag is not leaded with letter if tag starts with a letter
266
if (ScannerHelper.isJavaIdentifierStart(tag[0])) {
267                     if (ScannerHelper.isJavaIdentifierPart(previous)) {
268                         continue nextTag;
269                     }
270                 }
271     
272                 for (int t = 0; t < tagLength; t++) {
273                     char sc, tc;
274                     int x = i+t;
275                     if (x >= this.eofPosition || x >= commentEnd) continue nextTag;
276                     if ((sc = src[i + t]) != (tc = tag[t])) { // case sensitive check
277
if (this.isTaskCaseSensitive || (ScannerHelper.toLowerCase(sc) != ScannerHelper.toLowerCase(tc))) { // case insensitive check
278
continue nextTag;
279                         }
280                     }
281                 }
282                 // ensure tag is not followed with letter if tag finishes with a letter
283
if (i+tagLength < commentEnd && ScannerHelper.isJavaIdentifierPart(src[i+tagLength-1])) {
284                     if (ScannerHelper.isJavaIdentifierPart(src[i + tagLength]))
285                         continue nextTag;
286                 }
287                 if (this.foundTaskTags == null) {
288                     this.foundTaskTags = new char[5][];
289                     this.foundTaskMessages = new char[5][];
290                     this.foundTaskPriorities = new char[5][];
291                     this.foundTaskPositions = new int[5][];
292                 } else if (this.foundTaskCount == this.foundTaskTags.length) {
293                     System.arraycopy(this.foundTaskTags, 0, this.foundTaskTags = new char[this.foundTaskCount * 2][], 0, this.foundTaskCount);
294                     System.arraycopy(this.foundTaskMessages, 0, this.foundTaskMessages = new char[this.foundTaskCount * 2][], 0, this.foundTaskCount);
295                     System.arraycopy(this.foundTaskPriorities, 0, this.foundTaskPriorities = new char[this.foundTaskCount * 2][], 0, this.foundTaskCount);
296                     System.arraycopy(this.foundTaskPositions, 0, this.foundTaskPositions = new int[this.foundTaskCount * 2][], 0, this.foundTaskCount);
297                 }
298                 
299                 priority = this.taskPriorities != null && itag < this.taskPriorities.length
300                             ? this.taskPriorities[itag]
301                             : null;
302                 
303                 this.foundTaskTags[this.foundTaskCount] = tag;
304                 this.foundTaskPriorities[this.foundTaskCount] = priority;
305                 this.foundTaskPositions[this.foundTaskCount] = new int[] { i, i + tagLength - 1 };
306                 this.foundTaskMessages[this.foundTaskCount] = CharOperation.NO_CHAR;
307                 this.foundTaskCount++;
308                 i += tagLength - 1; // will be incremented when looping
309
break nextTag;
310             }
311         }
312         previous = src[i];
313     }
314     boolean containsEmptyTask = false;
315     for (int i = foundTaskIndex; i < this.foundTaskCount; i++) {
316         // retrieve message start and end positions
317
int msgStart = this.foundTaskPositions[i][0] + this.foundTaskTags[i].length;
318         int max_value = i + 1 < this.foundTaskCount
319                 ? this.foundTaskPositions[i + 1][0] - 1
320                 : commentEnd - 1;
321         // at most beginning of next task
322
if (max_value < msgStart) {
323             max_value = msgStart; // would only occur if tag is before EOF.
324
}
325         int end = -1;
326         char c;
327         for (int j = msgStart; j < max_value; j++) {
328             if ((c = src[j]) == '\n' || c == '\r') {
329                 end = j - 1;
330                 break;
331             }
332         }
333         if (end == -1) {
334             for (int j = max_value; j > msgStart; j--) {
335                 if ((c = src[j]) == '*') {
336                     end = j - 1;
337                     break;
338                 }
339             }
340             if (end == -1)
341                 end = max_value;
342         }
343         if (msgStart == end) {
344             // if the description is empty, we might want to see if two tags are not sharing the same message
345
// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=110797
346
containsEmptyTask = true;
347             continue;
348         }
349         // trim the message
350
while (CharOperation.isWhitespace(src[end]) && msgStart <= end)
351             end--;
352         while (CharOperation.isWhitespace(src[msgStart]) && msgStart <= end)
353             msgStart++;
354         // update the end position of the task
355
this.foundTaskPositions[i][1] = end;
356         // get the message source
357
final int messageLength = end - msgStart + 1;
358         char[] message = new char[messageLength];
359         System.arraycopy(src, msgStart, message, 0, messageLength);
360         this.foundTaskMessages[i] = message;
361     }
362     if (containsEmptyTask) {
363         for (int i = foundTaskIndex, max = this.foundTaskCount; i < max; i++) {
364             if (this.foundTaskMessages[i].length == 0) {
365                 loop: for (int j = i + 1; j < max; j++) {
366                     if (this.foundTaskMessages[j].length != 0) {
367                         this.foundTaskMessages[i] = this.foundTaskMessages[j];
368                         this.foundTaskPositions[i][1] = this.foundTaskPositions[j][1];
369                         break loop;
370                     }
371                 }
372             }
373         }
374     }
375 }
376
377 public char[] getCurrentIdentifierSource() {
378     //return the token REAL source (aka unicodes are precomputed)
379

380     char[] result;
381     if (this.withoutUnicodePtr != 0) {
382         //0 is used as a fast test flag so the real first char is in position 1
383
System.arraycopy(
384             this.withoutUnicodeBuffer,
385             1,
386             result = new char[this.withoutUnicodePtr],
387             0,
388             this.withoutUnicodePtr);
389     } else {
390         int length = this.currentPosition - this.startPosition;
391         if (length == this.eofPosition) return this.source;
392         switch (length) { // see OptimizedLength
393
case 1 :
394                 return optimizedCurrentTokenSource1();
395             case 2 :
396                 return optimizedCurrentTokenSource2();
397             case 3 :
398                 return optimizedCurrentTokenSource3();
399             case 4 :
400                 return optimizedCurrentTokenSource4();
401             case 5 :
402                 return optimizedCurrentTokenSource5();
403             case 6 :
404                 return optimizedCurrentTokenSource6();
405         }
406         //no optimization
407
System.arraycopy(this.source, this.startPosition, result = new char[length], 0, length);
408     }
409     //newIdentCount++;
410
return result;
411 }
412 public int getCurrentTokenEndPosition(){
413     return this.currentPosition - 1;
414 }
415 public char[] getCurrentTokenSource() {
416     // Return the token REAL source (aka unicodes are precomputed)
417

418     char[] result;
419     if (this.withoutUnicodePtr != 0)
420         // 0 is used as a fast test flag so the real first char is in position 1
421
System.arraycopy(
422             this.withoutUnicodeBuffer,
423             1,
424             result = new char[this.withoutUnicodePtr],
425             0,
426             this.withoutUnicodePtr);
427     else {
428         int length;
429         System.arraycopy(
430             this.source,
431             this.startPosition,
432             result = new char[length = this.currentPosition - this.startPosition],
433             0,
434             length);
435     }
436     return result;
437 }
438 public final String JavaDoc getCurrentTokenString() {
439     // Return current token as a string
440

441     if (this.withoutUnicodePtr != 0) {
442         // 0 is used as a fast test flag so the real first char is in position 1
443
return new String JavaDoc(
444             this.withoutUnicodeBuffer,
445             1,
446             this.withoutUnicodePtr);
447     }
448     return new String JavaDoc(
449         this.source,
450         this.startPosition,
451         this.currentPosition - this.startPosition);
452 }
453 public char[] getCurrentTokenSourceString() {
454     //return the token REAL source (aka unicodes are precomputed).
455
//REMOVE the two " that are at the beginning and the end.
456

457     char[] result;
458     if (this.withoutUnicodePtr != 0)
459         //0 is used as a fast test flag so the real first char is in position 1
460
System.arraycopy(this.withoutUnicodeBuffer, 2,
461         //2 is 1 (real start) + 1 (to jump over the ")
462
result = new char[this.withoutUnicodePtr - 2], 0, this.withoutUnicodePtr - 2);
463     else {
464         int length;
465         System.arraycopy(
466             this.source,
467             this.startPosition + 1,
468             result = new char[length = this.currentPosition - this.startPosition - 2],
469             0,
470             length);
471     }
472     return result;
473 }
474 public final String JavaDoc getCurrentStringLiteral() {
475     //return the token REAL source (aka unicodes are precomputed).
476
//REMOVE the two " that are at the beginning and the end.
477

478     if (this.withoutUnicodePtr != 0)
479         //0 is used as a fast test flag so the real first char is in position 1
480
//2 is 1 (real start) + 1 (to jump over the ")
481
return new String JavaDoc(this.withoutUnicodeBuffer, 2, this.withoutUnicodePtr - 2);
482     else {
483         return new String JavaDoc(this.source, this.startPosition + 1, this.currentPosition - this.startPosition - 2);
484     }
485 }
486 public final char[] getRawTokenSource() {
487     int length = this.currentPosition - this.startPosition;
488     char[] tokenSource = new char[length];
489     System.arraycopy(this.source, this.startPosition, tokenSource, 0, length);
490     return tokenSource;
491 }
492     
493 public final char[] getRawTokenSourceEnd() {
494     int length = this.eofPosition - this.currentPosition - 1;
495     char[] sourceEnd = new char[length];
496     System.arraycopy(this.source, this.currentPosition, sourceEnd, 0, length);
497     return sourceEnd;
498 }
499     
500 public int getCurrentTokenStartPosition(){
501     return this.startPosition;
502 }
503 /*
504  * Search the source position corresponding to the end of a given line number
505  *
506  * Line numbers are 1-based, and relative to the scanner initialPosition.
507  * Character positions are 0-based.
508  *
509  * In case the given line number is inconsistent, answers -1.
510  */

511 public final int getLineEnd(int lineNumber) {
512
513     if (this.lineEnds == null || this.linePtr == -1)
514         return -1;
515     if (lineNumber > this.lineEnds.length+1)
516         return -1;
517     if (lineNumber <= 0)
518         return -1;
519     if (lineNumber == this.lineEnds.length + 1)
520         return this.eofPosition;
521     return this.lineEnds[lineNumber-1]; // next line start one character behind the lineEnd of the previous line
522
}
523
524 public final int[] getLineEnds() {
525     //return a bounded copy of this.lineEnds
526
if (this.linePtr == -1) {
527         return EMPTY_LINE_ENDS;
528     }
529     int[] copy;
530     System.arraycopy(this.lineEnds, 0, copy = new int[this.linePtr + 1], 0, this.linePtr + 1);
531     return copy;
532 }
533
534 /**
535  * Search the source position corresponding to the beginning of a given line number
536  *
537  * Line numbers are 1-based, and relative to the scanner initialPosition.
538  * Character positions are 0-based.
539  *
540  * e.g. getLineStart(1) --> 0 indicates that the first line starts at character 0.
541  *
542  * In case the given line number is inconsistent, answers -1.
543  *
544  * @param lineNumber int
545  * @return int
546  */

547 public final int getLineStart(int lineNumber) {
548
549     if (this.lineEnds == null || this.linePtr == -1)
550         return -1;
551     if (lineNumber > this.lineEnds.length + 1)
552         return -1;
553     if (lineNumber <= 0)
554         return -1;
555     
556     if (lineNumber == 1)
557         return this.initialPosition;
558     return this.lineEnds[lineNumber-2]+1; // next line start one character behind the lineEnd of the previous line
559
}
560 public final int getNextChar() {
561     try {
562         if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
563             && (this.source[this.currentPosition] == 'u')) {
564                 getNextUnicodeChar();
565         } else {
566             this.unicodeAsBackSlash = false;
567             if (this.withoutUnicodePtr != 0) {
568                 unicodeStore();
569             }
570         }
571         return this.currentCharacter;
572     } catch (IndexOutOfBoundsException JavaDoc e) {
573         return -1;
574     } catch(InvalidInputException e) {
575         return -1;
576     }
577 }
578 public final int getNextCharWithBoundChecks() {
579     if (this.currentPosition >= this.eofPosition) {
580         return -1;
581     }
582     this.currentCharacter = this.source[this.currentPosition++];
583     if (this.currentPosition >= this.eofPosition) {
584         this.unicodeAsBackSlash = false;
585         if (this.withoutUnicodePtr != 0) {
586             unicodeStore();
587         }
588         return this.currentCharacter;
589     }
590     if (this.currentCharacter == '\\' && this.source[this.currentPosition] == 'u') {
591         try {
592             getNextUnicodeChar();
593         } catch (InvalidInputException e) {
594             return -1;
595         }
596     } else {
597         this.unicodeAsBackSlash = false;
598         if (this.withoutUnicodePtr != 0) {
599             unicodeStore();
600         }
601     }
602     return this.currentCharacter;
603 }
604 public final boolean getNextChar(char testedChar) {
605     //BOOLEAN
606
//handle the case of unicode.
607
//when a unicode appears then we must use a buffer that holds char internal values
608
//At the end of this method currentCharacter holds the new visited char
609
//and currentPosition points right next after it
610
//Both previous lines are true if the currentCharacter is == to the testedChar
611
//On false, no side effect has occured.
612

613     //ALL getNextChar.... ARE OPTIMIZED COPIES
614

615     if (this.currentPosition >= this.eofPosition) { // handle the obvious case upfront
616
this.unicodeAsBackSlash = false;
617         return false;
618     }
619
620     int temp = this.currentPosition;
621     try {
622         if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
623             && (this.source[this.currentPosition] == 'u')) {
624             getNextUnicodeChar();
625             if (this.currentCharacter != testedChar) {
626                 this.currentPosition = temp;
627                 this.withoutUnicodePtr--;
628                 return false;
629             }
630             return true;
631         } //-------------end unicode traitement--------------
632
else {
633             if (this.currentCharacter != testedChar) {
634                 this.currentPosition = temp;
635                 return false;
636             }
637             this.unicodeAsBackSlash = false;
638             if (this.withoutUnicodePtr != 0)
639                 unicodeStore();
640             return true;
641         }
642     } catch (IndexOutOfBoundsException JavaDoc e) {
643         this.unicodeAsBackSlash = false;
644         this.currentPosition = temp;
645         return false;
646     } catch(InvalidInputException e) {
647         this.unicodeAsBackSlash = false;
648         this.currentPosition = temp;
649         return false;
650     }
651 }
652 public final int getNextChar(char testedChar1, char testedChar2) {
653     //INT 0 : testChar1 \\\\///\\\\ 1 : testedChar2 \\\\///\\\\ -1 : others
654
//test can be done with (x==0) for the first and (x>0) for the second
655
//handle the case of unicode.
656
//when a unicode appears then we must use a buffer that holds char internal values
657
//At the end of this method currentCharacter holds the new visited char
658
//and currentPosition points right next after it
659
//Both previous lines are true if the currentCharacter is == to the testedChar1/2
660
//On false, no side effect has occured.
661

662     //ALL getNextChar.... ARE OPTIMIZED COPIES
663
if (this.currentPosition >= this.eofPosition) // handle the obvious case upfront
664
return -1;
665
666     int temp = this.currentPosition;
667     try {
668         int result;
669         if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
670             && (this.source[this.currentPosition] == 'u')) {
671             getNextUnicodeChar();
672             if (this.currentCharacter == testedChar1) {
673                 result = 0;
674             } else if (this.currentCharacter == testedChar2) {
675                 result = 1;
676             } else {
677                 this.currentPosition = temp;
678                 this.withoutUnicodePtr--;
679                 result = -1;
680             }
681             return result;
682         } else {
683             if (this.currentCharacter == testedChar1) {
684                 result = 0;
685             } else if (this.currentCharacter == testedChar2) {
686                 result = 1;
687             } else {
688                 this.currentPosition = temp;
689                 return -1;
690             }
691
692             if (this.withoutUnicodePtr != 0)
693                 unicodeStore();
694             return result;
695         }
696     } catch (IndexOutOfBoundsException JavaDoc e) {
697         this.currentPosition = temp;
698         return -1;
699     } catch(InvalidInputException e) {
700         this.currentPosition = temp;
701         return -1;
702     }
703 }
704 public final boolean getNextCharAsDigit() throws InvalidInputException {
705     //BOOLEAN
706
//handle the case of unicode.
707
//when a unicode appears then we must use a buffer that holds char internal values
708
//At the end of this method currentCharacter holds the new visited char
709
//and currentPosition points right next after it
710
//Both previous lines are true if the currentCharacter is a digit
711
//On false, no side effect has occured.
712

713     //ALL getNextChar.... ARE OPTIMIZED COPIES
714
if (this.currentPosition >= this.eofPosition) // handle the obvious case upfront
715
return false;
716
717     int temp = this.currentPosition;
718     try {
719         if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
720             && (this.source[this.currentPosition] == 'u')) {
721             getNextUnicodeChar();
722             if (!ScannerHelper.isDigit(this.currentCharacter)) {
723                 this.currentPosition = temp;
724                 this.withoutUnicodePtr--;
725                 return false;
726             }
727             return true;
728         } else {
729             if (!ScannerHelper.isDigit(this.currentCharacter)) {
730                 this.currentPosition = temp;
731                 return false;
732             }
733             if (this.withoutUnicodePtr != 0)
734                 unicodeStore();
735             return true;
736         }
737     } catch (IndexOutOfBoundsException JavaDoc e) {
738         this.currentPosition = temp;
739         return false;
740     } catch(InvalidInputException e) {
741         this.currentPosition = temp;
742         return false;
743     }
744 }
745 public final boolean getNextCharAsDigit(int radix) {
746     //BOOLEAN
747
//handle the case of unicode.
748
//when a unicode appears then we must use a buffer that holds char internal values
749
//At the end of this method currentCharacter holds the new visited char
750
//and currentPosition points right next after it
751
//Both previous lines are true if the currentCharacter is a digit base on radix
752
//On false, no side effect has occured.
753

754     //ALL getNextChar.... ARE OPTIMIZED COPIES
755
if (this.currentPosition >= this.eofPosition) // handle the obvious case upfront
756
return false;
757
758     int temp = this.currentPosition;
759     try {
760         if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
761             && (this.source[this.currentPosition] == 'u')) {
762             getNextUnicodeChar();
763             if (ScannerHelper.digit(this.currentCharacter, radix) == -1) {
764                 this.currentPosition = temp;
765                 this.withoutUnicodePtr--;
766                 return false;
767             }
768             return true;
769         } else {
770             if (ScannerHelper.digit(this.currentCharacter, radix) == -1) {
771                 this.currentPosition = temp;
772                 return false;
773             }
774             if (this.withoutUnicodePtr != 0)
775                 unicodeStore();
776             return true;
777         }
778     } catch (IndexOutOfBoundsException JavaDoc e) {
779         this.currentPosition = temp;
780         return false;
781     } catch(InvalidInputException e) {
782         this.currentPosition = temp;
783         return false;
784     }
785 }
786 public boolean getNextCharAsJavaIdentifierPartWithBoundCheck() {
787     //BOOLEAN
788
//handle the case of unicode.
789
//when a unicode appears then we must use a buffer that holds char internal values
790
//At the end of this method currentCharacter holds the new visited char
791
//and currentPosition points right next after it
792
//Both previous lines are true if the currentCharacter is a JavaIdentifierPart
793
//On false, no side effect has occured.
794

795     //ALL getNextChar.... ARE OPTIMIZED COPIES
796
int pos = this.currentPosition;
797     if (pos >= this.eofPosition) // handle the obvious case upfront
798
return false;
799
800     int temp2 = this.withoutUnicodePtr;
801     try {
802         boolean unicode = false;
803         this.currentCharacter = this.source[this.currentPosition++];
804         if (this.currentPosition < this.eofPosition) {
805             if (this.currentCharacter == '\\' && this.source[this.currentPosition] == 'u') {
806                 getNextUnicodeChar();
807                 unicode = true;
808             }
809         }
810         char c = this.currentCharacter;
811         boolean isJavaIdentifierPart = false;
812         if (c >= HIGH_SURROGATE_MIN_VALUE && c <= HIGH_SURROGATE_MAX_VALUE) {
813             if (this.complianceLevel < ClassFileConstants.JDK1_5) {
814                 this.currentPosition = pos;
815                 this.withoutUnicodePtr = temp2;
816                 return false;
817             }
818             // Unicode 4 detection
819
char low = (char) getNextCharWithBoundChecks();
820             if (low < LOW_SURROGATE_MIN_VALUE || low > LOW_SURROGATE_MAX_VALUE) {
821                 // illegal low surrogate
822
this.currentPosition = pos;
823                 this.withoutUnicodePtr = temp2;
824                 return false;
825             }
826             isJavaIdentifierPart = ScannerHelper.isJavaIdentifierPart(c, low);
827         }
828         else if (c >= LOW_SURROGATE_MIN_VALUE && c <= LOW_SURROGATE_MAX_VALUE) {
829             this.currentPosition = pos;
830             this.withoutUnicodePtr = temp2;
831             return false;
832         } else {
833             isJavaIdentifierPart = ScannerHelper.isJavaIdentifierPart(c);
834         }
835         if (unicode) {
836             if (!isJavaIdentifierPart) {
837                 this.currentPosition = pos;
838                 this.withoutUnicodePtr = temp2;
839                 return false;
840             }
841             return true;
842         } else {
843             if (!isJavaIdentifierPart) {
844                 this.currentPosition = pos;
845                 return false;
846             }
847
848             if (this.withoutUnicodePtr != 0)
849                 unicodeStore();
850             return true;
851         }
852     } catch(InvalidInputException e) {
853         this.currentPosition = pos;
854         this.withoutUnicodePtr = temp2;
855         return false;
856     }
857 }
858 public boolean getNextCharAsJavaIdentifierPart() {
859     //BOOLEAN
860
//handle the case of unicode.
861
//when a unicode appears then we must use a buffer that holds char internal values
862
//At the end of this method currentCharacter holds the new visited char
863
//and currentPosition points right next after it
864
//Both previous lines are true if the currentCharacter is a JavaIdentifierPart
865
//On false, no side effect has occured.
866

867     //ALL getNextChar.... ARE OPTIMIZED COPIES
868
int pos;
869     if ((pos = this.currentPosition) >= this.eofPosition) // handle the obvious case upfront
870
return false;
871
872     int temp2 = this.withoutUnicodePtr;
873     try {
874         boolean unicode = false;
875         if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
876             && (this.source[this.currentPosition] == 'u')) {
877             getNextUnicodeChar();
878             unicode = true;
879         }
880         char c = this.currentCharacter;
881         boolean isJavaIdentifierPart = false;
882         if (c >= HIGH_SURROGATE_MIN_VALUE && c <= HIGH_SURROGATE_MAX_VALUE) {
883             if (this.complianceLevel < ClassFileConstants.JDK1_5) {
884                 this.currentPosition = pos;
885                 this.withoutUnicodePtr = temp2;
886                 return false;
887             }
888             // Unicode 4 detection
889
char low = (char) getNextChar();
890             if (low < LOW_SURROGATE_MIN_VALUE || low > LOW_SURROGATE_MAX_VALUE) {
891                 // illegal low surrogate
892
this.currentPosition = pos;
893                 this.withoutUnicodePtr = temp2;
894                 return false;
895             }
896             isJavaIdentifierPart = ScannerHelper.isJavaIdentifierPart(c, low);
897         }
898         else if (c >= LOW_SURROGATE_MIN_VALUE && c <= LOW_SURROGATE_MAX_VALUE) {
899             this.currentPosition = pos;
900             this.withoutUnicodePtr = temp2;
901             return false;
902         } else {
903             isJavaIdentifierPart = ScannerHelper.isJavaIdentifierPart(c);
904         }
905         if (unicode) {
906             if (!isJavaIdentifierPart) {
907                 this.currentPosition = pos;
908                 this.withoutUnicodePtr = temp2;
909                 return false;
910             }
911             return true;
912         } else {
913             if (!isJavaIdentifierPart) {
914                 this.currentPosition = pos;
915                 return false;
916             }
917
918             if (this.withoutUnicodePtr != 0)
919                 unicodeStore();
920             return true;
921         }
922     } catch (IndexOutOfBoundsException JavaDoc e) {
923         this.currentPosition = pos;
924         this.withoutUnicodePtr = temp2;
925         return false;
926     } catch(InvalidInputException e) {
927         this.currentPosition = pos;
928         this.withoutUnicodePtr = temp2;
929         return false;
930     }
931 }
932 /*
933  * External API in JavaConventions.
934  * This is used to optimize the case where the scanner is used to scan a single identifier.
935  * In this case, the AIOOBE is slower to handle than a bound check
936  */

937 public int scanIdentifier() throws InvalidInputException {
938     int whiteStart = 0;
939     while (true) { //loop for jumping over comments
940
this.withoutUnicodePtr = 0;
941         //start with a new token (even comment written with unicode )
942
// ---------Consume white space and handles startPosition---------
943
whiteStart = this.currentPosition;
944         boolean isWhiteSpace, hasWhiteSpaces = false;
945         int offset;
946         int unicodePtr;
947         boolean checkIfUnicode = false;
948         do {
949             unicodePtr = this.withoutUnicodePtr;
950             offset = this.currentPosition;
951             this.startPosition = this.currentPosition;
952             if (this.currentPosition < this.eofPosition) {
953                 this.currentCharacter = this.source[this.currentPosition++];
954                 checkIfUnicode = this.currentPosition < this.eofPosition
955                         && this.currentCharacter == '\\'
956                         && this.source[this.currentPosition] == 'u';
957             } else if (this.tokenizeWhiteSpace && (whiteStart != this.currentPosition - 1)) {
958                 // reposition scanner in case we are interested by spaces as tokens
959
this.currentPosition--;
960                 this.startPosition = whiteStart;
961                 return TokenNameWHITESPACE;
962             } else {
963                 return TokenNameEOF;
964             }
965             if (checkIfUnicode) {
966                 isWhiteSpace = jumpOverUnicodeWhiteSpace();
967                 offset = this.currentPosition - offset;
968             } else {
969                 offset = this.currentPosition - offset;
970                 // inline version of:
971
//isWhiteSpace =
972
// (this.currentCharacter == ' ') || ScannerHelper.isWhitespace(this.currentCharacter);
973
switch (this.currentCharacter) {
974                     case 10 : /* \ u000a: LINE FEED */
975                     case 12 : /* \ u000c: FORM FEED */
976                     case 13 : /* \ u000d: CARRIAGE RETURN */
977                     case 32 : /* \ u0020: SPACE */
978                     case 9 : /* \ u0009: HORIZONTAL TABULATION */
979                         isWhiteSpace = true;
980                         break;
981                     default :
982                         isWhiteSpace = false;
983                 }
984             }
985             if (isWhiteSpace) {
986                 hasWhiteSpaces = true;
987             }
988         } while (isWhiteSpace);
989         if (hasWhiteSpaces) {
990             if (this.tokenizeWhiteSpace) {
991                 // reposition scanner in case we are interested by spaces as tokens
992
this.currentPosition-=offset;
993                 this.startPosition = whiteStart;
994                 if (checkIfUnicode) {
995                     this.withoutUnicodePtr = unicodePtr;
996                 }
997                 return TokenNameWHITESPACE;
998             } else if (checkIfUnicode) {
999                 this.withoutUnicodePtr = 0;
1000                unicodeStore();
1001            } else {
1002                this.withoutUnicodePtr = 0;
1003            }
1004        }
1005        char c = this.currentCharacter;
1006        if (c < ScannerHelper.MAX_OBVIOUS) {
1007            if ((ScannerHelper.OBVIOUS_IDENT_CHAR_NATURES[c] & ScannerHelper.C_IDENT_START) != 0) {
1008                return scanIdentifierOrKeywordWithBoundCheck();
1009            }
1010            return TokenNameERROR;
1011        }
1012        boolean isJavaIdStart;
1013        if (c >= HIGH_SURROGATE_MIN_VALUE && c <= HIGH_SURROGATE_MAX_VALUE) {
1014            if (this.complianceLevel < ClassFileConstants.JDK1_5) {
1015                throw new InvalidInputException(INVALID_UNICODE_ESCAPE);
1016            }
1017            // Unicode 4 detection
1018
char low = (char) getNextCharWithBoundChecks();
1019            if (low < LOW_SURROGATE_MIN_VALUE || low > LOW_SURROGATE_MAX_VALUE) {
1020                // illegal low surrogate
1021
throw new InvalidInputException(INVALID_LOW_SURROGATE);
1022            }
1023            isJavaIdStart = ScannerHelper.isJavaIdentifierStart(c, low);
1024        } else if (c >= LOW_SURROGATE_MIN_VALUE && c <= LOW_SURROGATE_MAX_VALUE) {
1025            if (this.complianceLevel < ClassFileConstants.JDK1_5) {
1026                throw new InvalidInputException(INVALID_UNICODE_ESCAPE);
1027            }
1028            throw new InvalidInputException(INVALID_HIGH_SURROGATE);
1029        } else {
1030            // optimized case already checked
1031
isJavaIdStart = Character.isJavaIdentifierStart(c);
1032        }
1033        if (isJavaIdStart)
1034            return scanIdentifierOrKeywordWithBoundCheck();
1035        return TokenNameERROR;
1036    }
1037}
1038public int getNextToken() throws InvalidInputException {
1039    this.wasAcr = false;
1040    if (this.diet) {
1041        jumpOverMethodBody();
1042        this.diet = false;
1043        return this.currentPosition > this.eofPosition ? TokenNameEOF : TokenNameRBRACE;
1044    }
1045    int whiteStart = 0;
1046    try {
1047        while (true) { //loop for jumping over comments
1048
this.withoutUnicodePtr = 0;
1049            //start with a new token (even comment written with unicode )
1050

1051            // ---------Consume white space and handles startPosition---------
1052
whiteStart = this.currentPosition;
1053            boolean isWhiteSpace, hasWhiteSpaces = false;
1054            int offset;
1055            int unicodePtr;
1056            boolean checkIfUnicode = false;
1057            do {
1058                unicodePtr = this.withoutUnicodePtr;
1059                offset = this.currentPosition;
1060                this.startPosition = this.currentPosition;
1061                try {
1062                    checkIfUnicode = ((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
1063                        && (this.source[this.currentPosition] == 'u');
1064                } catch(IndexOutOfBoundsException JavaDoc e) {
1065                    if (this.tokenizeWhiteSpace && (whiteStart != this.currentPosition - 1)) {
1066                        // reposition scanner in case we are interested by spaces as tokens
1067
this.currentPosition--;
1068                        this.startPosition = whiteStart;
1069                        return TokenNameWHITESPACE;
1070                    }
1071                    if (this.currentPosition > this.eofPosition)
1072                        return TokenNameEOF;
1073                }
1074                if (this.currentPosition > this.eofPosition)
1075                    return TokenNameEOF;
1076                if (checkIfUnicode) {
1077                    isWhiteSpace = jumpOverUnicodeWhiteSpace();
1078                    offset = this.currentPosition - offset;
1079                } else {
1080                    offset = this.currentPosition - offset;
1081                    if ((this.currentCharacter == '\r') || (this.currentCharacter == '\n')) {
1082                        if (this.recordLineSeparator) {
1083                            pushLineSeparator();
1084                        }
1085                    }
1086                    // inline version of:
1087
//isWhiteSpace =
1088
// (this.currentCharacter == ' ') || ScannerHelper.isWhitespace(this.currentCharacter);
1089
switch (this.currentCharacter) {
1090                        case 10 : /* \ u000a: LINE FEED */
1091                        case 12 : /* \ u000c: FORM FEED */
1092                        case 13 : /* \ u000d: CARRIAGE RETURN */
1093                        case 32 : /* \ u0020: SPACE */
1094                        case 9 : /* \ u0009: HORIZONTAL TABULATION */
1095                            isWhiteSpace = true;
1096                            break;
1097                        default :
1098                            isWhiteSpace = false;
1099                    }
1100                }
1101                if (isWhiteSpace) {
1102                    hasWhiteSpaces = true;
1103                }
1104            } while (isWhiteSpace);
1105            if (hasWhiteSpaces) {
1106                if (this.tokenizeWhiteSpace) {
1107                    // reposition scanner in case we are interested by spaces as tokens
1108
this.currentPosition-=offset;
1109                    this.startPosition = whiteStart;
1110                    if (checkIfUnicode) {
1111                        this.withoutUnicodePtr = unicodePtr;
1112                    }
1113                    return TokenNameWHITESPACE;
1114                } else if (checkIfUnicode) {
1115                    this.withoutUnicodePtr = 0;
1116                    unicodeStore();
1117                } else {
1118                    this.withoutUnicodePtr = 0;
1119                }
1120            }
1121            // ---------Identify the next token-------------
1122
switch (this.currentCharacter) {
1123                case '@' :
1124/* if (this.sourceLevel >= ClassFileConstants.JDK1_5) {
1125                        return TokenNameAT;
1126                    } else {
1127                        return TokenNameERROR;
1128                    }*/

1129                    return TokenNameAT;
1130                case '(' :
1131                    return TokenNameLPAREN;
1132                case ')' :
1133                    return TokenNameRPAREN;
1134                case '{' :
1135                    return TokenNameLBRACE;
1136                case '}' :
1137                    return TokenNameRBRACE;
1138                case '[' :
1139                    return TokenNameLBRACKET;
1140                case ']' :
1141                    return TokenNameRBRACKET;
1142                case ';' :
1143                    return TokenNameSEMICOLON;
1144                case ',' :
1145                    return TokenNameCOMMA;
1146                case '.' :
1147                    if (getNextCharAsDigit()) {
1148                        return scanNumber(true);
1149                    }
1150                    int temp = this.currentPosition;
1151                    if (getNextChar('.')) {
1152                        if (getNextChar('.')) {
1153                            return TokenNameELLIPSIS;
1154                        } else {
1155                            this.currentPosition = temp;
1156                            return TokenNameDOT;
1157                        }
1158                    } else {
1159                        this.currentPosition = temp;
1160                        return TokenNameDOT;
1161                    }
1162                case '+' :
1163                    {
1164                        int test;
1165                        if ((test = getNextChar('+', '=')) == 0)
1166                            return TokenNamePLUS_PLUS;
1167                        if (test > 0)
1168                            return TokenNamePLUS_EQUAL;
1169                        return TokenNamePLUS;
1170                    }
1171                case '-' :
1172                    {
1173                        int test;
1174                        if ((test = getNextChar('-', '=')) == 0)
1175                            return TokenNameMINUS_MINUS;
1176                        if (test > 0)
1177                            return TokenNameMINUS_EQUAL;
1178                        return TokenNameMINUS;
1179                    }
1180                case '~' :
1181                    return TokenNameTWIDDLE;
1182                case '!' :
1183                    if (getNextChar('='))
1184                        return TokenNameNOT_EQUAL;
1185                    return TokenNameNOT;
1186                case '*' :
1187                    if (getNextChar('='))
1188                        return TokenNameMULTIPLY_EQUAL;
1189                    return TokenNameMULTIPLY;
1190                case '%' :
1191                    if (getNextChar('='))
1192                        return TokenNameREMAINDER_EQUAL;
1193                    return TokenNameREMAINDER;
1194                case '<' :
1195                    {
1196                        int test;
1197                        if ((test = getNextChar('=', '<')) == 0)
1198                            return TokenNameLESS_EQUAL;
1199                        if (test > 0) {
1200                            if (getNextChar('='))
1201                                return TokenNameLEFT_SHIFT_EQUAL;
1202                            return TokenNameLEFT_SHIFT;
1203                        }
1204                        return TokenNameLESS;
1205                    }
1206                case '>' :
1207                    {
1208                        int test;
1209                        if (this.returnOnlyGreater) {
1210                            return TokenNameGREATER;
1211                        }
1212                        if ((test = getNextChar('=', '>')) == 0)
1213                            return TokenNameGREATER_EQUAL;
1214                        if (test > 0) {
1215                            if ((test = getNextChar('=', '>')) == 0)
1216                                return TokenNameRIGHT_SHIFT_EQUAL;
1217                            if (test > 0) {
1218                                if (getNextChar('='))
1219                                    return TokenNameUNSIGNED_RIGHT_SHIFT_EQUAL;
1220                                return TokenNameUNSIGNED_RIGHT_SHIFT;
1221                            }
1222                            return TokenNameRIGHT_SHIFT;
1223                        }
1224                        return TokenNameGREATER;
1225                    }
1226                case '=' :
1227                    if (getNextChar('='))
1228                        return TokenNameEQUAL_EQUAL;
1229                    return TokenNameEQUAL;
1230                case '&' :
1231                    {
1232                        int test;
1233                        if ((test = getNextChar('&', '=')) == 0)
1234                            return TokenNameAND_AND;
1235                        if (test > 0)
1236                            return TokenNameAND_EQUAL;
1237                        return TokenNameAND;
1238                    }
1239                case '|' :
1240                    {
1241                        int test;
1242                        if ((test = getNextChar('|', '=')) == 0)
1243                            return TokenNameOR_OR;
1244                        if (test > 0)
1245                            return TokenNameOR_EQUAL;
1246                        return TokenNameOR;
1247                    }
1248                case '^' :
1249                    if (getNextChar('='))
1250                        return TokenNameXOR_EQUAL;
1251                    return TokenNameXOR;
1252                case '?' :
1253                    return TokenNameQUESTION;
1254                case ':' :
1255                    return TokenNameCOLON;
1256                case '\'' :
1257                    {
1258                        int test;
1259                        if ((test = getNextChar('\n', '\r')) == 0) {
1260                            throw new InvalidInputException(INVALID_CHARACTER_CONSTANT);
1261                        }
1262                        if (test > 0) {
1263                            // relocate if finding another quote fairly close: thus unicode '/u000D' will be fully consumed
1264
for (int lookAhead = 0; lookAhead < 3; lookAhead++) {
1265                                if (this.currentPosition + lookAhead == this.eofPosition)
1266                                    break;
1267                                if (this.source[this.currentPosition + lookAhead] == '\n')
1268                                    break;
1269                                if (this.source[this.currentPosition + lookAhead] == '\'') {
1270                                    this.currentPosition += lookAhead + 1;
1271                                    break;
1272                                }
1273                            }
1274                            throw new InvalidInputException(INVALID_CHARACTER_CONSTANT);
1275                        }
1276                    }
1277                    if (getNextChar('\'')) {
1278                        // relocate if finding another quote fairly close: thus unicode '/u000D' will be fully consumed
1279
for (int lookAhead = 0; lookAhead < 3; lookAhead++) {
1280                            if (this.currentPosition + lookAhead == this.eofPosition)
1281                                break;
1282                            if (this.source[this.currentPosition + lookAhead] == '\n')
1283                                break;
1284                            if (this.source[this.currentPosition + lookAhead] == '\'') {
1285                                this.currentPosition += lookAhead + 1;
1286                                break;
1287                            }
1288                        }
1289                        throw new InvalidInputException(INVALID_CHARACTER_CONSTANT);
1290                    }
1291                    if (getNextChar('\\')) {
1292                        if (this.unicodeAsBackSlash) {
1293                            // consume next character
1294
this.unicodeAsBackSlash = false;
1295                            if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\') && (this.source[this.currentPosition] == 'u')) {
1296                                getNextUnicodeChar();
1297                            } else {
1298                                if (this.withoutUnicodePtr != 0) {
1299                                    unicodeStore();
1300                                }
1301                            }
1302                        } else {
1303                            this.currentCharacter = this.source[this.currentPosition++];
1304                        }
1305                        scanEscapeCharacter();
1306                    } else { // consume next character
1307
this.unicodeAsBackSlash = false;
1308                        checkIfUnicode = false;
1309                        try {
1310                            checkIfUnicode = ((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
1311                            && (this.source[this.currentPosition] == 'u');
1312                        } catch(IndexOutOfBoundsException JavaDoc e) {
1313                            this.currentPosition--;
1314                            throw new InvalidInputException(INVALID_CHARACTER_CONSTANT);
1315                        }
1316                        if (checkIfUnicode) {
1317                            getNextUnicodeChar();
1318                        } else {
1319                            if (this.withoutUnicodePtr != 0) {
1320                                unicodeStore();
1321                            }
1322                        }
1323                    }
1324                    if (getNextChar('\''))
1325                        return TokenNameCharacterLiteral;
1326                    // relocate if finding another quote fairly close: thus unicode '/u000D' will be fully consumed
1327
for (int lookAhead = 0; lookAhead < 20; lookAhead++) {
1328                        if (this.currentPosition + lookAhead == this.eofPosition)
1329                            break;
1330                        if (this.source[this.currentPosition + lookAhead] == '\n')
1331                            break;
1332                        if (this.source[this.currentPosition + lookAhead] == '\'') {
1333                            this.currentPosition += lookAhead + 1;
1334                            break;
1335                        }
1336                    }
1337                    throw new InvalidInputException(INVALID_CHARACTER_CONSTANT);
1338                case '"' :
1339                    try {
1340                        // consume next character
1341
this.unicodeAsBackSlash = false;
1342                        boolean isUnicode = false;
1343                        if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
1344                            && (this.source[this.currentPosition] == 'u')) {
1345                            getNextUnicodeChar();
1346                            isUnicode = true;
1347                        } else {
1348                            if (this.withoutUnicodePtr != 0) {
1349                                unicodeStore();
1350                            }
1351                        }
1352
1353                        while (this.currentCharacter != '"') {
1354                            /**** \r and \n are not valid in string literals ****/
1355                            if ((this.currentCharacter == '\n') || (this.currentCharacter == '\r')) {
1356                                // relocate if finding another quote fairly close: thus unicode '/u000D' will be fully consumed
1357
if (isUnicode) {
1358                                    int start = this.currentPosition;
1359                                    for (int lookAhead = 0; lookAhead < 50; lookAhead++) {
1360                                        if (this.currentPosition >= this.eofPosition) {
1361                                            this.currentPosition = start;
1362                                            break;
1363                                        }
1364                                        if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\') && (this.source[this.currentPosition] == 'u')) {
1365                                            isUnicode = true;
1366                                            getNextUnicodeChar();
1367                                        } else {
1368                                            isUnicode = false;
1369                                        }
1370                                        if (!isUnicode && this.currentCharacter == '\n') {
1371                                            this.currentPosition--; // set current position on new line character
1372
break;
1373                                        }
1374                                        if (this.currentCharacter == '\"') {
1375                                            throw new InvalidInputException(INVALID_CHAR_IN_STRING);
1376                                        }
1377                                    }
1378                                } else {
1379                                    this.currentPosition--; // set current position on new line character
1380
}
1381                                throw new InvalidInputException(INVALID_CHAR_IN_STRING);
1382                            }
1383                            if (this.currentCharacter == '\\') {
1384                                if (this.unicodeAsBackSlash) {
1385                                    this.withoutUnicodePtr--;
1386                                    // consume next character
1387
this.unicodeAsBackSlash = false;
1388                                    if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\') && (this.source[this.currentPosition] == 'u')) {
1389                                        getNextUnicodeChar();
1390                                        isUnicode = true;
1391                                        this.withoutUnicodePtr--;
1392                                    } else {
1393                                        isUnicode = false;
1394                                    }
1395                                } else {
1396                                    if (this.withoutUnicodePtr == 0) {
1397                                        unicodeInitializeBuffer(this.currentPosition - this.startPosition);
1398                                    }
1399                                    this.withoutUnicodePtr --;
1400                                    this.currentCharacter = this.source[this.currentPosition++];
1401                                }
1402                                // we need to compute the escape character in a separate buffer
1403
scanEscapeCharacter();
1404                                if (this.withoutUnicodePtr != 0) {
1405                                    unicodeStore();
1406                                }
1407                            }
1408                            // consume next character
1409
this.unicodeAsBackSlash = false;
1410                            if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
1411                                && (this.source[this.currentPosition] == 'u')) {
1412                                getNextUnicodeChar();
1413                                isUnicode = true;
1414                            } else {
1415                                isUnicode = false;
1416                                if (this.withoutUnicodePtr != 0) {
1417                                    unicodeStore();
1418                                }
1419                            }
1420
1421                        }
1422                    } catch (IndexOutOfBoundsException JavaDoc e) {
1423                        this.currentPosition--;
1424                        throw new InvalidInputException(UNTERMINATED_STRING);
1425                    } catch (InvalidInputException e) {
1426                        if (e.getMessage().equals(INVALID_ESCAPE)) {
1427                            // relocate if finding another quote fairly close: thus unicode '/u000D' will be fully consumed
1428
for (int lookAhead = 0; lookAhead < 50; lookAhead++) {
1429                                if (this.currentPosition + lookAhead == this.eofPosition)
1430                                    break;
1431                                if (this.source[this.currentPosition + lookAhead] == '\n')
1432                                    break;
1433                                if (this.source[this.currentPosition + lookAhead] == '\"') {
1434                                    this.currentPosition += lookAhead + 1;
1435                                    break;
1436                                }
1437                            }
1438
1439                        }
1440                        throw e; // rethrow
1441
}
1442                    return TokenNameStringLiteral;
1443                case '/' :
1444                    {
1445                        int test;
1446                        if ((test = getNextChar('/', '*')) == 0) { //line comment
1447
this.lastCommentLinePosition = this.currentPosition;
1448                            try { //get the next char
1449
if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
1450                                        && (this.source[this.currentPosition] == 'u')) {
1451                                    getNextUnicodeChar();
1452                                }
1453
1454                                //handle the \\u case manually into comment
1455
if (this.currentCharacter == '\\') {
1456                                    if (this.source[this.currentPosition] == '\\')
1457                                        this.currentPosition++;
1458                                } //jump over the \\
1459
boolean isUnicode = false;
1460                                while (this.currentCharacter != '\r' && this.currentCharacter != '\n') {
1461                                    this.lastCommentLinePosition = this.currentPosition;
1462                                    //get the next char
1463
isUnicode = false;
1464                                    if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
1465                                            && (this.source[this.currentPosition] == 'u')) {
1466                                        getNextUnicodeChar();
1467                                        isUnicode = true;
1468                                    }
1469                                    //handle the \\u case manually into comment
1470
if (this.currentCharacter == '\\') {
1471                                        if (this.source[this.currentPosition] == '\\')
1472                                            this.currentPosition++;
1473                                    } //jump over the \\
1474
}
1475                                /*
1476                                 * We need to completely consume the line break
1477                                 */

1478                                if (this.currentCharacter == '\r'
1479                                   && this.eofPosition > this.currentPosition) {
1480                                    if (this.source[this.currentPosition] == '\n') {
1481                                        this.currentPosition++;
1482                                        this.currentCharacter = '\n';
1483                                    } else if ((this.source[this.currentPosition] == '\\')
1484                                        && (this.source[this.currentPosition + 1] == 'u')) {
1485                                        getNextUnicodeChar();
1486                                        isUnicode = true;
1487                                    }
1488                                }
1489                                recordComment(TokenNameCOMMENT_LINE);
1490                                if (this.taskTags != null) checkTaskTag(this.startPosition, this.currentPosition);
1491                                if ((this.currentCharacter == '\r') || (this.currentCharacter == '\n')) {
1492                                    if (this.checkNonExternalizedStringLiterals) {
1493                                        parseTags();
1494                                    }
1495                                    if (this.recordLineSeparator) {
1496                                        if (isUnicode) {
1497                                            pushUnicodeLineSeparator();
1498                                        } else {
1499                                            pushLineSeparator();
1500                                        }
1501                                    }
1502                                }
1503                                if (this.tokenizeComments) {
1504                                    return TokenNameCOMMENT_LINE;
1505                                }
1506                            } catch (IndexOutOfBoundsException JavaDoc e) {
1507                                this.currentPosition--;
1508                                recordComment(TokenNameCOMMENT_LINE);
1509                                if (this.taskTags != null) checkTaskTag(this.startPosition, this.currentPosition);
1510                                if (this.checkNonExternalizedStringLiterals) {
1511                                    parseTags();
1512                                }
1513                                if (this.tokenizeComments) {
1514                                    return TokenNameCOMMENT_LINE;
1515                                } else {
1516                                    this.currentPosition++;
1517                                }
1518                            }
1519                            break;
1520                        }
1521                        if (test > 0) { //traditional and javadoc comment
1522
try { //get the next char
1523
boolean isJavadoc = false, star = false;
1524                                boolean isUnicode = false;
1525                                int previous;
1526                                // consume next character
1527
this.unicodeAsBackSlash = false;
1528                                if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
1529                                    && (this.source[this.currentPosition] == 'u')) {
1530                                    getNextUnicodeChar();
1531                                    isUnicode = true;
1532                                } else {
1533                                    isUnicode = false;
1534                                    if (this.withoutUnicodePtr != 0) {
1535                                        unicodeStore();
1536                                    }
1537                                }
1538
1539                                if (this.currentCharacter == '*') {
1540                                    isJavadoc = true;
1541                                    star = true;
1542                                }
1543                                if ((this.currentCharacter == '\r') || (this.currentCharacter == '\n')) {
1544                                    if (this.recordLineSeparator) {
1545                                        if (isUnicode) {
1546                                            pushUnicodeLineSeparator();
1547                                        } else {
1548                                            pushLineSeparator();
1549                                        }
1550                                    }
1551                                }
1552                                isUnicode = false;
1553                                previous = this.currentPosition;
1554                                if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
1555                                    && (this.source[this.currentPosition] == 'u')) {
1556                                    //-------------unicode traitement ------------
1557
getNextUnicodeChar();
1558                                    isUnicode = true;
1559                                } else {
1560                                    isUnicode = false;
1561                                }
1562                                //handle the \\u case manually into comment
1563
if (this.currentCharacter == '\\') {
1564                                    if (this.source[this.currentPosition] == '\\')
1565                                        this.currentPosition++; //jump over the \\
1566
}
1567                                // empty comment is not a javadoc /**/
1568
if (this.currentCharacter == '/') {
1569                                    isJavadoc = false;
1570                                }
1571                                //loop until end of comment */
1572
int firstTag = 0;
1573                                while ((this.currentCharacter != '/') || (!star)) {
1574                                    if ((this.currentCharacter == '\r') || (this.currentCharacter == '\n')) {
1575                                        if (this.recordLineSeparator) {
1576                                            if (isUnicode) {
1577                                                pushUnicodeLineSeparator();
1578                                            } else {
1579                                                pushLineSeparator();
1580                                            }
1581                                        }
1582                                    }
1583                                    switch (this.currentCharacter) {
1584                                        case '*':
1585                                            star = true;
1586                                            break;
1587                                        case '@':
1588                                            if (firstTag == 0) {
1589                                                firstTag = previous;
1590                                            }
1591                                            // fall through default case to set star to false
1592
default:
1593                                            star = false;
1594                                    }
1595                                    //get next char
1596
previous = this.currentPosition;
1597                                    if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
1598                                        && (this.source[this.currentPosition] == 'u')) {
1599                                        //-------------unicode traitement ------------
1600
getNextUnicodeChar();
1601                                        isUnicode = true;
1602                                    } else {
1603                                        isUnicode = false;
1604                                    }
1605                                    //handle the \\u case manually into comment
1606
if (this.currentCharacter == '\\') {
1607                                        if (this.source[this.currentPosition] == '\\')
1608                                            this.currentPosition++;
1609                                    } //jump over the \\
1610
}
1611                                int token = isJavadoc ? TokenNameCOMMENT_JAVADOC : TokenNameCOMMENT_BLOCK;
1612                                recordComment(token);
1613                                this.commentTagStarts[this.commentPtr] = firstTag;
1614                                if (this.taskTags != null) checkTaskTag(this.startPosition, this.currentPosition);
1615                                if (this.tokenizeComments) {
1616                                    /*
1617                                    if (isJavadoc)
1618                                        return TokenNameCOMMENT_JAVADOC;
1619                                    return TokenNameCOMMENT_BLOCK;
1620                                    */

1621                                    return token;
1622                                }
1623                            } catch (IndexOutOfBoundsException JavaDoc e) {
1624                                this.currentPosition--;
1625                                throw new InvalidInputException(UNTERMINATED_COMMENT);
1626                            }
1627                            break;
1628                        }
1629                        if (getNextChar('='))
1630                            return TokenNameDIVIDE_EQUAL;
1631                        return TokenNameDIVIDE;
1632                    }
1633                case '\u001a' :
1634                    if (atEnd())
1635                        return TokenNameEOF;
1636                    //the atEnd may not be <currentPosition == source.length> if source is only some part of a real (external) stream
1637
throw new InvalidInputException("Ctrl-Z"); //$NON-NLS-1$
1638
default :
1639                    char c = this.currentCharacter;
1640                    if (c < ScannerHelper.MAX_OBVIOUS) {
1641                        if ((ScannerHelper.OBVIOUS_IDENT_CHAR_NATURES[c] & ScannerHelper.C_IDENT_START) != 0) {
1642                            return scanIdentifierOrKeyword();
1643                        } else if ((ScannerHelper.OBVIOUS_IDENT_CHAR_NATURES[c] & ScannerHelper.C_DIGIT) != 0) {
1644                                return scanNumber(false);
1645                        } else {
1646                            return TokenNameERROR;
1647                        }
1648                    }
1649                    boolean isJavaIdStart;
1650                    if (c >= HIGH_SURROGATE_MIN_VALUE && c <= HIGH_SURROGATE_MAX_VALUE) {
1651                        if (this.complianceLevel < ClassFileConstants.JDK1_5) {
1652                            throw new InvalidInputException(INVALID_UNICODE_ESCAPE);
1653                        }
1654                        // Unicode 4 detection
1655
char low = (char) getNextChar();
1656                        if (low < LOW_SURROGATE_MIN_VALUE || low > LOW_SURROGATE_MAX_VALUE) {
1657                            // illegal low surrogate
1658
throw new InvalidInputException(INVALID_LOW_SURROGATE);
1659                        }
1660                        isJavaIdStart = ScannerHelper.isJavaIdentifierStart(c, low);
1661                    }
1662                    else if (c >= LOW_SURROGATE_MIN_VALUE && c <= LOW_SURROGATE_MAX_VALUE) {
1663                        if (this.complianceLevel < ClassFileConstants.JDK1_5) {
1664                            throw new InvalidInputException(INVALID_UNICODE_ESCAPE);
1665                        }
1666                        throw new InvalidInputException(INVALID_HIGH_SURROGATE);
1667                    } else {
1668                        // optimized case already checked
1669
isJavaIdStart = Character.isJavaIdentifierStart(c);
1670                    }
1671                    if (isJavaIdStart)
1672                        return scanIdentifierOrKeyword();
1673                    if (ScannerHelper.isDigit(this.currentCharacter)) {
1674                        return scanNumber(false);
1675                    }
1676                    return TokenNameERROR;
1677            }
1678        }
1679    } //-----------------end switch while try--------------------
1680
catch (IndexOutOfBoundsException JavaDoc e) {
1681        if (this.tokenizeWhiteSpace && (whiteStart != this.currentPosition - 1)) {
1682            // reposition scanner in case we are interested by spaces as tokens
1683
this.currentPosition--;
1684            this.startPosition = whiteStart;
1685            return TokenNameWHITESPACE;
1686        }
1687    }
1688    return TokenNameEOF;
1689}
1690public void getNextUnicodeChar()
1691    throws InvalidInputException {
1692    //VOID
1693
//handle the case of unicode.
1694
//when a unicode appears then we must use a buffer that holds char internal values
1695
//At the end of this method currentCharacter holds the new visited char
1696
//and currentPosition points right next after it
1697

1698    //ALL getNextChar.... ARE OPTIMIZED COPIES
1699
int c1 = 0, c2 = 0, c3 = 0, c4 = 0, unicodeSize = 6;
1700    this.currentPosition++;
1701    if (this.currentPosition < this.eofPosition) {
1702        while (this.source[this.currentPosition] == 'u') {
1703            this.currentPosition++;
1704            if (this.currentPosition >= this.eofPosition) {
1705                this.currentPosition--;
1706                throw new InvalidInputException(INVALID_UNICODE_ESCAPE);
1707            }
1708            unicodeSize++;
1709        }
1710    } else {
1711        this.currentPosition--;
1712        throw new InvalidInputException(INVALID_UNICODE_ESCAPE);
1713    }
1714
1715    if ((this.currentPosition + 4) > this.eofPosition) {
1716        this.currentPosition += (this.eofPosition - this.currentPosition);
1717        throw new InvalidInputException(INVALID_UNICODE_ESCAPE);
1718    }
1719    if ((c1 = ScannerHelper.getNumericValue(this.source[this.currentPosition++])) > 15
1720            || c1 < 0
1721            || (c2 = ScannerHelper.getNumericValue(this.source[this.currentPosition++])) > 15
1722            || c2 < 0
1723            || (c3 = ScannerHelper.getNumericValue(this.source[this.currentPosition++])) > 15
1724            || c3 < 0
1725            || (c4 = ScannerHelper.getNumericValue(this.source[this.currentPosition++])) > 15
1726            || c4 < 0){
1727        throw new InvalidInputException(INVALID_UNICODE_ESCAPE);
1728    }
1729    this.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
1730    //need the unicode buffer
1731
if (this.withoutUnicodePtr == 0) {
1732        //buffer all the entries that have been left aside....
1733
unicodeInitializeBuffer(this.currentPosition - unicodeSize - this.startPosition);
1734    }
1735    //fill the buffer with the char
1736
unicodeStore();
1737    this.unicodeAsBackSlash = this.currentCharacter == '\\';
1738}
1739public NLSTag[] getNLSTags() {
1740    final int length = this.nlsTagsPtr;
1741    if (length != 0) {
1742        NLSTag[] result = new NLSTag[length];
1743        System.arraycopy(this.nlsTags, 0, result, 0, length);
1744        this.nlsTagsPtr = 0;
1745        return result;
1746    }
1747    return null;
1748}
1749public char[] getSource(){
1750    return this.source;
1751}
1752public final void jumpOverMethodBody() {
1753
1754    this.wasAcr = false;
1755    int found = 1;
1756    try {
1757        while (true) { //loop for jumping over comments
1758
this.withoutUnicodePtr = 0;
1759            // ---------Consume white space and handles startPosition---------
1760
boolean isWhiteSpace;
1761            do {
1762                this.startPosition = this.currentPosition;
1763                if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
1764                    && (this.source[this.currentPosition] == 'u')) {
1765                    isWhiteSpace = jumpOverUnicodeWhiteSpace();
1766                } else {
1767                    if (this.recordLineSeparator
1768                            && ((this.currentCharacter == '\r') || (this.currentCharacter == '\n'))) {
1769                        pushLineSeparator();
1770                    }
1771                    isWhiteSpace = CharOperation.isWhitespace(this.currentCharacter);
1772                }
1773            } while (isWhiteSpace);
1774
1775            // -------consume token until } is found---------
1776
NextToken: switch (this.currentCharacter) {
1777                case '{' :
1778                    found++;
1779                    break NextToken;
1780                case '}' :
1781                    found--;
1782                    if (found == 0)
1783                        return;
1784                    break NextToken;
1785                case '\'' :
1786                    {
1787                        boolean test;
1788                        test = getNextChar('\\');
1789                        if (test) {
1790                            try {
1791                                if (this.unicodeAsBackSlash) {
1792                                    // consume next character
1793
this.unicodeAsBackSlash = false;
1794                                    if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\') && (this.source[this.currentPosition] == 'u')) {
1795                                        getNextUnicodeChar();
1796                                    } else {
1797                                        if (this.withoutUnicodePtr != 0) {
1798                                            unicodeStore();
1799                                        }
1800                                    }
1801                                } else {
1802                                    this.currentCharacter = this.source[this.currentPosition++];
1803                                }
1804                                scanEscapeCharacter();
1805                            } catch (InvalidInputException ex) {
1806                                // ignore
1807
}
1808                        } else {
1809                            try { // consume next character
1810
this.unicodeAsBackSlash = false;
1811                                if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
1812                                        && (this.source[this.currentPosition] == 'u')) {
1813                                    getNextUnicodeChar();
1814                                } else {
1815                                    if (this.withoutUnicodePtr != 0) {
1816                                        unicodeStore();
1817                                    }
1818                                }
1819                            } catch (InvalidInputException ex) {
1820                                // ignore
1821
}
1822                        }
1823                        getNextChar('\'');
1824                        break NextToken;
1825                    }
1826                case '"' :
1827                    try {
1828                        try { // consume next character
1829
this.unicodeAsBackSlash = false;
1830                            if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
1831                                    && (this.source[this.currentPosition] == 'u')) {
1832                                getNextUnicodeChar();
1833                            } else {
1834                                if (this.withoutUnicodePtr != 0) {
1835                                    unicodeStore();
1836                                }
1837                            }
1838                        } catch (InvalidInputException ex) {
1839                                // ignore
1840
}
1841                        while (this.currentCharacter != '"') {
1842                            if (this.currentCharacter == '\r'){
1843                                if (this.source[this.currentPosition] == '\n') this.currentPosition++;
1844                                break NextToken; // the string cannot go further that the line
1845
}
1846                            if (this.currentCharacter == '\n'){
1847                                break; // the string cannot go further that the line
1848
}
1849                            if (this.currentCharacter == '\\') {
1850                                try {
1851                                    if (this.unicodeAsBackSlash) {
1852                                        // consume next character
1853
this.unicodeAsBackSlash = false;
1854                                        if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\') && (this.source[this.currentPosition] == 'u')) {
1855                                            getNextUnicodeChar();
1856                                        } else {
1857                                            if (this.withoutUnicodePtr != 0) {
1858                                                unicodeStore();
1859                                            }
1860                                        }
1861                                    } else {
1862                                        this.currentCharacter = this.source[this.currentPosition++];
1863                                    }
1864                                    scanEscapeCharacter();
1865                                } catch (InvalidInputException ex) {
1866                                    // ignore
1867
}
1868                            }
1869                            try { // consume next character
1870
this.unicodeAsBackSlash = false;
1871                                if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
1872                                        && (this.source[this.currentPosition] == 'u')) {
1873                                    getNextUnicodeChar();
1874                                } else {
1875                                    if (this.withoutUnicodePtr != 0) {
1876                                        unicodeStore();
1877                                    }
1878                                }
1879                            } catch (InvalidInputException ex) {
1880                                // ignore
1881
}
1882                        }
1883                    } catch (IndexOutOfBoundsException JavaDoc e) {
1884                        return;
1885                    }
1886                    break NextToken;
1887                case '/' :
1888                    {
1889                        int test;
1890                        if ((test = getNextChar('/', '*')) == 0) { //line comment
1891
try {
1892                                this.lastCommentLinePosition = this.currentPosition;
1893                                //get the next char
1894
if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
1895                                        && (this.source[this.currentPosition] == 'u')) {
1896                                    getNextUnicodeChar();
1897                                }
1898                                //handle the \\u case manually into comment
1899
if (this.currentCharacter == '\\') {
1900                                    if (this.source[this.currentPosition] == '\\')
1901                                        this.currentPosition++;
1902                                } //jump over the \\
1903
boolean isUnicode = false;
1904                                while (this.currentCharacter != '\r' && this.currentCharacter != '\n') {
1905                                    this.lastCommentLinePosition = this.currentPosition;
1906                                    //get the next char
1907
isUnicode = false;
1908                                    if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
1909                                            && (this.source[this.currentPosition] == 'u')) {
1910                                        isUnicode = true;
1911                                        getNextUnicodeChar();
1912                                    }
1913                                    //handle the \\u case manually into comment
1914
if (this.currentCharacter == '\\') {
1915                                        if (this.source[this.currentPosition] == '\\')
1916                                            this.currentPosition++;
1917                                    } //jump over the \\
1918
}
1919                                /*
1920                                 * We need to completely consume the line break
1921                                 */

1922                                if (this.currentCharacter == '\r'
1923                                   && this.eofPosition > this.currentPosition) {
1924                                    if (this.source[this.currentPosition] == '\n') {
1925                                        this.currentPosition++;
1926                                        this.currentCharacter = '\n';
1927                                    } else if ((this.source[this.currentPosition] == '\\')
1928                                            && (this.source[this.currentPosition + 1] == 'u')) {
1929                                        isUnicode = true;
1930                                        getNextUnicodeChar();
1931                                    }
1932                                }
1933                                recordComment(TokenNameCOMMENT_LINE);
1934                                if (this.recordLineSeparator
1935                                    && ((this.currentCharacter == '\r') || (this.currentCharacter == '\n'))) {
1936                                        if (this.checkNonExternalizedStringLiterals) {
1937                                            parseTags();
1938                                        }
1939                                        if (this.recordLineSeparator) {
1940                                            if (isUnicode) {
1941                                                pushUnicodeLineSeparator();
1942                                            } else {
1943                                                pushLineSeparator();
1944                                            }
1945                                        }
1946                                    }
1947                            } catch (IndexOutOfBoundsException JavaDoc e) {
1948                                 //an eof will then be generated
1949
this.currentPosition--;
1950                                recordComment(TokenNameCOMMENT_LINE);
1951                                if (this.checkNonExternalizedStringLiterals) {
1952                                    parseTags();
1953                                }
1954                                if (!this.tokenizeComments) {
1955                                    this.currentPosition++;
1956                                }
1957                            }
1958                            break NextToken;
1959                        }
1960                        if (test > 0) { //traditional and javadoc comment
1961
boolean isJavadoc = false;
1962                            try { //get the next char
1963
boolean star = false;
1964                                int previous;
1965                                boolean isUnicode = false;
1966                                // consume next character
1967
this.unicodeAsBackSlash = false;
1968                                if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
1969                                        && (this.source[this.currentPosition] == 'u')) {
1970                                    getNextUnicodeChar();
1971                                    isUnicode = true;
1972                                } else {
1973                                    isUnicode = false;
1974                                    if (this.withoutUnicodePtr != 0) {
1975                                        unicodeStore();
1976                                    }
1977                                }
1978    
1979                                if (this.currentCharacter == '*') {
1980                                    isJavadoc = true;
1981                                    star = true;
1982                                }
1983                                if ((this.currentCharacter == '\r') || (this.currentCharacter == '\n')) {
1984                                    if (this.recordLineSeparator) {
1985                                        if (isUnicode) {
1986                                            pushUnicodeLineSeparator();
1987                                        } else {
1988                                            pushLineSeparator();
1989                                        }
1990                                    }
1991                                }
1992                                isUnicode = false;
1993                                previous = this.currentPosition;
1994                                if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
1995                                        && (this.source[this.currentPosition] == 'u')) {
1996                                    getNextUnicodeChar();
1997                                    isUnicode = true;
1998                                } else {
1999                                    isUnicode = false;
2000                                }
2001                                //handle the \\u case manually into comment
2002
if (this.currentCharacter == '\\') {
2003                                    if (this.source[this.currentPosition] == '\\')
2004                                        this.currentPosition++; //jump over the \\
2005
}
2006                                // empty comment is not a javadoc /**/
2007
if (this.currentCharacter == '/') {
2008                                    isJavadoc = false;
2009                                }
2010                                //loop until end of comment */
2011
int firstTag = 0;
2012                                while ((this.currentCharacter != '/') || (!star)) {
2013                                    if ((this.currentCharacter == '\r') || (this.currentCharacter == '\n')) {
2014                                        if (this.recordLineSeparator) {
2015                                            if (isUnicode) {
2016                                                pushUnicodeLineSeparator();
2017                                            } else {
2018                                                pushLineSeparator();
2019                                            }
2020                                        }
2021                                    }
2022                                    switch (this.currentCharacter) {
2023                                        case '*':
2024                                            star = true;
2025                                            break;
2026                                        case '@':
2027                                            if (firstTag == 0) {
2028                                                firstTag = previous;
2029                                            }
2030                                            // fall through default case to set star to false
2031
default:
2032                                            star = false;
2033                                    }
2034                                    //get next char
2035
previous = this.currentPosition;
2036                                    if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
2037                                            && (this.source[this.currentPosition] == 'u')) {
2038                                        getNextUnicodeChar();
2039                                        isUnicode = true;
2040                                    } else {
2041                                        isUnicode = false;
2042                                    }
2043                                    //handle the \\u case manually into comment
2044
if (this.currentCharacter == '\\') {
2045                                        if (this.source[this.currentPosition] == '\\')
2046                                            this.currentPosition++;
2047                                    } //jump over the \\
2048
}
2049                                recordComment(isJavadoc ? TokenNameCOMMENT_JAVADOC : TokenNameCOMMENT_BLOCK);
2050                                this.commentTagStarts[this.commentPtr] = firstTag;
2051                            } catch (IndexOutOfBoundsException JavaDoc e) {
2052                                return;
2053                            }
2054                            break NextToken;
2055                        }
2056                        break NextToken;
2057                    }
2058
2059                default :
2060                    try {
2061                        char c = this.currentCharacter;
2062                        if (c < ScannerHelper.MAX_OBVIOUS) {
2063                            if ((ScannerHelper.OBVIOUS_IDENT_CHAR_NATURES[c] & ScannerHelper.C_IDENT_START) != 0) {
2064                                scanIdentifierOrKeyword();
2065                                break NextToken;
2066                            } else if ((ScannerHelper.OBVIOUS_IDENT_CHAR_NATURES[c] & ScannerHelper.C_DIGIT) != 0) {
2067                                scanNumber(false);
2068                                break NextToken;
2069                            } else {
2070                                break NextToken;
2071                            }
2072                        }
2073                        boolean isJavaIdStart;
2074                        if (c >= HIGH_SURROGATE_MIN_VALUE && c <= HIGH_SURROGATE_MAX_VALUE) {
2075                            if (this.complianceLevel < ClassFileConstants.JDK1_5) {
2076                                throw new InvalidInputException(INVALID_UNICODE_ESCAPE);
2077                            }
2078                            // Unicode 4 detection
2079
char low = (char) getNextChar();
2080                            if (low < LOW_SURROGATE_MIN_VALUE || low > LOW_SURROGATE_MAX_VALUE) {
2081                                // illegal low surrogate
2082
break NextToken;
2083                            }
2084                            isJavaIdStart = ScannerHelper.isJavaIdentifierStart(c, low);
2085                        } else if (c >= LOW_SURROGATE_MIN_VALUE && c <= LOW_SURROGATE_MAX_VALUE) {
2086                            break NextToken;
2087                        } else {
2088                            // optimized case already checked
2089
isJavaIdStart = Character.isJavaIdentifierStart(c);
2090                        }
2091                        if (isJavaIdStart) {
2092                            scanIdentifierOrKeyword();
2093                            break NextToken;
2094                        }
2095// if (ScannerHelper.isDigit(this.currentCharacter)) {
2096
// scanNumber(false);
2097
// break NextToken;
2098
// }
2099
} catch (InvalidInputException ex) {
2100                        // ignore
2101
}
2102            }
2103        }
2104        //-----------------end switch while try--------------------
2105
} catch (IndexOutOfBoundsException JavaDoc e) {
2106        // ignore
2107
} catch (InvalidInputException e) {
2108        // ignore
2109
}
2110    return;
2111}
2112public final boolean jumpOverUnicodeWhiteSpace() throws InvalidInputException {
2113    //BOOLEAN
2114
//handle the case of unicode. Jump over the next whiteSpace
2115
//making startPosition pointing on the next available char
2116
//On false, the currentCharacter is filled up with a potential
2117
//correct char
2118

2119    this.wasAcr = false;
2120    getNextUnicodeChar();
2121    return CharOperation.isWhitespace(this.currentCharacter);
2122}
2123
2124final char[] optimizedCurrentTokenSource1() {
2125    //return always the same char[] build only once
2126

2127    //optimization at no speed cost of 99.5 % of the singleCharIdentifier
2128
char charOne = this.source[this.startPosition];
2129    switch (charOne) {
2130        case 'a' :
2131            return charArray_a;
2132        case 'b' :
2133            return charArray_b;
2134        case 'c' :
2135            return charArray_c;
2136        case 'd' :
2137            return charArray_d;
2138        case 'e' :
2139            return charArray_e;
2140        case 'f' :
2141            return charArray_f;
2142        case 'g' :
2143            return charArray_g;
2144        case 'h' :
2145            return charArray_h;
2146        case 'i' :
2147            return charArray_i;
2148        case 'j' :
2149            return charArray_j;
2150        case 'k' :
2151            return charArray_k;
2152        case 'l' :
2153            return charArray_l;
2154        case 'm' :
2155            return charArray_m;
2156        case 'n' :
2157            return charArray_n;
2158        case 'o' :
2159            return charArray_o;
2160        case 'p' :
2161            return charArray_p;
2162        case 'q' :
2163            return charArray_q;
2164        case 'r' :
2165            return charArray_r;
2166        case 's' :
2167            return charArray_s;
2168        case 't' :
2169            return charArray_t;
2170        case 'u' :
2171            return charArray_u;
2172        case 'v' :
2173            return charArray_v;
2174        case 'w' :
2175            return charArray_w;
2176        case 'x' :
2177            return charArray_x;
2178        case 'y' :
2179            return charArray_y;
2180        case 'z' :
2181            return charArray_z;
2182        default :
2183            return new char[] {charOne};
2184    }
2185}
2186final char[] optimizedCurrentTokenSource2() {
2187    //try to return the same char[] build only once
2188

2189    char[] src = this.source;
2190    int start = this.startPosition;
2191    char c0 , c1;
2192    int hash = (((c0=src[start]) << 6) + (c1=src[start+1])) % TableSize;
2193    char[][] table = this.charArray_length[0][hash];
2194    int i = newEntry2;
2195    while (++i < InternalTableSize) {
2196        char[] charArray = table[i];
2197        if ((c0 == charArray[0]) && (c1 == charArray[1]))
2198            return charArray;
2199    }
2200    //---------other side---------
2201
i = -1;
2202    int max = newEntry2;
2203    while (++i <= max) {
2204        char[] charArray = table[i];
2205        if ((c0 == charArray[0]) && (c1 == charArray[1]))
2206            return charArray;
2207    }
2208    //--------add the entry-------
2209
if (++max >= InternalTableSize) max = 0;
2210    char[] r;
2211    System.arraycopy(src, start, r= new char[2], 0, 2);
2212    //newIdentCount++;
2213
return table[newEntry2 = max] = r; //(r = new char[] {c0, c1});
2214
}
2215final char[] optimizedCurrentTokenSource3() {
2216    //try to return the same char[] build only once
2217

2218    char[] src = this.source;
2219    int start = this.startPosition;
2220    char c0, c1=src[start+1], c2;
2221    int hash = (((c0=src[start])<< 6) + (c2=src[start+2])) % TableSize;
2222// int hash = ((c0 << 12) + (c1<< 6) + c2) % TableSize;
2223
char[][] table = this.charArray_length[1][hash];
2224    int i = newEntry3;
2225    while (++i < InternalTableSize) {
2226        char[] charArray = table[i];
2227        if ((c0 == charArray[0]) && (c1 == charArray[1]) && (c2 == charArray[2]))
2228            return charArray;
2229    }
2230    //---------other side---------
2231
i = -1;
2232    int max = newEntry3;
2233    while (++i <= max) {
2234        char[] charArray = table[i];
2235        if ((c0 == charArray[0]) && (c1 == charArray[1]) && (c2 == charArray[2]))
2236            return charArray;
2237    }
2238    //--------add the entry-------
2239
if (++max >= InternalTableSize) max = 0;
2240    char[] r;
2241    System.arraycopy(src, start, r= new char[3], 0, 3);
2242    //newIdentCount++;
2243
return table[newEntry3 = max] = r; //(r = new char[] {c0, c1, c2});
2244
}
2245final char[] optimizedCurrentTokenSource4() {
2246    //try to return the same char[] build only once
2247

2248    char[] src = this.source;
2249    int start = this.startPosition;
2250    char c0, c1 = src[start+1], c2, c3 = src[start+3];
2251    int hash = (((c0=src[start]) << 6) + (c2=src[start+2])) % TableSize;
2252// int hash = (int) (((((long) c0) << 18) + (c1 << 12) + (c2 << 6) + c3) % TableSize);
2253
char[][] table = this.charArray_length[2][hash];
2254    int i = newEntry4;
2255    while (++i < InternalTableSize) {
2256        char[] charArray = table[i];
2257        if ((c0 == charArray[0])
2258            && (c1 == charArray[1])
2259            && (c2 == charArray[2])
2260            && (c3 == charArray[3]))
2261            return charArray;
2262    }
2263    //---------other side---------
2264
i = -1;
2265    int max = newEntry4;
2266    while (++i <= max) {
2267        char[] charArray = table[i];
2268        if ((c0 == charArray[0])
2269            && (c1 == charArray[1])
2270            && (c2 == charArray[2])
2271            && (c3 == charArray[3]))
2272            return charArray;
2273    }
2274    //--------add the entry-------
2275
if (++max >= InternalTableSize) max = 0;
2276    char[] r;
2277    System.arraycopy(src, start, r= new char[4], 0, 4);
2278    //newIdentCount++;
2279
return table[newEntry4 = max] = r; //(r = new char[] {c0, c1, c2, c3});
2280
}
2281final char[] optimizedCurrentTokenSource5() {
2282    //try to return the same char[] build only once
2283

2284    char[] src = this.source;
2285    int start = this.startPosition;
2286    char c0, c1 = src[start+1], c2, c3 = src[start+3], c4;
2287    int hash = (((c0=src[start]) << 12) +((c2=src[start+2]) << 6) + (c4=src[start+4])) % TableSize;
2288// int hash = (int) (((((long) c0) << 24) + (((long) c1) << 18) + (c2 << 12) + (c3 << 6) + c4) % TableSize);
2289
char[][] table = this.charArray_length[3][hash];
2290    int i = newEntry5;
2291    while (++i < InternalTableSize) {
2292        char[] charArray = table[i];
2293        if ((c0 == charArray[0])
2294            && (c1 == charArray[1])
2295            && (c2 == charArray[2])
2296            && (c3 == charArray[3])
2297            && (c4 == charArray[4]))
2298            return charArray;
2299    }
2300    //---------other side---------
2301
i = -1;
2302    int max = newEntry5;
2303    while (++i <= max) {
2304        char[] charArray = table[i];
2305        if ((c0 == charArray[0])
2306            && (c1 == charArray[1])
2307            && (c2 == charArray[2])
2308            && (c3 == charArray[3])
2309            && (c4 == charArray[4]))
2310            return charArray;
2311    }
2312    //--------add the entry-------
2313
if (++max >= InternalTableSize) max = 0;
2314    char[] r;
2315    System.arraycopy(src, start, r= new char[5], 0, 5);
2316    //newIdentCount++;
2317
return table[newEntry5 = max] = r; //(r = new char[] {c0, c1, c2, c3, c4});
2318
}
2319final char[] optimizedCurrentTokenSource6() {
2320    //try to return the same char[] build only once
2321

2322    char[] src = this.source;
2323    int start = this.startPosition;
2324    char c0, c1 = src[start+1], c2, c3 = src[start+3], c4, c5 = src[start+5];
2325    int hash = (((c0=src[start]) << 12) +((c2=src[start+2]) << 6) + (c4=src[start+4])) % TableSize;
2326// int hash = (int)(((((long) c0) << 32) + (((long) c1) << 24) + (((long) c2) << 18) + (c3 << 12) + (c4 << 6) + c5) % TableSize);
2327
char[][] table = this.charArray_length[4][hash];
2328    int i = newEntry6;
2329    while (++i < InternalTableSize) {
2330        char[] charArray = table[i];
2331        if ((c0 == charArray[0])
2332            && (c1 == charArray[1])
2333            && (c2 == charArray[2])
2334            && (c3 == charArray[3])
2335            && (c4 == charArray[4])
2336            && (c5 == charArray[5]))
2337            return charArray;
2338    }
2339    //---------other side---------
2340
i = -1;
2341    int max = newEntry6;
2342    while (++i <= max) {
2343        char[] charArray = table[i];
2344        if ((c0 == charArray[0])
2345            && (c1 == charArray[1])
2346            && (c2 == charArray[2])
2347            && (c3 == charArray[3])
2348            && (c4 == charArray[4])
2349            && (c5 == charArray[5]))
2350            return charArray;
2351    }
2352    //--------add the entry-------
2353
if (++max >= InternalTableSize) max = 0;
2354    char[] r;
2355    System.arraycopy(src, start, r= new char[6], 0, 6);
2356    //newIdentCount++;
2357
return table[newEntry6 = max] = r; //(r = new char[] {c0, c1, c2, c3, c4, c5});
2358
}
2359
2360private void parseTags() {
2361    int position = 0;
2362    final int currentStartPosition = this.startPosition;
2363    final int currentLinePtr = this.linePtr;
2364    if (currentLinePtr >= 0) {
2365        position = this.lineEnds[currentLinePtr] + 1;
2366    }
2367    while (ScannerHelper.isWhitespace(this.source[position])) {
2368        position++;
2369    }
2370    if (currentStartPosition == position) {
2371        // the whole line is commented out
2372
return;
2373    }
2374    char[] s = null;
2375    int sourceEnd = this.currentPosition;
2376    int sourceStart = currentStartPosition;
2377    int sourceDelta = 0;
2378    if (this.withoutUnicodePtr != 0) {
2379        // 0 is used as a fast test flag so the real first char is in position 1
2380
System.arraycopy(
2381            this.withoutUnicodeBuffer,
2382            1,
2383            s = new char[this.withoutUnicodePtr],
2384            0,
2385            this.withoutUnicodePtr);
2386        sourceEnd = this.withoutUnicodePtr;
2387        sourceStart = 1;
2388        sourceDelta = currentStartPosition;
2389    } else {
2390        s = this.source;
2391    }
2392    int pos = CharOperation.indexOf(TAG_PREFIX, s, true, sourceStart, sourceEnd);
2393    if (pos != -1) {
2394        if (this.nlsTags == null) {
2395            this.nlsTags = new NLSTag[10];
2396            this.nlsTagsPtr = 0;
2397        }
2398        while (pos != -1) {
2399            int start = pos + TAG_PREFIX_LENGTH;
2400            int end = CharOperation.indexOf(TAG_POSTFIX, s, start, sourceEnd);
2401            if (end != -1) {
2402                NLSTag currentTag = null;
2403                final int currentLine = currentLinePtr + 1;
2404                try {
2405                    currentTag = new NLSTag(pos + sourceDelta, end + sourceDelta, currentLine, extractInt(s, start, end));
2406                } catch (NumberFormatException JavaDoc e) {
2407                    currentTag = new NLSTag(pos + sourceDelta, end + sourceDelta, currentLine, -1);
2408                }
2409                if (this.nlsTagsPtr == this.nlsTags.length) {
2410                    // resize
2411
System.arraycopy(this.nlsTags, 0, (this.nlsTags = new NLSTag[this.nlsTagsPtr + 10]), 0, this.nlsTagsPtr);
2412                }
2413                this.nlsTags[this.nlsTagsPtr++] = currentTag;
2414            } else {
2415                end = start;
2416            }
2417            pos = CharOperation.indexOf(TAG_PREFIX, s, true, end, sourceEnd);
2418        }
2419    }
2420}
2421private int extractInt(char[] array, int start, int end) {
2422    int value = 0;
2423    for (int i = start; i < end; i++) {
2424        final char currentChar = array[i];
2425        int digit = 0;
2426        switch(currentChar) {
2427            case '0' :
2428                digit = 0;
2429                break;
2430            case '1' :
2431                digit = 1;
2432                break;
2433            case '2' :
2434                digit = 2;
2435                break;
2436            case '3' :
2437                digit = 3;
2438                break;
2439            case '4' :
2440                digit = 4;
2441                break;
2442            case '5' :
2443                digit = 5;
2444                break;
2445            case '6' :
2446                digit = 6;
2447                break;
2448            case '7' :
2449                digit = 7;
2450                break;
2451            case '8' :
2452                digit = 8;
2453                break;
2454            case '9' :
2455                digit = 9;
2456                break;
2457            default :
2458                throw new NumberFormatException JavaDoc();
2459        }
2460        value *= 10;
2461        if (digit < 0) throw new NumberFormatException JavaDoc();
2462        value += digit;
2463    }
2464    return value;
2465}
2466public final void pushLineSeparator() {
2467    //see comment on isLineDelimiter(char) for the use of '\n' and '\r'
2468
final int INCREMENT = 250;
2469    //currentCharacter is at position currentPosition-1
2470
// cr 000D
2471
if (this.currentCharacter == '\r') {
2472        int separatorPos = this.currentPosition - 1;
2473        if ((this.linePtr >= 0) && (this.lineEnds[this.linePtr] >= separatorPos)) return;
2474        int length = this.lineEnds.length;
2475        if (++this.linePtr >= length)
2476            System.arraycopy(this.lineEnds, 0, this.lineEnds = new int[length + INCREMENT], 0, length);
2477        this.lineEnds[this.linePtr] = separatorPos;
2478        // look-ahead for merged cr+lf
2479
try {
2480            if (this.source[this.currentPosition] == '\n') {
2481                //System.out.println("look-ahead LF-" + this.currentPosition);
2482
this.lineEnds[this.linePtr] = this.currentPosition;
2483                this.currentPosition++;
2484                this.wasAcr = false;
2485            } else {
2486                this.wasAcr = true;
2487            }
2488        } catch(IndexOutOfBoundsException JavaDoc e) {
2489            this.wasAcr = true;
2490        }
2491    } else {
2492        // lf 000A
2493
if (this.currentCharacter == '\n') { //must merge eventual cr followed by lf
2494
if (this.wasAcr && (this.lineEnds[this.linePtr] == (this.currentPosition - 2))) {
2495                //System.out.println("merge LF-" + (this.currentPosition - 1));
2496
this.lineEnds[this.linePtr] = this.currentPosition - 1;
2497            } else {
2498                int separatorPos = this.currentPosition - 1;
2499                if ((this.linePtr >= 0) && (this.lineEnds[this.linePtr] >= separatorPos)) return;
2500                int length = this.lineEnds.length;
2501                if (++this.linePtr >= length)
2502                    System.arraycopy(this.lineEnds, 0, this.lineEnds = new int[length + INCREMENT], 0, length);
2503                this.lineEnds[this.linePtr] = separatorPos;
2504            }
2505            this.wasAcr = false;
2506        }
2507    }
2508}
2509public final void pushUnicodeLineSeparator() {
2510    // cr 000D
2511
if (this.currentCharacter == '\r') {
2512        if (this.source[this.currentPosition] == '\n') {
2513            this.wasAcr = false;
2514        } else {
2515            this.wasAcr = true;
2516        }
2517    } else {
2518        // lf 000A
2519
if (this.currentCharacter == '\n') { //must merge eventual cr followed by lf
2520
this.wasAcr = false;
2521        }
2522    }
2523}
2524
2525public void recordComment(int token) {
2526    // compute position
2527
int stopPosition = this.currentPosition;
2528    switch (token) {
2529        case TokenNameCOMMENT_LINE:
2530            stopPosition = -this.lastCommentLinePosition;
2531            break;
2532        case TokenNameCOMMENT_BLOCK:
2533            stopPosition = -this.currentPosition;
2534            break;
2535    }
2536
2537    // a new comment is recorded
2538
int length = this.commentStops.length;
2539    if (++this.commentPtr >= length) {
2540        int newLength = length + COMMENT_ARRAYS_SIZE*10;
2541        System.arraycopy(this.commentStops, 0, this.commentStops = new int[newLength], 0, length);
2542        System.arraycopy(this.commentStarts, 0, this.commentStarts = new int[newLength], 0, length);
2543        System.arraycopy(this.commentTagStarts, 0, this.commentTagStarts = new int[newLength], 0, length);
2544    }
2545    this.commentStops[this.commentPtr] = stopPosition;
2546    this.commentStarts[this.commentPtr] = this.startPosition;
2547}
2548
2549/**
2550 * Reposition the scanner on some portion of the original source. The given endPosition is the last valid position.
2551 * Beyond this position, the scanner will answer EOF tokens (<code>ITerminalSymbols.TokenNameEOF</code>).
2552 *
2553 * @param begin the given start position
2554 * @param end the given end position
2555 */

2556public void resetTo(int begin, int end) {
2557    //reset the scanner to a given position where it may rescan again
2558

2559    this.diet = false;
2560    this.initialPosition = this.startPosition = this.currentPosition = begin;
2561    if (this.source != null && this.source.length < end) {
2562        this.eofPosition = this.source.length;
2563    } else {
2564        this.eofPosition = end < Integer.MAX_VALUE ? end + 1 : end;
2565    }
2566    this.commentPtr = -1; // reset comment stack
2567
this.foundTaskCount = 0;
2568}
2569
2570public final void scanEscapeCharacter() throws InvalidInputException {
2571    // the string with "\\u" is a legal string of two chars \ and u
2572
//thus we use a direct access to the source (for regular cases).
2573
switch (this.currentCharacter) {
2574        case 'b' :
2575            this.currentCharacter = '\b';
2576            break;
2577        case 't' :
2578            this.currentCharacter = '\t';
2579            break;
2580        case 'n' :
2581            this.currentCharacter = '\n';
2582            break;
2583        case 'f' :
2584            this.currentCharacter = '\f';
2585            break;
2586        case 'r' :
2587            this.currentCharacter = '\r';
2588            break;
2589        case '\"' :
2590            this.currentCharacter = '\"';
2591            break;
2592        case '\'' :
2593            this.currentCharacter = '\'';
2594            break;
2595        case '\\' :
2596            this.currentCharacter = '\\';
2597            break;
2598        default :
2599            // -----------octal escape--------------
2600
// OctalDigit
2601
// OctalDigit OctalDigit
2602
// ZeroToThree OctalDigit OctalDigit
2603

2604            int number = ScannerHelper.getNumericValue(this.currentCharacter);
2605            if (number >= 0 && number <= 7) {
2606                boolean zeroToThreeNot = number > 3;
2607                if (ScannerHelper.isDigit(this.currentCharacter = this.source[this.currentPosition++])) {
2608                    int digit = ScannerHelper.getNumericValue(this.currentCharacter);
2609                    if (digit >= 0 && digit <= 7) {
2610                        number = (number * 8) + digit;
2611                        if (ScannerHelper.isDigit(this.currentCharacter = this.source[this.currentPosition++])) {
2612                            if (zeroToThreeNot) {// has read \NotZeroToThree OctalDigit Digit --> ignore last character
2613
this.currentPosition--;
2614                            } else {
2615                                digit = ScannerHelper.getNumericValue(this.currentCharacter);
2616                                if (digit >= 0 && digit <= 7){ // has read \ZeroToThree OctalDigit OctalDigit
2617
number = (number * 8) + digit;
2618                                } else {// has read \ZeroToThree OctalDigit NonOctalDigit --> ignore last character
2619
this.currentPosition--;
2620                                }
2621                            }
2622                        } else { // has read \OctalDigit NonDigit--> ignore last character
2623
this.currentPosition--;
2624                        }
2625                    } else { // has read \OctalDigit NonOctalDigit--> ignore last character
2626
this.currentPosition--;
2627                    }
2628                } else { // has read \OctalDigit --> ignore last character
2629
this.currentPosition--;
2630                }
2631                if (number > 255)
2632                    throw new InvalidInputException(INVALID_ESCAPE);
2633                this.currentCharacter = (char) number;
2634            } else
2635                throw new InvalidInputException(INVALID_ESCAPE);
2636    }
2637}
2638public int scanIdentifierOrKeywordWithBoundCheck() {
2639    //test keywords
2640

2641    //first dispatch on the first char.
2642
//then the length. If there are several
2643
//keywors with the same length AND the same first char, then do another
2644
//dispatch on the second char
2645
this.useAssertAsAnIndentifier = false;
2646    this.useEnumAsAnIndentifier = false;
2647
2648    char[] src = this.source;
2649    identLoop: {
2650        int pos;
2651        int srcLength = this.eofPosition;
2652        while (true) {
2653            if ((pos = this.currentPosition) >= srcLength) // handle the obvious case upfront
2654
break identLoop;
2655            char c = src[pos];
2656            if (c < ScannerHelper.MAX_OBVIOUS) {
2657                if ((ScannerHelper.OBVIOUS_IDENT_CHAR_NATURES[c] &
2658                        (ScannerHelper.C_UPPER_LETTER | ScannerHelper.C_LOWER_LETTER | ScannerHelper.C_IDENT_PART | ScannerHelper.C_DIGIT)) != 0) {
2659                       if (this.withoutUnicodePtr != 0) {
2660                            this.currentCharacter = c;
2661                            unicodeStore();
2662                        }
2663                        this.currentPosition++;
2664                } else if ((ScannerHelper.OBVIOUS_IDENT_CHAR_NATURES[c] & (ScannerHelper.C_SEPARATOR | ScannerHelper.C_JLS_SPACE)) != 0) {
2665                        this.currentCharacter = c;
2666                        break identLoop;
2667                } else {
2668                    //System.out.println("slow<=128: "+ c);
2669
while (getNextCharAsJavaIdentifierPartWithBoundCheck()){/*empty*/}
2670                    break identLoop;
2671                }
2672            } else {
2673                //System.out.println("slow>>128: "+ c);
2674
while (getNextCharAsJavaIdentifierPartWithBoundCheck()){/*empty*/}
2675                break identLoop;
2676            }
2677        }
2678    }
2679    
2680    int index, length;
2681    char[] data;
2682    if (this.withoutUnicodePtr == 0) {
2683        //quick test on length == 1 but not on length > 12 while most identifier
2684
//have a length which is <= 12...but there are lots of identifier with
2685
//only one char....
2686
if ((length = this.currentPosition - this.startPosition) == 1) {
2687            return TokenNameIdentifier;
2688        }
2689        data = this.source;
2690        index = this.startPosition;
2691    } else {
2692        if ((length = this.withoutUnicodePtr) == 1)
2693            return TokenNameIdentifier;
2694        data = this.withoutUnicodeBuffer;
2695        index = 1;
2696    }
2697
2698    return internalScanIdentifierOrKeyword(index, length, data);
2699}
2700public int scanIdentifierOrKeyword() {
2701    //test keywords
2702

2703    //first dispatch on the first char.
2704
//then the length. If there are several
2705
//keywors with the same length AND the same first char, then do another
2706
//dispatch on the second char
2707
this.useAssertAsAnIndentifier = false;
2708    this.useEnumAsAnIndentifier = false;
2709
2710    char[] src = this.source;
2711    identLoop: {
2712        int pos;
2713        int srcLength = this.eofPosition;
2714        while (true) {
2715            if ((pos = this.currentPosition) >= srcLength) // handle the obvious case upfront
2716
break identLoop;
2717            char c = src[pos];
2718            if (c < ScannerHelper.MAX_OBVIOUS) {
2719                if ((ScannerHelper.OBVIOUS_IDENT_CHAR_NATURES[c] &
2720                        (ScannerHelper.C_UPPER_LETTER | ScannerHelper.C_LOWER_LETTER | ScannerHelper.C_IDENT_PART | ScannerHelper.C_DIGIT)) != 0) {
2721                       if (this.withoutUnicodePtr != 0) {
2722                            this.currentCharacter = c;
2723                            unicodeStore();
2724                        }
2725                        this.currentPosition++;
2726                } else if ((ScannerHelper.OBVIOUS_IDENT_CHAR_NATURES[c] & (ScannerHelper.C_SEPARATOR | ScannerHelper.C_JLS_SPACE)) != 0) {
2727                        this.currentCharacter = c;
2728                        break identLoop;
2729                } else {
2730                    //System.out.println("slow<=128: "+ c);
2731
while (getNextCharAsJavaIdentifierPart()){/*empty*/}
2732                    break identLoop;
2733                }
2734            } else {
2735                //System.out.println("slow>>128: "+ c);
2736
while (getNextCharAsJavaIdentifierPart()){/*empty*/}
2737                break identLoop;
2738            }
2739        }
2740    }
2741    
2742    int index, length;
2743    char[] data;
2744    if (this.withoutUnicodePtr == 0) {
2745        //quick test on length == 1 but not on length > 12 while most identifier
2746
//have a length which is <= 12...but there are lots of identifier with
2747
//only one char....
2748
if ((length = this.currentPosition - this.startPosition) == 1) {
2749            return TokenNameIdentifier;
2750        }
2751        data = this.source;
2752        index = this.startPosition;
2753    } else {
2754        if ((length = this.withoutUnicodePtr) == 1)
2755            return TokenNameIdentifier;
2756        data = this.withoutUnicodeBuffer;
2757        index = 1;
2758    }
2759
2760    return internalScanIdentifierOrKeyword(index, length, data);
2761}
2762
2763private int internalScanIdentifierOrKeyword(int index, int length, char[] data) {
2764    switch (data[index]) {
2765        case 'a' :
2766            switch(length) {
2767                case 8: //abstract
2768
if ((data[++index] == 'b')
2769                        && (data[++index] == 's')
2770                        && (data[++index] == 't')
2771                        && (data[++index] == 'r')
2772                        && (data[++index] == 'a')
2773                        && (data[++index] == 'c')
2774                        && (data[++index] == 't')) {
2775                            return TokenNameabstract;
2776                        } else {
2777                            return TokenNameIdentifier;
2778                        }
2779                case 6: // assert
2780
if ((data[++index] == 's')
2781                        && (data[++index] == 's')
2782                        && (data[++index] == 'e')
2783                        && (data[++index] == 'r')
2784                        && (data[++index] == 't')) {
2785                            if (this.sourceLevel >= ClassFileConstants.JDK1_4) {
2786                                this.containsAssertKeyword = true;
2787                                return TokenNameassert;
2788                            } else {
2789                                this.useAssertAsAnIndentifier = true;
2790                                return TokenNameIdentifier;
2791                            }
2792                        } else {
2793                            return TokenNameIdentifier;
2794                        }
2795                default:
2796                    return TokenNameIdentifier;
2797            }
2798        case 'b' : //boolean break byte
2799
switch (length) {
2800                case 4 :
2801                    if ((data[++index] == 'y') && (data[++index] == 't') && (data[++index] == 'e'))
2802                        return TokenNamebyte;
2803                    else
2804                        return TokenNameIdentifier;
2805                case 5 :
2806                    if ((data[++index] == 'r')
2807                        && (data[++index] == 'e')
2808                        && (data[++index] == 'a')
2809                        && (data[++index] == 'k'))
2810                        return TokenNamebreak;
2811                    else
2812                        return TokenNameIdentifier;
2813                case 7 :
2814                    if ((data[++index] == 'o')
2815                        && (data[++index] == 'o')
2816                        && (data[++index] == 'l')
2817                        && (data[++index] == 'e')
2818                        && (data[++index] == 'a')
2819                        && (data[++index] == 'n'))
2820                        return TokenNameboolean;
2821                    else
2822                        return TokenNameIdentifier;
2823                default :
2824                    return TokenNameIdentifier;
2825            }
2826
2827        case 'c' : //case char catch const class continue
2828
switch (length) {
2829                case 4 :
2830                    if (data[++index] == 'a')
2831                        if ((data[++index] == 's') && (data[++index] == 'e'))
2832                            return TokenNamecase;
2833                        else
2834                            return TokenNameIdentifier;
2835                    else
2836                        if ((data[index] == 'h') && (data[++index] == 'a') && (data[++index] == 'r'))
2837                            return TokenNamechar;
2838                        else
2839                            return TokenNameIdentifier;
2840                case 5 :
2841                    if (data[++index] == 'a')
2842                        if ((data[++index] == 't') && (data[++index] == 'c') && (data[++index] == 'h'))
2843                            return TokenNamecatch;
2844                        else
2845                            return TokenNameIdentifier;
2846                    else
2847                        if (data[index] == 'l')
2848                            if ((data[++index] == 'a')
2849                                && (data[++index] == 's')
2850                                && (data[++index] == 's'))
2851                                return TokenNameclass;
2852                            else
2853                                return TokenNameIdentifier;
2854                        else if ((data[index] == 'o')
2855                            && (data[++index] == 'n')
2856                            && (data[++index] == 's')
2857                            && (data[++index] == 't'))
2858                            return TokenNameconst; //const is not used in java ???????
2859
else
2860                            return TokenNameIdentifier;
2861                case 8 :
2862                    if ((data[++index] == 'o')
2863                        && (data[++index] == 'n')
2864                        && (data[++index] == 't')
2865                        && (data[++index] == 'i')
2866                        && (data[++index] == 'n')
2867                        && (data[++index] == 'u')
2868                        && (data[++index] == 'e'))
2869                        return TokenNamecontinue;
2870                    else
2871                        return TokenNameIdentifier;
2872                default :
2873                    return TokenNameIdentifier;
2874            }
2875
2876        case 'd' : //default do double
2877
switch (length) {
2878                case 2 :
2879                    if ((data[++index] == 'o'))
2880                        return TokenNamedo;
2881                    else
2882                        return TokenNameIdentifier;
2883                case 6 :
2884                    if ((data[++index] == 'o')
2885                        && (data[++index] == 'u')
2886                        && (data[++index] == 'b')
2887                        && (data[++index] == 'l')
2888                        && (data[++index] == 'e'))
2889                        return TokenNamedouble;
2890                    else
2891                        return TokenNameIdentifier;
2892                case 7 :
2893                    if ((data[++index] == 'e')
2894                        && (data[++index] == 'f')
2895                        && (data[++index] == 'a')
2896                        && (data[++index] == 'u')
2897                        && (data[++index] == 'l')
2898                        && (data[++index] == 't'))
2899                        return TokenNamedefault;
2900                    else
2901                        return TokenNameIdentifier;
2902                default :
2903                    return TokenNameIdentifier;
2904            }
2905        case 'e' : //else extends
2906
switch (length) {
2907                case 4 :
2908                    if ((data[++index] == 'l') && (data[++index] == 's') && (data[++index] == 'e'))
2909                        return TokenNameelse;
2910                    else if ((data[index] == 'n')
2911                        && (data[++index] == 'u')
2912                        && (data[++index] == 'm')) {
2913                            if (this.sourceLevel >= ClassFileConstants.JDK1_5) {
2914                                return TokenNameenum;
2915                            } else {
2916                                this.useEnumAsAnIndentifier = true;
2917                                return TokenNameIdentifier;
2918                            }
2919                        } else {
2920                            return TokenNameIdentifier;
2921                        }
2922                case 7 :
2923                    if ((data[++index] == 'x')
2924                        && (data[++index] == 't')
2925                        && (data[++index] == 'e')
2926                        && (data[++index] == 'n')
2927                        && (data[++index] == 'd')
2928                        && (data[++index] == 's'))
2929                        return TokenNameextends;
2930                    else
2931                        return TokenNameIdentifier;
2932                default :
2933                    return TokenNameIdentifier;
2934            }
2935
2936        case 'f' : //final finally float for false
2937
switch (length) {
2938                case 3 :
2939                    if ((data[++index] == 'o') && (data[++index] == 'r'))
2940                        return TokenNamefor;
2941                    else
2942                        return TokenNameIdentifier;
2943                case 5 :
2944                    if (data[++index] == 'i')
2945                        if ((data[++index] == 'n')
2946                            && (data[++index] == 'a')
2947                            && (data[++index] == 'l')) {
2948                            return TokenNamefinal;
2949                        } else
2950                            return TokenNameIdentifier;
2951                    else
2952                        if (data[index] == 'l')
2953                            if ((data[++index] == 'o')
2954                                && (data[++index] == 'a')
2955                                && (data[++index] == 't'))
2956                                return TokenNamefloat;
2957                            else
2958                                return TokenNameIdentifier;
2959                        else
2960                            if ((data[index] == 'a')
2961                                && (data[++index] == 'l')
2962                                && (data[++index] == 's')
2963                                && (data[++index] == 'e'))
2964                                return TokenNamefalse;
2965                            else
2966                                return TokenNameIdentifier;
2967                case 7 :
2968                    if ((data[++index] == 'i')
2969                        && (data[++index] == 'n')
2970                        && (data[++index] == 'a')
2971                        && (data[++index] == 'l')
2972                        && (data[++index] == 'l')
2973                        && (data[++index] == 'y'))
2974                        return TokenNamefinally;
2975                    else
2976                        return TokenNameIdentifier;
2977
2978                default :
2979                    return TokenNameIdentifier;
2980            }
2981        case 'g' : //goto
2982
if (length == 4) {
2983                if ((data[++index] == 'o')
2984                    && (data[++index] == 't')
2985                    && (data[++index] == 'o')) {
2986                    return TokenNamegoto;
2987                }
2988            } //no goto in java are allowed, so why java removes this keyword ???
2989
return TokenNameIdentifier;
2990
2991        case 'i' : //if implements import instanceof int interface
2992
switch (length) {
2993                case 2 :
2994                    if (data[++index] == 'f')
2995                        return TokenNameif;
2996                    else
2997                        return TokenNameIdentifier;
2998                case 3 :
2999                    if ((data[++index] == 'n') && (data[++index] == 't'))
3000                        return TokenNameint;
3001                    else
3002                        return TokenNameIdentifier;
3003                case 6 :
3004                    if ((data[++index] == 'm')
3005                        && (data[++index] == 'p')
3006                        && (data[++index] == 'o')
3007                        && (data[++index] == 'r')
3008                        && (data[++index] == 't'))
3009                        return TokenNameimport;
3010                    else
3011                        return TokenNameIdentifier;
3012                case 9 :
3013                    if ((data[++index] == 'n')
3014                        && (data[++index] == 't')
3015                        && (data[++index] == 'e')
3016                        && (data[++index] == 'r')
3017                        && (data[++index] == 'f')
3018                        && (data[++index] == 'a')
3019                        && (data[++index] == 'c')
3020                        && (data[++index] == 'e'))
3021                        return TokenNameinterface;
3022                    else
3023                        return TokenNameIdentifier;
3024                case 10 :
3025                    if (data[++index] == 'm')
3026                        if ((data[++index] == 'p')
3027                            && (data[++index] == 'l')
3028                            && (data[++index] == 'e')
3029                            && (data[++index] == 'm')
3030                            && (data[++index] == 'e')
3031                            && (data[++index] == 'n')
3032                            && (data[++index] == 't')
3033                            && (data[++index] == 's'))
3034                            return TokenNameimplements;
3035                        else
3036                            return TokenNameIdentifier;
3037                    else
3038                        if ((data[index] == 'n')
3039                            && (data[++index] == 's')
3040                            && (data[++index] == 't')
3041                            && (data[++index] == 'a')
3042                            && (data[++index] == 'n')
3043                            && (data[++index] == 'c')
3044                            && (data[++index] == 'e')
3045                            && (data[++index] == 'o')
3046                            && (data[++index] == 'f'))
3047                            return TokenNameinstanceof;
3048                        else
3049                            return TokenNameIdentifier;
3050
3051                default :
3052                    return TokenNameIdentifier;
3053            }
3054
3055        case 'l' : //long
3056
if (length == 4) {
3057                if ((data[++index] == 'o')
3058                    && (data[++index] == 'n')
3059                    && (data[++index] == 'g')) {
3060                    return TokenNamelong;
3061                }
3062            }
3063            return TokenNameIdentifier;
3064
3065        case 'n' : //native new null
3066
switch (length) {
3067                case 3 :
3068                    if ((data[++index] == 'e') && (data[++index] == 'w'))
3069                        return TokenNamenew;
3070                    else
3071                        return TokenNameIdentifier;
3072                case 4 :
3073                    if ((data[++index] == 'u') && (data[++index] == 'l') && (data[++index] == 'l'))
3074                        return TokenNamenull;
3075                    else
3076                        return TokenNameIdentifier;
3077                case 6 :
3078                    if ((data[++index] == 'a')
3079                        && (data[++index] == 't')
3080                        && (data[++index] == 'i')
3081                        && (data[++index] == 'v')
3082                        && (data[++index] == 'e')) {
3083                        return TokenNamenative;
3084                    } else
3085                        return TokenNameIdentifier;
3086                default :
3087                    return TokenNameIdentifier;
3088            }
3089
3090        case 'p' : //package private protected public
3091
switch (length) {
3092                case 6 :
3093                    if ((data[++index] == 'u')
3094                        && (data[++index] == 'b')
3095                        && (data[++index] == 'l')
3096                        && (data[++index] == 'i')
3097                        && (data[++index] == 'c')) {
3098                        return TokenNamepublic;
3099                    } else
3100                        return TokenNameIdentifier;
3101                case 7 :
3102                    if (data[++index] == 'a')
3103                        if ((data[++index] == 'c')
3104                            && (data[++index] == 'k')
3105                            && (data[++index] == 'a')
3106                            && (data[++index] == 'g')
3107                            && (data[++index] == 'e'))
3108                            return TokenNamepackage;
3109                        else
3110                            return TokenNameIdentifier;
3111                    else
3112                        if ((data[index] == 'r')
3113                            && (data[++index] == 'i')
3114                            && (data[++index] == 'v')
3115                            && (data[++index] == 'a')
3116                            && (data[++index] == 't')
3117                            && (data[++index] == 'e')) {
3118                            return TokenNameprivate;
3119                        } else
3120                            return TokenNameIdentifier;
3121                case 9 :
3122                    if ((data[++index] == 'r')
3123                        && (data[++index] == 'o')
3124                        && (data[++index] == 't')
3125                        && (data[++index] == 'e')
3126                        && (data[++index] == 'c')
3127                        && (data[++index] == 't')
3128                        && (data[++index] == 'e')
3129                        && (data[++index] == 'd')) {
3130                        return TokenNameprotected;
3131                    } else
3132                        return TokenNameIdentifier;
3133
3134                default :
3135                    return TokenNameIdentifier;
3136            }
3137
3138        case 'r' : //return
3139
if (length == 6) {
3140                if ((data[++index] == 'e')
3141                    && (data[++index] == 't')
3142                    && (data[++index] == 'u')
3143                    && (data[++index] == 'r')
3144                    && (data[++index] == 'n')) {
3145                    return TokenNamereturn;
3146                }
3147            }
3148            return TokenNameIdentifier;
3149
3150        case 's' : //short static super switch synchronized strictfp
3151
switch (length) {
3152                case 5 :
3153                    if (data[++index] == 'h')
3154                        if ((data[++index] == 'o') && (data[++index] == 'r') && (data[++index] == 't'))
3155                            return TokenNameshort;
3156                        else
3157                            return TokenNameIdentifier;
3158                    else
3159                        if ((data[index] == 'u')
3160                            && (data[++index] == 'p')
3161                            && (data[++index] == 'e')
3162                            && (data[++index] == 'r'))
3163                            return TokenNamesuper;
3164                        else
3165                            return TokenNameIdentifier;
3166
3167                case 6 :
3168                    if (data[++index] == 't')
3169                        if ((data[++index] == 'a')
3170                            && (data[++index] == 't')
3171                            && (data[++index] == 'i')
3172                            && (data[++index] == 'c')) {
3173                            return TokenNamestatic;
3174                        } else
3175                            return TokenNameIdentifier;
3176                    else
3177                        if ((data[index] == 'w')
3178                            && (data[++index] == 'i')
3179                            && (data[++index] == 't')
3180                            && (data[++index] == 'c')
3181                            && (data[++index] == 'h'))
3182                            return TokenNameswitch;
3183                        else
3184                            return TokenNameIdentifier;
3185                case 8 :
3186                    if ((data[++index] == 't')
3187                        && (data[++index] == 'r')
3188                        && (data[++index] == 'i')
3189                        && (data[++index] == 'c')
3190                        && (data[++index] == 't')
3191                        && (data[++index] == 'f')
3192                        && (data[++index] == 'p'))
3193                        return TokenNamestrictfp;
3194                    else
3195                        return TokenNameIdentifier;
3196                case 12 :
3197                    if ((data[++index] == 'y')
3198                        && (data[++index] == 'n')
3199                        && (data[++index] == 'c')
3200                        && (data[++index] == 'h')
3201                        && (data[++index] == 'r')
3202                        && (data[++index] == 'o')
3203                        && (data[++index] == 'n')
3204                        && (data[++index] == 'i')
3205                        && (data[++index] == 'z')
3206                        && (data[++index] == 'e')
3207                        && (data[++index] == 'd')) {
3208                        return TokenNamesynchronized;
3209                    } else
3210                        return TokenNameIdentifier;
3211                default :
3212                    return TokenNameIdentifier;
3213            }
3214
3215        case 't' : //try throw throws transient this true
3216
switch (length) {
3217                case 3 :
3218                    if ((data[++index] == 'r') && (data[++index] == 'y'))
3219                        return TokenNametry;
3220                    else
3221                        return TokenNameIdentifier;
3222                case 4 :
3223                    if (data[++index] == 'h')
3224                        if ((data[++index] == 'i') && (data[++index] == 's'))
3225                            return TokenNamethis;
3226                        else
3227                            return TokenNameIdentifier;
3228                    else
3229                        if ((data[index] == 'r') && (data[++index] == 'u') && (data[++index] == 'e'))
3230                            return TokenNametrue;
3231                        else
3232                            return TokenNameIdentifier;
3233                case 5 :
3234                    if ((data[++index] == 'h')
3235                        && (data[++index] == 'r')
3236                        && (data[++index] == 'o')
3237                        && (data[++index] == 'w'))
3238                        return TokenNamethrow;
3239                    else
3240                        return TokenNameIdentifier;
3241                case 6 :
3242                    if ((data[++index] == 'h')
3243                        && (data[++index] == 'r')
3244                        && (data[++index] == 'o')
3245                        && (data[++index] == 'w')
3246                        && (data[++index] == 's'))
3247                        return TokenNamethrows;
3248                    else
3249                        return TokenNameIdentifier;
3250                case 9 :
3251                    if ((data[++index] == 'r')
3252                        && (data[++index] == 'a')
3253                        && (data[++index] == 'n')
3254                        && (data[++index] == 's')
3255                        && (data[++index] == 'i')
3256                        && (data[++index] == 'e')
3257                        && (data[++index] == 'n')
3258                        && (data[++index] == 't')) {
3259                        return TokenNametransient;
3260                    } else
3261                        return TokenNameIdentifier;
3262
3263                default :
3264                    return TokenNameIdentifier;
3265            }
3266
3267        case 'v' : //void volatile
3268
switch (length) {
3269                case 4 :
3270                    if ((data[++index] == 'o') && (data[++index] == 'i') && (data[++index] == 'd'))
3271                        return TokenNamevoid;
3272                    else
3273                        return TokenNameIdentifier;
3274                case 8 :
3275                    if ((data[++index] == 'o')
3276                        && (data[++index] == 'l')
3277                        && (data[++index] == 'a')
3278                        && (data[++index] == 't')
3279                        && (data[++index] == 'i')
3280                        && (data[++index] == 'l')
3281                        && (data[++index] == 'e')) {
3282                        return TokenNamevolatile;
3283                    } else
3284                        return TokenNameIdentifier;
3285
3286                default :
3287                    return TokenNameIdentifier;
3288            }
3289
3290        case 'w' : //while widefp
3291
switch (length) {
3292                case 5 :
3293                    if ((data[++index] == 'h')
3294                        && (data[++index] == 'i')
3295                        && (data[++index] == 'l')
3296                        && (data[++index] == 'e'))
3297                        return TokenNamewhile;
3298                    else
3299                        return TokenNameIdentifier;
3300                    //case 6:if ( (data[++index] =='i') && (data[++index]=='d') && (data[++index]=='e') && (data[++index]=='f')&& (data[++index]=='p'))
3301
//return TokenNamewidefp ;
3302
//else
3303
//return TokenNameIdentifier;
3304
default :
3305                    return TokenNameIdentifier;
3306            }
3307
3308        default :
3309            return TokenNameIdentifier;
3310    }
3311}
3312
3313
3314public int scanNumber(boolean dotPrefix) throws InvalidInputException {
3315
3316    //when entering this method the currentCharacter is the first
3317
//digit of the number. It may be preceeded by a '.' when
3318
//dotPrefix is true
3319

3320    boolean floating = dotPrefix;
3321    if ((!dotPrefix) && (this.currentCharacter == '0')) {
3322        if (getNextChar('x', 'X') >= 0) { //----------hexa-----------------
3323
int start = this.currentPosition;
3324            while (getNextCharAsDigit(16)){/*empty*/}
3325            int end = this.currentPosition;
3326            if (getNextChar('l', 'L') >= 0) {
3327                if (end == start) {
3328                    throw new InvalidInputException(INVALID_HEXA);
3329                }
3330                return TokenNameLongLiteral;
3331            } else if (getNextChar('.')) {
3332                if (this.sourceLevel < ClassFileConstants.JDK1_5) {
3333                    if (end == start) {
3334                        throw new InvalidInputException(INVALID_HEXA);
3335                    }
3336                    this.currentPosition = end;
3337                    return TokenNameIntegerLiteral;
3338                }
3339                // hexadecimal floating point literal
3340
// read decimal part
3341
boolean hasNoDigitsBeforeDot = end == start;
3342                start = this.currentPosition;
3343                while (getNextCharAsDigit(16)){/*empty*/}
3344                end = this.currentPosition;
3345                if (hasNoDigitsBeforeDot && end == start) {
3346                    throw new InvalidInputException(INVALID_HEXA);
3347                }
3348                
3349                if (getNextChar('p', 'P') >= 0) { // consume next character
3350
this.unicodeAsBackSlash = false;
3351                    if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
3352                        && (this.source[this.currentPosition] == 'u')) {
3353                        getNextUnicodeChar();
3354                    } else {
3355                        if (this.withoutUnicodePtr != 0) {
3356                            unicodeStore();
3357                        }
3358                    }
3359
3360                    if ((this.currentCharacter == '-')
3361                        || (this.currentCharacter == '+')) { // consume next character
3362
this.unicodeAsBackSlash = false;
3363                        if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
3364                            && (this.source[this.currentPosition] == 'u')) {
3365                            getNextUnicodeChar();
3366                        } else {
3367                            if (this.withoutUnicodePtr != 0) {
3368                                unicodeStore();
3369                            }
3370                        }
3371                    }
3372                    if (!ScannerHelper.isDigit(this.currentCharacter)) {
3373                        throw new InvalidInputException(INVALID_HEXA);
3374                    }
3375                    while (getNextCharAsDigit()){/*empty*/}
3376                    if (getNextChar('f', 'F') >= 0) {
3377                        return TokenNameFloatingPointLiteral;
3378                    }
3379                    if (getNextChar('d', 'D') >= 0) {
3380                        return TokenNameDoubleLiteral;
3381                    }
3382                    if (getNextChar('l', 'L') >= 0) {
3383                        throw new InvalidInputException(INVALID_HEXA);
3384                    }
3385                    return TokenNameDoubleLiteral;
3386                } else {
3387                    throw new InvalidInputException(INVALID_HEXA);
3388                }
3389            } else if (getNextChar('p', 'P') >= 0) { // consume next character
3390
if (this.sourceLevel < ClassFileConstants.JDK1_5) {
3391                    // if we are in source level < 1.5 we report an integer literal
3392
this.currentPosition = end;
3393                    return TokenNameIntegerLiteral;
3394                }
3395                this.unicodeAsBackSlash = false;
3396                if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
3397                    && (this.source[this.currentPosition] == 'u')) {
3398                    getNextUnicodeChar();
3399                } else {
3400                    if (this.withoutUnicodePtr != 0) {
3401                        unicodeStore();
3402                    }
3403                }
3404
3405                if ((this.currentCharacter == '-')
3406                    || (this.currentCharacter == '+')) { // consume next character
3407
this.unicodeAsBackSlash = false;
3408                    if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
3409                        && (this.source[this.currentPosition] == 'u')) {
3410                        getNextUnicodeChar();
3411                    } else {
3412                        if (this.withoutUnicodePtr != 0) {
3413                            unicodeStore();
3414                        }
3415                    }
3416                }
3417                if (!ScannerHelper.isDigit(this.currentCharacter))
3418                    throw new InvalidInputException(INVALID_FLOAT);
3419                while (getNextCharAsDigit()){/*empty*/}
3420                if (getNextChar('f', 'F') >= 0)
3421                    return TokenNameFloatingPointLiteral;
3422                if (getNextChar('d', 'D') >= 0)
3423                    return TokenNameDoubleLiteral;
3424                if (getNextChar('l', 'L') >= 0) {
3425                    throw new InvalidInputException(INVALID_HEXA);
3426                }
3427                return TokenNameDoubleLiteral;
3428            } else {
3429                if (end == start)
3430                    throw new InvalidInputException(INVALID_HEXA);
3431                return TokenNameIntegerLiteral;
3432            }
3433        }
3434
3435        //there is x or X in the number
3436
//potential octal ! ... some one may write 000099.0 ! thus 00100 < 00078.0 is true !!!!! crazy language
3437
if (getNextCharAsDigit()) { //-------------potential octal-----------------
3438
while (getNextCharAsDigit()){/*empty*/}
3439
3440            if (getNextChar('l', 'L') >= 0) {
3441                return TokenNameLongLiteral;
3442            }
3443
3444            if (getNextChar('f', 'F') >= 0) {
3445                return TokenNameFloatingPointLiteral;
3446            }
3447
3448            if (getNextChar('d', 'D') >= 0) {
3449                return TokenNameDoubleLiteral;
3450            } else { //make the distinction between octal and float ....
3451
boolean isInteger = true;
3452                if (getNextChar('.')) {
3453                    isInteger = false;
3454                    while (getNextCharAsDigit()){/*empty*/}
3455                }
3456                if (getNextChar('e', 'E') >= 0) { // consume next character
3457
isInteger = false;
3458                    this.unicodeAsBackSlash = false;
3459                    if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
3460                        && (this.source[this.currentPosition] == 'u')) {
3461                        getNextUnicodeChar();
3462                    } else {
3463                        if (this.withoutUnicodePtr != 0) {
3464                            unicodeStore();
3465                        }
3466                    }
3467
3468                    if ((this.currentCharacter == '-')
3469                        || (this.currentCharacter == '+')) { // consume next character
3470
this.unicodeAsBackSlash = false;
3471                        if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
3472                            && (this.source[this.currentPosition] == 'u')) {
3473                            getNextUnicodeChar();
3474                        } else {
3475                            if (this.withoutUnicodePtr != 0) {
3476                                unicodeStore();
3477                            }
3478                        }
3479                    }
3480                    if (!ScannerHelper.isDigit(this.currentCharacter))
3481                        throw new InvalidInputException(INVALID_FLOAT);
3482                    while (getNextCharAsDigit()){/*empty*/}
3483                }
3484                if (getNextChar('f', 'F') >= 0)
3485                    return TokenNameFloatingPointLiteral;
3486                if (getNextChar('d', 'D') >= 0 || !isInteger)
3487                    return TokenNameDoubleLiteral;
3488                return TokenNameIntegerLiteral;
3489            }
3490        } else {
3491            /* carry on */
3492        }
3493    }
3494
3495    while (getNextCharAsDigit()){/*empty*/}
3496
3497    if ((!dotPrefix) && (getNextChar('l', 'L') >= 0))
3498        return TokenNameLongLiteral;
3499
3500    if ((!dotPrefix) && (getNextChar('.'))) { //decimal part that can be empty
3501
while (getNextCharAsDigit()){/*empty*/}
3502        floating = true;
3503    }
3504
3505    //if floating is true both exponant and suffix may be optional
3506

3507    if (getNextChar('e', 'E') >= 0) {
3508        floating = true;
3509        // consume next character
3510
this.unicodeAsBackSlash = false;
3511        if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
3512            && (this.source[this.currentPosition] == 'u')) {
3513            getNextUnicodeChar();
3514        } else {
3515            if (this.withoutUnicodePtr != 0) {
3516                unicodeStore();
3517            }
3518        }
3519
3520        if ((this.currentCharacter == '-')
3521            || (this.currentCharacter == '+')) { // consume next character
3522
this.unicodeAsBackSlash = false;
3523            if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
3524                && (this.source[this.currentPosition] == 'u')) {
3525                getNextUnicodeChar();
3526            } else {
3527                if (this.withoutUnicodePtr != 0) {
3528                    unicodeStore();
3529                }
3530            }
3531        }
3532        if (!ScannerHelper.isDigit(this.currentCharacter))
3533            throw new InvalidInputException(INVALID_FLOAT);
3534        while (getNextCharAsDigit()){/*empty*/}
3535    }
3536
3537    if (getNextChar('d', 'D') >= 0)
3538        return TokenNameDoubleLiteral;
3539    if (getNextChar('f', 'F') >= 0)
3540        return TokenNameFloatingPointLiteral;
3541
3542    //the long flag has been tested before
3543

3544    return floating ? TokenNameDoubleLiteral : TokenNameIntegerLiteral;
3545}
3546
3547/**
3548 * Search the line number corresponding to a specific position
3549 * @param position int
3550 * @return int
3551 */

3552public final int getLineNumber(int position) {
3553    return Util.getLineNumber(position, this.lineEnds, 0, this.linePtr);
3554}
3555public final void setSource(char[] sourceString){
3556    //the source-buffer is set to sourceString
3557

3558    int sourceLength;
3559    if (sourceString == null) {
3560        this.source = CharOperation.NO_CHAR;
3561        sourceLength = 0;
3562    } else {
3563        this.source = sourceString;
3564        sourceLength = sourceString.length;
3565    }
3566    this.startPosition = -1;
3567    this.eofPosition = sourceLength;
3568    this.initialPosition = this.currentPosition = 0;
3569    this.containsAssertKeyword = false;
3570    this.linePtr = -1;
3571}
3572/*
3573 * Should be used if a parse (usually a diet parse) has already been performed on the unit,
3574 * so as to get the already computed line end positions.
3575 */

3576public final void setSource(char[] contents, CompilationResult compilationResult) {
3577    if (contents == null) {
3578        char[] cuContents = compilationResult.compilationUnit.getContents();
3579        setSource(cuContents);
3580    } else {
3581        setSource(contents);
3582    }
3583    int[] lineSeparatorPositions = compilationResult.lineSeparatorPositions;
3584    if (lineSeparatorPositions != null) {
3585        this.lineEnds = lineSeparatorPositions;
3586        this.linePtr = lineSeparatorPositions.length - 1;
3587    }
3588}
3589/*
3590 * Should be used if a parse (usually a diet parse) has already been performed on the unit,
3591 * so as to get the already computed line end positions.
3592 */

3593public final void setSource(CompilationResult compilationResult) {
3594    setSource(null, compilationResult);
3595}
3596public String JavaDoc toString() {
3597    if (this.startPosition == this.eofPosition)
3598        return "EOF\n\n" + new String JavaDoc(this.source); //$NON-NLS-1$
3599
if (this.currentPosition > this.eofPosition)
3600        return "behind the EOF\n\n" + new String JavaDoc(this.source); //$NON-NLS-1$
3601

3602    char front[] = new char[this.startPosition];
3603    System.arraycopy(this.source, 0, front, 0, this.startPosition);
3604
3605    int middleLength = (this.currentPosition - 1) - this.startPosition + 1;
3606    char middle[];
3607    if (middleLength > -1) {
3608        middle = new char[middleLength];
3609        System.arraycopy(
3610            this.source,
3611            this.startPosition,
3612            middle,
3613            0,
3614            middleLength);
3615    } else {
3616        middle = CharOperation.NO_CHAR;
3617    }
3618    
3619    char end[] = new char[this.eofPosition - (this.currentPosition - 1)];
3620    System.arraycopy(
3621        this.source,
3622        (this.currentPosition - 1) + 1,
3623        end,
3624        0,
3625        this.eofPosition - (this.currentPosition - 1) - 1);
3626    
3627    return new String JavaDoc(front)
3628        + "\n===============================\nStarts here -->" //$NON-NLS-1$
3629
+ new String JavaDoc(middle)
3630        + "<-- Ends here\n===============================\n" //$NON-NLS-1$
3631
+ new String JavaDoc(end);
3632}
3633public String JavaDoc toStringAction(int act) {
3634    switch (act) {
3635        case TokenNameIdentifier :
3636            return "Identifier(" + new String JavaDoc(getCurrentTokenSource()) + ")"; //$NON-NLS-1$ //$NON-NLS-2$
3637
case TokenNameabstract :
3638            return "abstract"; //$NON-NLS-1$
3639
case TokenNameboolean :
3640            return "boolean"; //$NON-NLS-1$
3641
case TokenNamebreak :
3642            return "break"; //$NON-NLS-1$
3643
case TokenNamebyte :
3644            return "byte"; //$NON-NLS-1$
3645
case TokenNamecase :
3646            return "case"; //$NON-NLS-1$
3647
case TokenNamecatch :
3648            return "catch"; //$NON-NLS-1$
3649
case TokenNamechar :
3650            return "char"; //$NON-NLS-1$
3651
case TokenNameclass :
3652            return "class"; //$NON-NLS-1$
3653
case TokenNamecontinue :
3654            return "continue"; //$NON-NLS-1$
3655
case TokenNamedefault :
3656            return "default"; //$NON-NLS-1$
3657
case TokenNamedo :
3658            return "do"; //$NON-NLS-1$
3659
case TokenNamedouble :
3660            return "double"; //$NON-NLS-1$
3661
case TokenNameelse :
3662            return "else"; //$NON-NLS-1$
3663
case TokenNameextends :
3664            return "extends"; //$NON-NLS-1$
3665
case TokenNamefalse :
3666            return "false"; //$NON-NLS-1$
3667
case TokenNamefinal :
3668            return "final"; //$NON-NLS-1$
3669
case TokenNamefinally :
3670            return "finally"; //$NON-NLS-1$
3671
case TokenNamefloat :
3672            return "float"; //$NON-NLS-1$
3673
case TokenNamefor :
3674            return "for"; //$NON-NLS-1$
3675
case TokenNameif :
3676            return "if"; //$NON-NLS-1$
3677
case TokenNameimplements :
3678            return "implements"; //$NON-NLS-1$
3679
case TokenNameimport :
3680            return "import"; //$NON-NLS-1$
3681
case TokenNameinstanceof :
3682            return "instanceof"; //$NON-NLS-1$
3683
case TokenNameint :
3684            return "int"; //$NON-NLS-1$
3685
case TokenNameinterface :
3686            return "interface"; //$NON-NLS-1$
3687
case TokenNamelong :
3688            return "long"; //$NON-NLS-1$
3689
case TokenNamenative :
3690            return "native"; //$NON-NLS-1$
3691
case TokenNamenew :
3692            return "new"; //$NON-NLS-1$
3693
case TokenNamenull :
3694            return "null"; //$NON-NLS-1$
3695
case TokenNamepackage :
3696            return "package"; //$NON-NLS-1$
3697
case TokenNameprivate :
3698            return "private"; //$NON-NLS-1$
3699
case TokenNameprotected :
3700            return "protected"; //$NON-NLS-1$
3701
case TokenNamepublic :
3702            return "public"; //$NON-NLS-1$
3703
case TokenNamereturn :
3704            return "return"; //$NON-NLS-1$
3705
case TokenNameshort :
3706            return "short"; //$NON-NLS-1$
3707
case TokenNamestatic :
3708            return "static"; //$NON-NLS-1$
3709
case TokenNamesuper :
3710            return "super"; //$NON-NLS-1$
3711
case TokenNameswitch :
3712            return "switch"; //$NON-NLS-1$
3713
case TokenNamesynchronized :
3714            return "synchronized"; //$NON-NLS-1$
3715
case TokenNamethis :
3716            return "this"; //$NON-NLS-1$
3717
case TokenNamethrow :
3718            return "throw"; //$NON-NLS-1$
3719
case TokenNamethrows :
3720            return "throws"; //$NON-NLS-1$
3721
case TokenNametransient :
3722            return "transient"; //$NON-NLS-1$
3723
case TokenNametrue :
3724            return "true"; //$NON-NLS-1$
3725
case TokenNametry :
3726            return "try"; //$NON-NLS-1$
3727
case TokenNamevoid :
3728            return "void"; //$NON-NLS-1$
3729
case TokenNamevolatile :
3730            return "volatile"; //$NON-NLS-1$
3731
case TokenNamewhile :
3732            return "while"; //$NON-NLS-1$
3733

3734        case TokenNameIntegerLiteral :
3735            return "Integer(" + new String JavaDoc(getCurrentTokenSource()) + ")"; //$NON-NLS-1$ //$NON-NLS-2$
3736
case TokenNameLongLiteral :
3737            return "Long(" + new String JavaDoc(getCurrentTokenSource()) + ")"; //$NON-NLS-1$ //$NON-NLS-2$
3738
case TokenNameFloatingPointLiteral :
3739            return "Float(" + new String JavaDoc(getCurrentTokenSource()) + ")"; //$NON-NLS-1$ //$NON-NLS-2$
3740
case TokenNameDoubleLiteral :
3741            return "Double(" + new String JavaDoc(getCurrentTokenSource()) + ")"; //$NON-NLS-1$ //$NON-NLS-2$
3742
case TokenNameCharacterLiteral :
3743            return "Char(" + new String JavaDoc(getCurrentTokenSource()) + ")"; //$NON-NLS-1$ //$NON-NLS-2$
3744
case TokenNameStringLiteral :
3745            return "String(" + new String JavaDoc(getCurrentTokenSource()) + ")"; //$NON-NLS-1$ //$NON-NLS-2$
3746

3747        case TokenNamePLUS_PLUS :
3748            return "++"; //$NON-NLS-1$
3749
case TokenNameMINUS_MINUS :
3750            return "--"; //$NON-NLS-1$
3751
case TokenNameEQUAL_EQUAL :
3752            return "=="; //$NON-NLS-1$
3753
case TokenNameLESS_EQUAL :
3754            return "<="; //$NON-NLS-1$
3755
case TokenNameGREATER_EQUAL :
3756            return ">="; //$NON-NLS-1$
3757
case TokenNameNOT_EQUAL :
3758            return "!="; //$NON-NLS-1$
3759
case TokenNameLEFT_SHIFT :
3760            return "<<"; //$NON-NLS-1$
3761
case TokenNameRIGHT_SHIFT :
3762            return ">>"; //$NON-NLS-1$
3763
case TokenNameUNSIGNED_RIGHT_SHIFT :
3764            return ">>>"; //$NON-NLS-1$
3765
case TokenNamePLUS_EQUAL :
3766            return "+="; //$NON-NLS-1$
3767
case TokenNameMINUS_EQUAL :
3768            return "-="; //$NON-NLS-1$
3769
case TokenNameMULTIPLY_EQUAL :
3770            return "*="; //$NON-NLS-1$
3771
case TokenNameDIVIDE_EQUAL :
3772            return "/="; //$NON-NLS-1$
3773
case TokenNameAND_EQUAL :
3774            return "&="; //$NON-NLS-1$
3775
case TokenNameOR_EQUAL :
3776            return "|="; //$NON-NLS-1$
3777
case TokenNameXOR_EQUAL :
3778            return "^="; //$NON-NLS-1$
3779
case TokenNameREMAINDER_EQUAL :
3780            return "%="; //$NON-NLS-1$
3781
case TokenNameLEFT_SHIFT_EQUAL :
3782            return "<<="; //$NON-NLS-1$
3783
case TokenNameRIGHT_SHIFT_EQUAL :
3784            return ">>="; //$NON-NLS-1$
3785
case TokenNameUNSIGNED_RIGHT_SHIFT_EQUAL :
3786            return ">>>="; //$NON-NLS-1$
3787
case TokenNameOR_OR :
3788            return "||"; //$NON-NLS-1$
3789
case TokenNameAND_AND :
3790            return "&&"; //$NON-NLS-1$
3791
case TokenNamePLUS :
3792            return "+"; //$NON-NLS-1$
3793
case TokenNameMINUS :
3794            return "-"; //$NON-NLS-1$
3795
case TokenNameNOT :
3796            return "!"; //$NON-NLS-1$
3797
case TokenNameREMAINDER :
3798            return "%"; //$NON-NLS-1$
3799
case TokenNameXOR :
3800            return "^"; //$NON-NLS-1$
3801
case TokenNameAND :
3802            return "&"; //$NON-NLS-1$
3803
case TokenNameMULTIPLY :
3804            return "*"; //$NON-NLS-1$
3805
case TokenNameOR :
3806            return "|"; //$NON-NLS-1$
3807
case TokenNameTWIDDLE :
3808            return "~"; //$NON-NLS-1$
3809
case TokenNameDIVIDE :
3810            return "/"; //$NON-NLS-1$
3811
case TokenNameGREATER :
3812            return ">"; //$NON-NLS-1$
3813
case TokenNameLESS :
3814            return "<"; //$NON-NLS-1$
3815
case TokenNameLPAREN :
3816            return "("; //$NON-NLS-1$
3817
case TokenNameRPAREN :
3818            return ")"; //$NON-NLS-1$
3819
case TokenNameLBRACE :
3820            return "{"; //$NON-NLS-1$
3821
case TokenNameRBRACE :
3822            return "}"; //$NON-NLS-1$
3823
case TokenNameLBRACKET :
3824            return "["; //$NON-NLS-1$
3825
case TokenNameRBRACKET :
3826            return "]"; //$NON-NLS-1$
3827
case TokenNameSEMICOLON :
3828            return ";"; //$NON-NLS-1$
3829
case TokenNameQUESTION :
3830            return "?"; //$NON-NLS-1$
3831
case TokenNameCOLON :
3832            return ":"; //$NON-NLS-1$
3833
case TokenNameCOMMA :
3834            return ","; //$NON-NLS-1$
3835
case TokenNameDOT :
3836            return "."; //$NON-NLS-1$
3837
case TokenNameEQUAL :
3838            return "="; //$NON-NLS-1$
3839
case TokenNameEOF :
3840            return "EOF"; //$NON-NLS-1$
3841
case TokenNameWHITESPACE :
3842            return "white_space(" + new String JavaDoc(getCurrentTokenSource()) + ")"; //$NON-NLS-1$ //$NON-NLS-2$
3843
default :
3844            return "not-a-token"; //$NON-NLS-1$
3845
}
3846}
3847public void unicodeInitializeBuffer(int length) {
3848    this.withoutUnicodePtr = length;
3849    if (this.withoutUnicodeBuffer == null) this.withoutUnicodeBuffer = new char[length+(1+10)];
3850    int bLength = this.withoutUnicodeBuffer.length;
3851    if (1+length >= bLength) {
3852        System.arraycopy(this.withoutUnicodeBuffer, 0, this.withoutUnicodeBuffer = new char[length + (1+10)], 0, bLength);
3853    }
3854    System.arraycopy(this.source, this.startPosition, this.withoutUnicodeBuffer, 1, length);
3855}
3856public void unicodeStore() {
3857    int pos = ++this.withoutUnicodePtr;
3858    if (this.withoutUnicodeBuffer == null) this.withoutUnicodeBuffer = new char[10];
3859    int length = this.withoutUnicodeBuffer.length;
3860    if (pos == length) {
3861        System.arraycopy(this.withoutUnicodeBuffer, 0, this.withoutUnicodeBuffer = new char[length * 2], 0, length);
3862    }
3863    this.withoutUnicodeBuffer[pos] = this.currentCharacter;
3864}
3865}
3866
Popular Tags