KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > core > util > PublicScanner


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.core.util;
12
13 import org.eclipse.jdt.core.compiler.CharOperation;
14 import org.eclipse.jdt.core.compiler.IScanner;
15 import org.eclipse.jdt.core.compiler.ITerminalSymbols;
16 import org.eclipse.jdt.core.compiler.InvalidInputException;
17 import org.eclipse.jdt.internal.compiler.CompilationResult;
18 import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
19 import org.eclipse.jdt.internal.compiler.parser.NLSTag;
20 import org.eclipse.jdt.internal.compiler.parser.ScannerHelper;
21 import org.eclipse.jdt.internal.compiler.util.Util;
22
23 public class PublicScanner implements IScanner, ITerminalSymbols {
24     
25     //public int newIdentCount = 0;
26

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

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

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

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

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

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

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

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

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

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

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

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

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

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

610     //ALL getNextChar.... ARE OPTIMIZED COPIES
611

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

2553public void resetTo(int begin, int end) {
2554    //reset the scanner to a given position where it may rescan again
2555

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

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

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

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

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

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

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

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

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

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

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

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

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

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