1 package net.sourceforge.phpdt.internal.ui.text;
4 * (c) Copyright IBM Corp. 2000, 2001.
8 import org.eclipse.jface.text.IDocument;
9 import org.eclipse.jface.text.rules.ICharacterScanner;
10 import org.eclipse.jface.text.rules.IPartitionTokenScanner;
11 import org.eclipse.jface.text.rules.IToken;
12 import org.eclipse.jface.text.rules.Token;
16 * This scanner recognizes the JavaDoc comments, Java multi line comments, Java single line comments,
17 * Java strings and Java characters.
19 public class FastJavaPartitionScanner implements IPartitionTokenScanner {
21 // private final static String SKIP= "__skip"; //$NON-NLS-1$
22 // public final static String JAVA_STRING= "__php_string"; //$NON-NLS-1$
23 // public final static String JAVA_SINGLE_LINE_COMMENT= "__php_singleline_comment"; //$NON-NLS-1$
24 // public final static String JAVA_MULTI_LINE_COMMENT= "__php_multiline_comment"; //$NON-NLS-1$
25 // public final static String JAVA_DOC= "__php_phpdoc"; //$NON-NLS-1$
28 private static final int HTML= 0;
29 private static final int SINGLE_LINE_COMMENT= 1;
30 private static final int MULTI_LINE_COMMENT= 2;
31 private static final int PHPDOC= 3;
32 // private static final int CHARACTER= 4;
33 private static final int STRING_SQ= 4; // single quote string
34 private static final int STRING_DQ= 5; // double quote string
35 private static final int PHP= 6; // double quote string
37 // beginning of prefixes and postfixes
38 private static final int NONE= 0;
39 private static final int BACKSLASH= 1; // postfix for STRING and CHARACTER
40 private static final int SLASH= 2; // prefix for SINGLE_LINE or MULTI_LINE or JAVADOC
41 private static final int SLASH_STAR= 3; // prefix for MULTI_LINE_COMMENT or JAVADOC
42 private static final int SLASH_STAR_STAR= 4; // prefix for MULTI_LINE_COMMENT or JAVADOC
43 private static final int STAR= 5; // postfix for MULTI_LINE_COMMENT or JAVADOC
44 private static final int CARRIAGE_RETURN=6; // postfix for STRING, CHARACTER and SINGLE_LINE_COMMENT
47 // private final BufferedRuleBasedScanner fScanner= new BufferedRuleBasedScanner(1000);
48 private final BufferedDocumentScanner fScanner= new BufferedDocumentScanner(1000); // faster implementation
50 /** The offset of the last returned token. */
51 private int fTokenOffset;
52 /** The length of the last returned token. */
53 private int fTokenLength;
55 /** The state of the scanner. */
57 /** The last significant characters read. */
59 /** The amount of characters already read on first call to nextToken(). */
60 private int fPrefixLength;
62 // emulate JavaPartitionScanner
63 // private static final boolean fgEmulate= false;
64 private int fJavaOffset;
65 private int fJavaLength;
67 private final IToken[] fTokens= new IToken[] {
69 new Token(IPHPPartitions.PHP_SINGLELINE_COMMENT),
70 new Token(IPHPPartitions.PHP_MULTILINE_COMMENT),
71 new Token(IPHPPartitions.PHP_PHPDOC_COMMENT),
72 new Token(IPHPPartitions.PHP_STRING_SQ),
73 new Token(IPHPPartitions.PHP_STRING_DQ),
74 new Token(IPHPPartitions.PHP_PARTITIONING),
78 * @see org.eclipse.jface.text.rules.ITokenScanner#nextToken()
80 public IToken nextToken() {
82 fTokenOffset += fTokenLength;
83 fTokenLength= fPrefixLength;
86 final int ch= fScanner.read();
90 case ICharacterScanner.EOF:
91 if (fTokenLength > 0) {
92 fLast= NONE; // ignore last
93 return preFix(fState, HTML, NONE, 0);
102 if ( fLast != CARRIAGE_RETURN) {
103 fLast= CARRIAGE_RETURN;
110 case SINGLE_LINE_COMMENT:
114 if (fTokenLength > 0) {
115 IToken token= fTokens[fState];
117 // emulate JavaPartitionScanner
123 fLast= CARRIAGE_RETURN;
143 case SINGLE_LINE_COMMENT:
147 // assert(fTokenLength > 0);
148 return postFix(fState);
156 if ( fLast == CARRIAGE_RETURN) {
158 case SINGLE_LINE_COMMENT:
178 // newState= CHARACTER;
188 last= CARRIAGE_RETURN;
203 fLast= NONE; // ignore fLast
204 return preFix(fState, newState, last, 1);
217 if (fLast == SLASH) {
218 if (fTokenLength - getLastLength(fLast) > 0) {
219 return preFix(PHP, SINGLE_LINE_COMMENT, NONE, 2);
221 preFix(PHP, SINGLE_LINE_COMMENT, NONE, 2);
222 fTokenOffset += fTokenLength;
223 fTokenLength= fPrefixLength;
234 if (fLast == SLASH) {
235 if (fTokenLength - getLastLength(fLast) > 0)
236 return preFix(PHP, MULTI_LINE_COMMENT, SLASH_STAR, 2);
238 preFix(PHP, MULTI_LINE_COMMENT, SLASH_STAR, 2);
239 fTokenOffset += fTokenLength;
240 fTokenLength= fPrefixLength;
250 fLast= NONE; // ignore fLast
251 if (fTokenLength > 0)
252 return preFix(PHP, STRING_SQ, NONE, 1);
254 preFix(PHP, STRING_SQ, NONE, 1);
255 fTokenOffset += fTokenLength;
256 fTokenLength= fPrefixLength;
261 fLast= NONE; // ignore fLast
262 if (fTokenLength > 0)
263 return preFix(PHP, STRING_DQ, NONE, 1);
265 preFix(PHP, STRING_DQ, NONE, 1);
266 fTokenOffset += fTokenLength;
267 fTokenLength= fPrefixLength;
277 case SINGLE_LINE_COMMENT:
285 case SLASH_STAR_STAR:
286 return postFix(MULTI_LINE_COMMENT);
289 return postFix(PHPDOC);
308 case MULTI_LINE_COMMENT:
311 if (fLast == SLASH_STAR) {
312 fLast= SLASH_STAR_STAR;
323 return postFix(MULTI_LINE_COMMENT);
338 fLast= (fLast == BACKSLASH) ? NONE : BACKSLASH;
343 if (fLast != BACKSLASH) {
344 return postFix(STRING_DQ);
360 fLast= (fLast == BACKSLASH) ? NONE : BACKSLASH;
365 if (fLast != BACKSLASH) {
366 return postFix(STRING_SQ);
382 private static final int getLastLength(int last) {
390 case CARRIAGE_RETURN:
399 case SLASH_STAR_STAR:
404 private final void consume() {
409 private final IToken postFix(int state) {
414 return fTokens[state];
417 private final IToken preFix(int state, int newState, int last, int prefixLength) {
418 // emulate JavaPartitionScanner
419 // if (fgEmulate && state == JAVA && (fTokenLength - getLastLength(fLast) > 0)) {
420 // fTokenLength -= getLastLength(fLast);
421 // fJavaOffset= fTokenOffset;
422 // fJavaLength= fTokenLength;
425 // fPrefixLength= prefixLength;
427 // return fTokens[state];
430 fTokenLength -= getLastLength(fLast);
432 fPrefixLength= prefixLength;
433 IToken token= fTokens[state];
439 private static int getState(String contentType) {
441 if (contentType == null)
444 else if (contentType.equals(IPHPPartitions.PHP_PARTITIONING))
447 else if (contentType.equals(IPHPPartitions.PHP_SINGLELINE_COMMENT))
448 return SINGLE_LINE_COMMENT;
450 else if (contentType.equals(IPHPPartitions.PHP_MULTILINE_COMMENT))
451 return MULTI_LINE_COMMENT;
453 else if (contentType.equals(IPHPPartitions.PHP_PHPDOC_COMMENT))
456 else if (contentType.equals(IPHPPartitions.PHP_STRING_DQ))
459 else if (contentType.equals(IPHPPartitions.PHP_STRING_SQ))
462 // else if (contentType.equals(SKIP))
470 * @see IPartitionTokenScanner#setPartialRange(IDocument, int, int, String, int)
472 public void setPartialRange(IDocument document, int offset, int length, String contentType, int partitionOffset) {
474 fScanner.setRange(document, offset, length);
475 fTokenOffset= partitionOffset;
477 fPrefixLength= offset - partitionOffset;
480 if (offset == partitionOffset) {
481 // restart at beginning of partition
484 fState= getState(contentType);
487 // emulate JavaPartitionScanner
495 * @see ITokenScanner#setRange(IDocument, int, int)
497 public void setRange(IDocument document, int offset, int length) {
499 fScanner.setRange(document, offset, length);
500 fTokenOffset= offset;
506 // emulate JavaPartitionScanner
514 * @see ITokenScanner#getTokenLength()
516 public int getTokenLength() {
521 * @see ITokenScanner#getTokenOffset()
523 public int getTokenOffset() {