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() {