Changeset 10982
- Timestamp:
- 02/04/06 21:00:26 (18 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/j/src/org/armedbear/j/JavaTagger.java
r5285 r10982 2 2 * JavaTagger.java 3 3 * 4 * Copyright (C) 1998-200 2Peter Graves5 * $Id: JavaTagger.java,v 1. 6 2003-12-30 19:24:02piso Exp $4 * Copyright (C) 1998-2006 Peter Graves 5 * $Id: JavaTagger.java,v 1.7 2006-02-04 21:00:26 piso Exp $ 6 6 * 7 7 * This program is free software; you can redistribute it and/or … … 27 27 public class JavaTagger extends Tagger implements Constants 28 28 { 29 // States. 30 private static final int NEUTRAL = 0; 31 private static final int INTERFACE_NAME = 1; 32 private static final int CLASS_NAME = 2; 33 private static final int CLASS_PROLOG = 3; // After name, before opening brace. 34 private static final int EXTENDS = 4; 35 private static final int IMPLEMENTS = 5; 36 private static final int METHOD_NAME = 6; 37 private static final int METHOD_PROLOG = 7; 38 private static final int STATIC_INITIALIZER = 8; 39 private static final int NEW = 9; 40 private static final int FIELD_INITIALIZER = 10; // After '=' in a variable declaration. 41 42 protected Position pos; 43 protected String token; 44 protected Position tokenStart; 45 46 private ArrayList tags; 47 private JavaClass currentClass; 48 private int visibility; // TAG_PUBLIC, TAG_PRIVATE, TAG_PROTECTED 49 50 public JavaTagger(SystemBuffer buffer) 51 { 52 super(buffer); 53 } 54 55 public synchronized void run() 56 { 57 pos = new Position(buffer.getFirstLine(), 0); 58 token = null; 59 tokenStart = null; 60 tags = new ArrayList(); 61 currentClass = null; 62 visibility = 0; 63 final boolean beanShell = buffer.getModeId() == BEANSHELL_MODE; 64 final boolean javaScript = buffer.getModeId() == JAVASCRIPT_MODE; 65 final Stack stack = new Stack(); 66 int state = NEUTRAL; 67 while (!pos.atEnd()) { 68 char c = pos.getChar(); 69 if (Character.isWhitespace(c)) { 70 pos.skipWhitespace(); 71 continue; 72 } 73 if (c == '\'' || c == '"') { 74 pos.skipQuote(); 75 continue; 76 } 77 if (pos.lookingAt("/*")) { 78 skipComment(pos); 79 continue; 80 } 81 if (pos.lookingAt("//")) { 82 skipSingleLineComment(pos); 83 continue; 84 } 85 if (state == STATIC_INITIALIZER) { 86 if (c == '{') { 87 skipBrace(); 88 state = NEUTRAL; 89 continue; 90 } 91 // Anything else... 92 state = NEUTRAL; 93 // Fall through... 94 } 95 if (state == METHOD_NAME) { 96 if (c == '{') { 29 // States. 30 private static final int NEUTRAL = 0; 31 private static final int INTERFACE_NAME = 1; 32 private static final int CLASS_NAME = 2; 33 private static final int CLASS_PROLOG = 3; // After name, before opening brace. 34 private static final int EXTENDS = 4; 35 private static final int IMPLEMENTS = 5; 36 private static final int METHOD_NAME = 6; 37 private static final int METHOD_PROLOG = 7; 38 private static final int STATIC_INITIALIZER = 8; 39 private static final int NEW = 9; 40 private static final int FIELD_INITIALIZER = 10; // After '=' in a variable declaration. 41 42 protected Position pos; 43 protected String token; 44 protected Position tokenStart; 45 46 private ArrayList tags; 47 private JavaClass currentClass; 48 private int visibility; // TAG_PUBLIC, TAG_PRIVATE, TAG_PROTECTED 49 50 public JavaTagger(SystemBuffer buffer) 51 { 52 super(buffer); 53 } 54 55 public synchronized void run() 56 { 57 pos = new Position(buffer.getFirstLine(), 0); 58 token = null; 59 tokenStart = null; 60 tags = new ArrayList(); 61 currentClass = null; 62 visibility = 0; 63 final boolean beanShell = buffer.getModeId() == BEANSHELL_MODE; 64 final boolean javaScript = buffer.getModeId() == JAVASCRIPT_MODE; 65 final Stack stack = new Stack(); 66 int state = NEUTRAL; 67 while (!pos.atEnd()) 68 { 69 char c = pos.getChar(); 70 if (Character.isWhitespace(c)) 71 { 72 pos.skipWhitespace(); 73 continue; 74 } 75 if (c == '\'' || c == '"') 76 { 77 pos.skipQuote(); 78 continue; 79 } 80 if (pos.lookingAt("/*")) 81 { 82 skipComment(pos); 83 continue; 84 } 85 if (pos.lookingAt("//")) 86 { 87 skipSingleLineComment(pos); 88 continue; 89 } 90 if (state == STATIC_INITIALIZER) 91 { 92 if (c == '{') 93 { 94 skipBrace(); 95 state = NEUTRAL; 96 continue; 97 } 98 // Anything else... 99 state = NEUTRAL; 100 // Fall through... 101 } 102 if (state == METHOD_NAME) 103 { 104 if (c == '{') 105 { 106 addTag(TAG_METHOD); 107 visibility = 0; 108 skipBrace(); 109 state = NEUTRAL; 110 continue; 111 } 112 if (c == ';') 113 { 114 if (beanShell) 115 { 116 ; // It's just a function call. 117 } 118 else 119 { 120 // Abstract or native method. 97 121 addTag(TAG_METHOD); 98 122 visibility = 0; 99 skipBrace(); 100 state = NEUTRAL; 101 continue; 102 } 103 if (c == ';') { 104 if (beanShell) { 105 ; // It's just a function call. 106 } else { 107 // Abstract or native method. 108 addTag(TAG_METHOD); 109 visibility = 0; 110 } 111 state = NEUTRAL; 112 pos.next(); 113 continue; 114 } 115 if (pos.lookingAt("throws")) { 123 } 124 state = NEUTRAL; 125 pos.next(); 126 continue; 127 } 128 if (pos.lookingAt("throws")) 129 { 130 addTag(TAG_METHOD); 131 // Set token to null here so we don't try to add this method again. 132 token = null; 133 visibility = 0; 134 state = METHOD_PROLOG; 135 pos.skip(6); // Skip over "throws". 136 continue; 137 } 138 state = NEUTRAL; 139 // Fall through... 140 } 141 if (state == CLASS_PROLOG) 142 { 143 if (pos.lookingAt("extends")) 144 { 145 state = EXTENDS; 146 pos.skip(7); // Skip over "extends". 147 continue; 148 } 149 if (pos.lookingAt("implements")) 150 { 151 state = IMPLEMENTS; 152 pos.skip(10); 153 continue; 154 } 155 if (c == '{') 156 state = NEUTRAL; 157 pos.next(); 158 continue; 159 } 160 if (state == IMPLEMENTS) 161 { 162 if (c == '{') 163 { 164 state = NEUTRAL; 165 pos.next(); 166 continue; 167 } 168 // else fall through... 169 } 170 if (state == METHOD_PROLOG) 171 { 172 // Wait for a semicolon or the opening brace of the method body. 173 if (c == '{') 174 { 175 skipBrace(); 176 state = NEUTRAL; 177 } 178 else if (c == ';') 179 { 180 // Abstract or native method. If token is null, we've 181 // added it already. 182 if (token != null) 183 { 116 184 addTag(TAG_METHOD); 117 // Set token to null here so we don't try to add this method again.118 token = null;119 185 visibility = 0; 120 state = METHOD_PROLOG; 121 pos.skip(6); // Skip over "throws". 122 continue; 123 } 124 state = NEUTRAL; 125 // Fall through... 126 } 127 if (state == CLASS_PROLOG) { 128 if (pos.lookingAt("extends")) { 129 state = EXTENDS; 130 pos.skip(7); // Skip over "extends". 131 continue; 132 } 133 if (pos.lookingAt("implements")) { 134 state = IMPLEMENTS; 135 pos.skip(10); 136 continue; 137 } 138 if (c == '{') 139 state = NEUTRAL; 186 } 187 state = NEUTRAL; 140 188 pos.next(); 141 continue; 142 } 143 if (state == IMPLEMENTS) { 144 if (c == '{') { 145 state = NEUTRAL; 146 pos.next(); 147 continue; 148 } 149 // else fall through... 150 } 151 if (state == METHOD_PROLOG) { 152 // Wait for a semicolon or the opening brace of the method body. 153 if (c == '{') { 154 skipBrace(); 155 state = NEUTRAL; 156 } else if (c == ';') { 157 // Abstract or native method. If token is null, we've 158 // added it already. 159 if (token != null) { 160 addTag(TAG_METHOD); 161 visibility = 0; 162 } 163 state = NEUTRAL; 164 pos.next(); 165 } else 166 pos.next(); 167 continue; 168 } 169 if (state == NEW) { 170 if (c == '(') { 171 skipParen(); 172 continue; 173 } else if (c == '{') { 174 skipBrace(); 175 continue; 176 } else if (c == ';') 177 state = NEUTRAL; 189 } 190 else 191 pos.next(); 192 continue; 193 } 194 if (state == NEW) 195 { 196 if (c == '(') 197 { 198 skipParen(); 199 continue; 200 } 201 else if (c == '{') 202 { 203 skipBrace(); 204 continue; 205 } 206 else if (c == ';') 207 state = NEUTRAL; 208 pos.next(); 209 continue; 210 } 211 if (state == FIELD_INITIALIZER) 212 { 213 if (c == '(') 214 { 215 skipParen(); 216 continue; 217 } 218 if (c == '{') 219 { 220 skipBrace(); 221 if (javaScript) 222 state = NEUTRAL; 223 continue; 224 } 225 if (c == ',') 226 state = NEUTRAL; 227 else if (c == ';') 228 { 229 state = NEUTRAL; 230 visibility = 0; 231 } 232 pos.next(); 233 continue; 234 } 235 if (state == IMPLEMENTS) 236 { 237 if (c == ',') 238 { 178 239 pos.next(); 179 240 continue; 180 } 181 if (state == FIELD_INITIALIZER) { 182 if (c == '(') { 183 skipParen(); 184 continue; 185 } 186 if (c == '{') { 187 skipBrace(); 188 if (javaScript) 189 state = NEUTRAL; 190 continue; 191 } 192 if (c == ',') 193 state = NEUTRAL; 194 else if (c == ';') { 195 state = NEUTRAL; 196 visibility = 0; 197 } 198 pos.next(); 199 continue; 200 } 201 if (state == IMPLEMENTS) { 202 if (c == ',') { 203 pos.next(); 204 continue; 205 } 206 } 207 if (c == '}') { 208 if (!stack.empty()) 209 currentClass = (JavaClass) stack.pop(); 210 else 211 currentClass = null; 212 pos.next(); 213 continue; 214 } 215 if (Character.isJavaIdentifierStart(c)) { 216 // If we're in an "extends" or "implements" clause, the token 217 // may be a canonical class name (like "java.lang.String"). 218 // Otherwise the token is a simple identifier. 219 gatherToken(state == EXTENDS || state == IMPLEMENTS); 220 if (state == INTERFACE_NAME) { 221 if (currentClass != null) 222 stack.push(currentClass); 223 final JavaClass parentClass = currentClass; 224 currentClass = new JavaClass(token, TAG_INTERFACE); 225 state = CLASS_PROLOG; 226 // Add a tag for the class itself. 227 tags.add(new JavaTag("interface ".concat(token), 228 tokenStart,TAG_INTERFACE, visibility, parentClass)); 229 visibility = 0; 230 } else if (state == CLASS_NAME) { 231 if (currentClass != null) 232 stack.push(currentClass); 233 final JavaClass parentClass = currentClass; 234 currentClass = new JavaClass(token, TAG_CLASS); 235 state = CLASS_PROLOG; 236 // Add a tag for the class itself. 237 tags.add(new JavaTag("class ".concat(token), tokenStart, 238 TAG_CLASS, visibility, parentClass)); 239 visibility = 0; 240 } else if (state == EXTENDS) { 241 tags.add(new JavaTag(token, tokenStart, TAG_EXTENDS, 242 visibility, currentClass)); 243 state = CLASS_PROLOG; 244 } else if (state == IMPLEMENTS) 245 tags.add(new JavaTag(token, tokenStart, TAG_IMPLEMENTS, 246 visibility, currentClass)); 247 else if (token.equals("package") || token.equals("import")) 248 skipSemi(); 249 else if (token.equals("interface")) 250 state = INTERFACE_NAME; 251 else if (token.equals("class")) 252 state = CLASS_NAME; 253 else if (token.equals("static")) 254 state = STATIC_INITIALIZER; 255 else if (token.equals("new")) 256 // Don't be confused by lines like "Runnable r = new Runnable() { ... };" 257 state = NEW; 258 else if (token.equals("public")) 259 visibility |= TAG_PUBLIC; 260 else if (token.equals("protected")) 261 visibility |= TAG_PROTECTED; 262 else if (token.equals("private")) 263 visibility |= TAG_PRIVATE; 264 continue; 265 } 266 if (c == '(') { 267 skipParen(); 268 state = METHOD_NAME; 269 continue; 270 } 271 if (c == '=') { 272 addTag(TAG_FIELD); 273 state = FIELD_INITIALIZER; 274 pos.next(); 275 continue; 276 } 277 // "int x, y;" 278 if (c == ';' || c == ',') { 279 if (token != null) 280 addTag(TAG_FIELD); 281 // Don't reset the visibility until we see the semicolon. 282 if (c == ';') 283 visibility = 0; 284 } 241 } 242 } 243 if (c == '}') 244 { 245 if (!stack.empty()) 246 currentClass = (JavaClass) stack.pop(); 247 else 248 currentClass = null; 285 249 pos.next(); 286 } 287 buffer.setTags(tags); 288 } 289 290 private void addTag(int type) 291 { 292 if (currentClass != null) { 293 FastStringBuffer sb = new FastStringBuffer(currentClass.getName()); 294 sb.append('.'); 295 sb.append(token); 296 tags.add(new JavaTag(sb.toString(), tokenStart, type, visibility, currentClass)); 297 } else 298 tags.add(new JavaTag(token, tokenStart, type, visibility)); 299 } 300 301 protected static final void skipComment(Position pos) 302 { 303 while (true) { 304 if (pos.lookingAt("*/")) { 305 pos.skip(2); 306 return; 307 } 250 continue; 251 } 252 if (Character.isJavaIdentifierStart(c)) 253 { 254 // If we're in an "extends" or "implements" clause, the token 255 // may be a canonical class name (like "java.lang.String"). 256 // Otherwise the token is a simple identifier. 257 gatherToken(state == EXTENDS || state == IMPLEMENTS); 258 if (state == INTERFACE_NAME) 259 { 260 if (currentClass != null) 261 stack.push(currentClass); 262 final JavaClass parentClass = currentClass; 263 currentClass = new JavaClass(token, TAG_INTERFACE); 264 state = CLASS_PROLOG; 265 // Add a tag for the class itself. 266 tags.add(new JavaTag("interface ".concat(token), 267 tokenStart,TAG_INTERFACE, visibility, parentClass)); 268 visibility = 0; 269 } 270 else if (state == CLASS_NAME) 271 { 272 if (currentClass != null) 273 stack.push(currentClass); 274 final JavaClass parentClass = currentClass; 275 currentClass = new JavaClass(token, TAG_CLASS); 276 state = CLASS_PROLOG; 277 // Add a tag for the class itself. 278 tags.add(new JavaTag("class ".concat(token), tokenStart, 279 TAG_CLASS, visibility, parentClass)); 280 visibility = 0; 281 } 282 else if (state == EXTENDS) 283 { 284 tags.add(new JavaTag(token, tokenStart, TAG_EXTENDS, 285 visibility, currentClass)); 286 state = CLASS_PROLOG; 287 } 288 else if (state == IMPLEMENTS) 289 tags.add(new JavaTag(token, tokenStart, TAG_IMPLEMENTS, 290 visibility, currentClass)); 291 else if (token.equals("package") || token.equals("import")) 292 skipSemi(); 293 else if (token.equals("interface")) 294 state = INTERFACE_NAME; 295 else if (token.equals("class")) 296 state = CLASS_NAME; 297 else if (token.equals("static")) 298 state = STATIC_INITIALIZER; 299 else if (token.equals("new")) 300 // Don't be confused by lines like "Runnable r = new Runnable() { ... };" 301 state = NEW; 302 else if (token.equals("public")) 303 visibility |= TAG_PUBLIC; 304 else if (token.equals("protected")) 305 visibility |= TAG_PROTECTED; 306 else if (token.equals("private")) 307 visibility |= TAG_PRIVATE; 308 continue; 309 } 310 if (c == '(') 311 { 312 skipParen(); 313 state = METHOD_NAME; 314 continue; 315 } 316 if (c == '=') 317 { 318 addTag(TAG_FIELD); 319 state = FIELD_INITIALIZER; 320 pos.next(); 321 continue; 322 } 323 // "int x, y;" 324 if (c == ';' || c == ',') 325 { 326 if (token != null) 327 addTag(TAG_FIELD); 328 // Don't reset the visibility until we see the semicolon. 329 if (c == ';') 330 visibility = 0; 331 } 332 pos.next(); 333 } 334 buffer.setTags(tags); 335 } 336 337 private void addTag(int type) 338 { 339 if (currentClass != null) 340 { 341 FastStringBuffer sb = new FastStringBuffer(currentClass.getName()); 342 sb.append('.'); 343 sb.append(token); 344 tags.add(new JavaTag(sb.toString(), tokenStart, type, visibility, currentClass)); 345 } 346 else 347 tags.add(new JavaTag(token, tokenStart, type, visibility)); 348 } 349 350 protected static final void skipComment(Position pos) 351 { 352 while (true) 353 { 354 if (pos.lookingAt("*/")) 355 { 356 pos.skip(2); 357 return; 358 } 359 if (!pos.next()) 360 return; 361 } 362 } 363 364 protected final void skipSingleLineComment(Position pos) 365 { 366 checkForExplicitTag(pos); 367 Line next = pos.getNextLine(); 368 if (next != null) 369 pos.moveTo(next, 0); 370 else 371 pos.setOffset(pos.getLineLength()); 372 } 373 374 private final void checkForExplicitTag(Position pos) 375 { 376 if (tags == null) 377 return; // Only supported for Java and JavaScript for now. 378 final String explicitTag = 379 Editor.preferences().getStringProperty(Property.EXPLICIT_TAG); 380 if (explicitTag != null && explicitTag.length() > 0) 381 { 382 pos = pos.copy(); 383 String s = pos.getString(); // Substring to end of line. 384 int index = s.indexOf(explicitTag); 385 if (index >= 0) 386 { 387 pos.skip(index + explicitTag.length()); 388 pos.skipWhitespace(); 389 // Now we're looking at the first character of the tag. 390 FastStringBuffer sb = new FastStringBuffer(); 391 char c = pos.getChar(); 392 if (c == '"') 393 { 394 while (pos.next()) 395 { 396 c = pos.getChar(); 397 if (c == '"') 398 break; 399 sb.append(c); 400 } 401 } 402 else 403 { 404 // By default, explicit tags are whitespace-delimited, so 405 // they can contain characters that are not legal in Java 406 // identifiers ("symbol-value"). 407 sb.append(c); 408 while (pos.next()) 409 { 410 c = pos.getChar(); 411 if (Character.isWhitespace(c)) 412 break; 413 sb.append(c); 414 } 415 } 416 final String tag = sb.toString(); 417 // Exact location of tag is beginning of text on line 418 // containing tag. 419 pos.setOffset(0); 420 pos.skipWhitespace(); 421 tags.add(new JavaTag(tag, pos, TAG_EXPLICIT, 0, currentClass)); 422 } 423 } 424 } 425 426 // If canonical is true, strings like "java.lang.String" are considered to 427 // be a single token. Used for "extends" and "implements" clauses. 428 private void gatherToken(boolean canonical) 429 { 430 tokenStart = new Position(pos); 431 FastStringBuffer sb = new FastStringBuffer(); 432 char c; 433 if (canonical) 434 { 435 while (Character.isJavaIdentifierPart(c = pos.getChar()) || c == '.') 436 { 437 sb.append(c); 308 438 if (!pos.next()) 309 return; 310 } 311 } 312 313 protected final void skipSingleLineComment(Position pos) 314 { 315 checkForExplicitTag(pos); 316 Line next = pos.getNextLine(); 317 if (next != null) 318 pos.moveTo(next, 0); 439 break; 440 } 441 } 442 else 443 { 444 while (Character.isJavaIdentifierPart(c = pos.getChar())) 445 { 446 sb.append(c); 447 if (!pos.next()) 448 break; 449 } 450 } 451 token = sb.toString(); 452 } 453 454 protected void skipParen() 455 { 456 if (pos.next()) 457 { 458 int count = 1; 459 while (true) 460 { 461 if (pos.lookingAt("/*")) 462 { 463 skipComment(pos); 464 continue; 465 } 466 if (pos.lookingAt("//")) 467 { 468 skipSingleLineComment(pos); 469 continue; 470 } 471 char c = pos.getChar(); 472 if (c == '"' || c == '\'') 473 { 474 pos.skipQuote(); 475 continue; 476 } 477 if (c == '(') 478 ++count; 479 else if (c == ')') 480 --count; 481 if (!pos.next()) 482 break; 483 if (count == 0) 484 break; 485 } 486 } 487 } 488 489 protected void skipBrace() 490 { 491 if (pos.next()) 492 { 493 int count = 1; 494 while (true) 495 { 496 if (pos.lookingAt("/*")) 497 { 498 skipComment(pos); 499 continue; 500 } 501 if (pos.lookingAt("//")) 502 { 503 skipSingleLineComment(pos); 504 continue; 505 } 506 char c = pos.getChar(); 507 if (c == '"' || c == '\'') 508 { 509 pos.skipQuote(); 510 continue; 511 } 512 if (c == '\\') 513 { 514 // Escape. Ignore this char and the next. 515 if (!pos.next()) 516 break; 517 if (!pos.next()) 518 break; 519 continue; 520 } 521 if (c == '{') 522 ++count; 523 else if (c == '}') 524 --count; 525 if (!pos.next()) 526 break; 527 if (count == 0) 528 break; 529 } 530 } 531 } 532 533 private void skipSemi() 534 { 535 while (!pos.atEnd()) 536 { 537 if (pos.lookingAt("/*")) 538 { 539 skipComment(pos); 540 continue; 541 } 542 if (pos.lookingAt("//")) 543 { 544 skipSingleLineComment(pos); 545 continue; 546 } 547 char c = pos.getChar(); 548 if (c == '"' || c == '\'') 549 { 550 pos.skipQuote(); 551 continue; 552 } 553 else if (c == ';') 554 { 555 pos.next(); 556 break; 557 } 319 558 else 320 pos.setOffset(pos.getLineLength()); 321 } 322 323 private final void checkForExplicitTag(Position pos) 324 { 325 if (tags == null) 326 return; // Only supported for Java and JavaScript for now. 327 final String explicitTag = 328 Editor.preferences().getStringProperty(Property.EXPLICIT_TAG); 329 if (explicitTag != null && explicitTag.length() > 0) { 330 pos = pos.copy(); 331 String s = pos.getString(); // Substring to end of line. 332 int index = s.indexOf(explicitTag); 333 if (index >= 0) { 334 pos.skip(index + explicitTag.length()); 335 pos.skipWhitespace(); 336 // Now we're looking at the first character of the tag. 337 FastStringBuffer sb = new FastStringBuffer(); 338 char c = pos.getChar(); 339 if (c == '"') { 340 while (pos.next()) { 341 c = pos.getChar(); 342 if (c == '"') 343 break; 344 sb.append(c); 345 } 346 } else { 347 // By default, explicit tags are whitespace-delimited, so 348 // they can contain characters that are not legal in Java 349 // identifiers ("symbol-value"). 350 sb.append(c); 351 while (pos.next()) { 352 c = pos.getChar(); 353 if (Character.isWhitespace(c)) 354 break; 355 sb.append(c); 356 } 357 } 358 final String tag = sb.toString(); 359 // Exact location of tag is beginning of text on line 360 // containing tag. 361 pos.setOffset(0); 362 pos.skipWhitespace(); 363 tags.add(new JavaTag(tag, pos, TAG_EXPLICIT, 0, currentClass)); 364 } 365 } 366 } 367 368 // If canonical is true, strings like "java.lang.String" are considered to 369 // be a single token. Used for "extends" and "implements" clauses. 370 private void gatherToken(boolean canonical) 371 { 372 tokenStart = new Position(pos); 373 FastStringBuffer sb = new FastStringBuffer(); 374 char c; 375 if (canonical) { 376 while (Character.isJavaIdentifierPart(c = pos.getChar()) || c == '.') { 377 sb.append(c); 378 if (!pos.next()) 379 break; 380 } 381 } else { 382 while (Character.isJavaIdentifierPart(c = pos.getChar())) { 383 sb.append(c); 384 if (!pos.next()) 385 break; 386 } 387 } 388 token = sb.toString(); 389 } 390 391 protected void skipParen() 392 { 393 if (pos.next()) { 394 int count = 1; 395 while (true) { 396 if (pos.lookingAt("/*")) { 397 skipComment(pos); 398 continue; 399 } 400 if (pos.lookingAt("//")) { 401 skipSingleLineComment(pos); 402 continue; 403 } 404 char c = pos.getChar(); 405 if (c == '"' || c == '\'') { 406 pos.skipQuote(); 407 continue; 408 } 409 if (c == '(') 410 ++count; 411 else if (c == ')') 412 --count; 413 if (!pos.next()) 414 break; 415 if (count == 0) 416 break; 417 } 418 } 419 } 420 421 protected void skipBrace() 422 { 423 if (pos.next()) { 424 int count = 1; 425 while (true) { 426 if (pos.lookingAt("/*")) { 427 skipComment(pos); 428 continue; 429 } 430 if (pos.lookingAt("//")) { 431 skipSingleLineComment(pos); 432 continue; 433 } 434 char c = pos.getChar(); 435 if (c == '"' || c == '\'') { 436 pos.skipQuote(); 437 continue; 438 } 439 if (c == '\\') { 440 // Escape. Ignore this char and the next. 441 if (!pos.next()) 442 break; 443 if (!pos.next()) 444 break; 445 continue; 446 } 447 if (c == '{') 448 ++count; 449 else if (c == '}') 450 --count; 451 if (!pos.next()) 452 break; 453 if (count == 0) 454 break; 455 } 456 } 457 } 458 459 private void skipSemi() 460 { 461 while (!pos.atEnd()) { 462 if (pos.lookingAt("/*")) { 463 skipComment(pos); 464 continue; 465 } 466 if (pos.lookingAt("//")) { 467 skipSingleLineComment(pos); 468 continue; 469 } 470 char c = pos.getChar(); 471 if (c == '"' || c == '\'') { 472 pos.skipQuote(); 473 continue; 474 } else if (c == ';') { 475 pos.next(); 476 break; 477 } else 478 pos.next(); 479 } 480 } 481 482 // Used by the C, C++ and Objective C taggers. 483 protected static final void skipPreprocessor(Position pos) 484 { 485 while (true) { 486 Line line = pos.getLine(); 487 Line nextLine = line.next(); 488 if (nextLine == null) { 489 pos.setOffset(line.length()); 490 return; 491 } 492 pos.moveTo(nextLine, 0); 493 if (line.length() == 0 || line.charAt(line.length()-1) != '\\') 494 return; 495 } 496 } 559 pos.next(); 560 } 561 } 562 563 // Used by the C, C++ and Objective C taggers. 564 protected static final void skipPreprocessor(Position pos) 565 { 566 while (true) 567 { 568 Line line = pos.getLine(); 569 Line nextLine = line.next(); 570 if (nextLine == null) 571 { 572 pos.setOffset(line.length()); 573 return; 574 } 575 pos.moveTo(nextLine, 0); 576 if (line.length() == 0 || line.charAt(line.length()-1) != '\\') 577 return; 578 } 579 } 497 580 }
Note: See TracChangeset
for help on using the changeset viewer.