1 11 package org.eclipse.jdt.internal.compiler.parser.diagnose; 12 13 import org.eclipse.jdt.core.compiler.CharOperation; 14 import org.eclipse.jdt.core.compiler.InvalidInputException; 15 import org.eclipse.jdt.internal.compiler.parser.Scanner; 16 import org.eclipse.jdt.internal.compiler.parser.TerminalTokens; 17 import org.eclipse.jdt.internal.compiler.util.Util; 18 19 public class LexStream implements TerminalTokens { 20 public static final int IS_AFTER_JUMP = 1; 21 public static final int LBRACE_MISSING = 2; 22 23 public static class Token{ 24 int kind; 25 char[] name; 26 int start; 27 int end; 28 int line; 29 int flags; 30 31 public String toString() { 32 StringBuffer buffer = new StringBuffer (); 33 buffer.append(name).append('[').append(kind).append(']'); 34 buffer.append('{').append(start).append(',').append(end).append('}').append(line); 35 return buffer.toString(); 36 } 37 38 } 39 40 private int tokenCacheIndex; 41 private int tokenCacheEOFIndex; 42 private Token[] tokenCache; 43 44 private int currentIndex = -1; 45 46 private Scanner scanner; 47 private int[] intervalStartToSkip; 48 private int[] intervalEndToSkip; 49 private int[] intervalFlagsToSkip; 50 51 private int previousInterval = -1; 52 private int currentInterval = -1; 53 54 public LexStream(int size, Scanner scanner, int[] intervalStartToSkip, int[] intervalEndToSkip, int[] intervalFlagsToSkip, int firstToken, int init, int eof) { 55 this.tokenCache = new Token[size]; 56 this.tokenCacheIndex = 0; 57 this.tokenCacheEOFIndex = Integer.MAX_VALUE; 58 this.tokenCache[0] = new Token(); 59 this.tokenCache[0].kind = firstToken; 60 this.tokenCache[0].name = CharOperation.NO_CHAR; 61 this.tokenCache[0].start = init; 62 this.tokenCache[0].end = init; 63 this.tokenCache[0].line = 0; 64 65 this.intervalStartToSkip = intervalStartToSkip; 66 this.intervalEndToSkip = intervalEndToSkip; 67 this.intervalFlagsToSkip = intervalFlagsToSkip; 68 69 scanner.resetTo(init, eof); 70 this.scanner = scanner; 71 } 72 73 private void readTokenFromScanner(){ 74 int length = tokenCache.length; 75 boolean tokenNotFound = true; 76 77 while(tokenNotFound) { 78 try { 79 int tokenKind = scanner.getNextToken(); 80 if(tokenKind != TokenNameEOF) { 81 int start = scanner.getCurrentTokenStartPosition(); 82 int end = scanner.getCurrentTokenEndPosition(); 83 84 int nextInterval = currentInterval + 1; 85 if(intervalStartToSkip.length == 0 || 86 nextInterval >= intervalStartToSkip.length || 87 start < intervalStartToSkip[nextInterval]) { 88 Token token = new Token(); 89 token.kind = tokenKind; 90 token.name = scanner.getCurrentTokenSource(); 91 token.start = start; 92 token.end = end; 93 token.line = Util.getLineNumber(end, scanner.lineEnds, 0, scanner.linePtr); 94 95 if(currentInterval != previousInterval && (intervalFlagsToSkip[currentInterval] & RangeUtil.IGNORE) == 0){ 96 token.flags = IS_AFTER_JUMP; 97 if((intervalFlagsToSkip[currentInterval] & RangeUtil.LBRACE_MISSING) != 0){ 98 token.flags |= LBRACE_MISSING; 99 } 100 } 101 previousInterval = currentInterval; 102 103 tokenCache[++tokenCacheIndex % length] = token; 104 105 tokenNotFound = false; 106 } else { 107 scanner.resetTo(intervalEndToSkip[++currentInterval] + 1, scanner.eofPosition - 1); 108 } 109 } else { 110 int start = scanner.getCurrentTokenStartPosition(); 111 int end = scanner.getCurrentTokenEndPosition(); 112 Token token = new Token(); 113 token.kind = tokenKind; 114 token.name = CharOperation.NO_CHAR; 115 token.start = start; 116 token.end = end; 117 token.line = Util.getLineNumber(end, scanner.lineEnds, 0, scanner.linePtr); 118 119 tokenCache[++tokenCacheIndex % length] = token; 120 121 tokenCacheEOFIndex = tokenCacheIndex; 122 tokenNotFound = false; 123 } 124 } catch (InvalidInputException e) { 125 } 127 } 128 } 129 130 public Token token(int index) { 131 if(index < 0) { 132 Token eofToken = new Token(); 133 eofToken.kind = TokenNameEOF; 134 eofToken.name = CharOperation.NO_CHAR; 135 return eofToken; 136 } 137 if(this.tokenCacheEOFIndex >= 0 && index > this.tokenCacheEOFIndex) { 138 return token(this.tokenCacheEOFIndex); 139 } 140 int length = tokenCache.length; 141 if(index > this.tokenCacheIndex) { 142 int tokensToRead = index - this.tokenCacheIndex; 143 while(tokensToRead-- != 0) { 144 readTokenFromScanner(); 145 } 146 } else if(this.tokenCacheIndex - length >= index) { 147 return null; 148 } 149 150 return tokenCache[index % length]; 151 } 152 153 154 155 public int getToken() { 156 return currentIndex = next(currentIndex); 157 } 158 159 public int previous(int tokenIndex) { 160 return tokenIndex > 0 ? tokenIndex - 1 : 0; 161 } 162 163 public int next(int tokenIndex) { 164 return tokenIndex < this.tokenCacheEOFIndex ? tokenIndex + 1 : this.tokenCacheEOFIndex; 165 } 166 167 public boolean afterEol(int i) { 168 return i < 1 ? true : line(i - 1) < line(i); 169 } 170 171 public void reset() { 172 currentIndex = -1; 173 } 174 175 public void reset(int i) { 176 currentIndex = previous(i); 177 } 178 179 public int badtoken() { 180 return 0; 181 } 182 183 public int kind(int tokenIndex) { 184 return token(tokenIndex).kind; 185 } 186 187 public char[] name(int tokenIndex) { 188 return token(tokenIndex).name; 189 } 190 191 public int line(int tokenIndex) { 192 return token(tokenIndex).line; 193 } 194 195 public int start(int tokenIndex) { 196 return token(tokenIndex).start; 197 } 198 199 public int end(int tokenIndex) { 200 return token(tokenIndex).end; 201 } 202 203 public int flags(int tokenIndex) { 204 return token(tokenIndex).flags; 205 } 206 207 public boolean isInsideStream(int index) { 208 if(this.tokenCacheEOFIndex >= 0 && index > this.tokenCacheEOFIndex) { 209 return false; 210 } else if(index > this.tokenCacheIndex) { 211 return true; 212 } else if(this.tokenCacheIndex - tokenCache.length >= index) { 213 return false; 214 } else { 215 return true; 216 } 217 } 218 219 222 public String toString() { 223 StringBuffer res = new StringBuffer (); 224 225 String source = new String (scanner.source); 226 if(currentIndex < 0) { 227 int previousEnd = -1; 228 for (int i = 0; i < intervalStartToSkip.length; i++) { 229 int intervalStart = intervalStartToSkip[i]; 230 int intervalEnd = intervalEndToSkip[i]; 231 232 res.append(source.substring(previousEnd + 1, intervalStart)); 233 res.append('<'); 234 res.append('@'); 235 res.append(source.substring(intervalStart, intervalEnd + 1)); 236 res.append('@'); 237 res.append('>'); 238 239 previousEnd = intervalEnd; 240 } 241 res.append(source.substring(previousEnd + 1)); 242 } else { 243 Token token = token(currentIndex); 244 int curtokKind = token.kind; 245 int curtokStart = token.start; 246 int curtokEnd = token.end; 247 248 int previousEnd = -1; 249 for (int i = 0; i < intervalStartToSkip.length; i++) { 250 int intervalStart = intervalStartToSkip[i]; 251 int intervalEnd = intervalEndToSkip[i]; 252 253 if(curtokStart >= previousEnd && curtokEnd <= intervalStart) { 254 res.append(source.substring(previousEnd + 1, curtokStart)); 255 res.append('<'); 256 res.append('#'); 257 res.append(source.substring(curtokStart, curtokEnd + 1)); 258 res.append('#'); 259 res.append('>'); 260 res.append(source.substring(curtokEnd+1, intervalStart)); 261 } else { 262 res.append(source.substring(previousEnd + 1, intervalStart)); 263 } 264 res.append('<'); 265 res.append('@'); 266 res.append(source.substring(intervalStart, intervalEnd + 1)); 267 res.append('@'); 268 res.append('>'); 269 270 previousEnd = intervalEnd; 271 } 272 if(curtokStart >= previousEnd) { 273 res.append(source.substring(previousEnd + 1, curtokStart)); 274 res.append('<'); 275 res.append('#'); 276 if(curtokKind == TokenNameEOF) { 277 res.append("EOF#>"); } else { 279 res.append(source.substring(curtokStart, curtokEnd + 1)); 280 res.append('#'); 281 res.append('>'); 282 res.append(source.substring(curtokEnd+1)); 283 } 284 } else { 285 res.append(source.substring(previousEnd + 1)); 286 } 287 } 288 289 return res.toString(); 290 } 291 } 292 | Popular Tags |