Fixed bug #1404228: Crash on <?php // comment ?>
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / internal / ui / text / FastJavaPartitionScanner.java
index 41246b6..7efcc30 100644 (file)
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
 package net.sourceforge.phpdt.internal.ui.text;
 
-/*
- * (c) Copyright IBM Corp. 2000, 2001.
- * All Rights Reserved.
- */
+import net.sourceforge.phpeclipse.ui.text.rules.AbstractPartitioner;
 
+import org.eclipse.jface.text.Assert;
 import org.eclipse.jface.text.IDocument;
 import org.eclipse.jface.text.rules.ICharacterScanner;
 import org.eclipse.jface.text.rules.IPartitionTokenScanner;
 import org.eclipse.jface.text.rules.IToken;
 import org.eclipse.jface.text.rules.Token;
 
-
 /**
- * This scanner recognizes the JavaDoc comments, Java multi line comments, Java single line comments,
- * Java strings and Java characters.
+ * This scanner recognizes the JavaDoc comments, Java multi line comments, Java
+ * single line comments, Java strings.
  */
-public class FastJavaPartitionScanner implements IPartitionTokenScanner {
-
-       private final static String SKIP= "__skip"; //$NON-NLS-1$       
-       public final static String JAVA_STRING= "__php_string"; //$NON-NLS-1$
-       public final static String JAVA_SINGLE_LINE_COMMENT= "__php_singleline_comment"; //$NON-NLS-1$
-       public final static String JAVA_MULTI_LINE_COMMENT= "__php_multiline_comment"; //$NON-NLS-1$
-       public final static String JAVA_DOC= "__php_phpdoc"; //$NON-NLS-1$
+public class FastJavaPartitionScanner implements IPartitionTokenScanner, IPHPPartitions {
 
        // states
-       private static final int JAVA= 0;       
-       private static final int SINGLE_LINE_COMMENT= 1;
-       private static final int MULTI_LINE_COMMENT= 2;
-       private static final int JAVADOC= 3;
-       private static final int CHARACTER= 4;
-       private static final int STRING= 5;
-       
+       private static final int PHP = 0;
+
+       private static final int SINGLE_LINE_COMMENT = 1;
+
+       private static final int MULTI_LINE_COMMENT = 2;
+
+       private static final int PHPDOC = 3;
+
+       private static final int STRING_DQ = 4;
+
+       private static final int STRING_SQ = 5;
+
+       private static final int STRING_HEREDOC = 6;
+
        // beginning of prefixes and postfixes
-       private static final int NONE= 0;
-       private static final int BACKSLASH= 1; // postfix for STRING and CHARACTER
-       private static final int SLASH= 2; // prefix for SINGLE_LINE or MULTI_LINE or JAVADOC
-       private static final int SLASH_STAR= 3; // prefix for MULTI_LINE_COMMENT or JAVADOC
-       private static final int SLASH_STAR_STAR= 4; // prefix for MULTI_LINE_COMMENT or JAVADOC
-       private static final int STAR= 5; // postfix for MULTI_LINE_COMMENT or JAVADOC
-       private static final int CARRIAGE_RETURN=6; // postfix for STRING, CHARACTER and SINGLE_LINE_COMMENT
-       
+       private static final int NONE = 0;
+
+       private static final int BACKSLASH = 1; // postfix for STRING_DQ and CHARACTER
+
+       private static final int SLASH = 2; // prefix for SINGLE_LINE or MULTI_LINE or
+                                                                                                                                                       // JAVADOC
+
+       private static final int SLASH_STAR = 3; // prefix for MULTI_LINE_COMMENT or
+                                                                                                                                                                               // JAVADOC
+
+       private static final int SLASH_STAR_STAR = 4; // prefix for MULTI_LINE_COMMENT
+                                                                                                                                                                                               // or JAVADOC
+
+       private static final int STAR = 5; // postfix for MULTI_LINE_COMMENT or
+                                                                                                                                                       // JAVADOC
+
+       private static final int CARRIAGE_RETURN = 6; // postfix for STRING_DQ,
+                                                                                                                                                                                               // CHARACTER and
+                                                                                                                                                                                               // SINGLE_LINE_COMMENT
+
+       // private static final int HEREDOC = 7;
+
        /** The scanner. */
-//     private final BufferedRuleBasedScanner fScanner= new BufferedRuleBasedScanner(1000);
-       private final BufferedDocumentScanner fScanner= new BufferedDocumentScanner(1000);      // faster implementation
-       
+       private final BufferedDocumentScanner fScanner = new BufferedDocumentScanner(1000); // faster
+                                                                                                                                                                                                                                                                                                                                                       // implementation
+
        /** The offset of the last returned token. */
        private int fTokenOffset;
+
        /** The length of the last returned token. */
        private int fTokenLength;
-       
-       /** The state of the scanner. */        
+
+       /** The state of the scanner. */
        private int fState;
+
        /** The last significant characters read. */
        private int fLast;
+
        /** The amount of characters already read on first call to nextToken(). */
        private int fPrefixLength;
-       
+
        // emulate JavaPartitionScanner
-       private static final boolean fgEmulate= false;
+       private boolean fEmulate = false;
+
        private int fJavaOffset;
+
        private int fJavaLength;
-       
-       private final IToken[] fTokens= new IToken[] {
-               new Token(null),
-               new Token(JAVA_SINGLE_LINE_COMMENT),
-               new Token(JAVA_MULTI_LINE_COMMENT),
-               new Token(JAVA_DOC),
-               new Token(SKIP),
-               new Token(JAVA_STRING)
-       };
+
+       private final IToken[] fTokens = new IToken[] { new Token(null), new Token(PHP_SINGLELINE_COMMENT),
+                       new Token(PHP_MULTILINE_COMMENT), new Token(PHP_PHPDOC_COMMENT), new Token(PHP_STRING_DQ), new Token(PHP_STRING_SQ),
+                       new Token(PHP_STRING_HEREDOC) };
+
+       public FastJavaPartitionScanner(boolean emulate) {
+               fEmulate = emulate;
+       }
+
+       public FastJavaPartitionScanner() {
+               this(false);
+       }
 
        /*
         * @see org.eclipse.jface.text.rules.ITokenScanner#nextToken()
         */
        public IToken nextToken() {
-               
+
                // emulate JavaPartitionScanner
-               if (fgEmulate) {
+               if (fEmulate) {
                        if (fJavaOffset != -1 && fTokenOffset + fTokenLength != fJavaOffset + fJavaLength) {
-                               fTokenOffset += fTokenLength;           
-                               return fTokens[JAVA];   
+                               fTokenOffset += fTokenLength;
+                               return fTokens[PHP];
                        } else {
-                               fJavaOffset= -1;
-                               fJavaLength= 0; 
+                               fJavaOffset = -1;
+                               fJavaLength = 0;
                        }
-               }               
+               }
 
                fTokenOffset += fTokenLength;
-               fTokenLength= fPrefixLength;
+               fTokenLength = fPrefixLength;
 
                while (true) {
-                       final int ch= fScanner.read();
-                       
+                       final int ch = fScanner.read();
+
                        // characters
-                       switch (ch) {
-                       case ICharacterScanner.EOF:
-                               if (fTokenLength > 0) {
-                                       fLast= NONE; // ignore last
-                                       return preFix(fState, JAVA, NONE, 0);
-
-                               } else {
-                                       fLast= NONE;
-                                       fPrefixLength= 0;
+                       switch (ch) {
+                       case ICharacterScanner.EOF:
+                               if (fTokenLength > 0) {
+                                       fLast = NONE; // ignore last
+                                       return preFix(fState, PHP, NONE, 0);
+
+                               } else {
+                                       fLast = NONE;
+                                       fPrefixLength = 0;
                                        return Token.EOF;
-                               }
+                               }
 
-                       case '\r':
-                               // emulate JavaPartitionScanner
-                               if (!fgEmulate && fLast != CARRIAGE_RETURN) {
-                                               fLast= CARRIAGE_RETURN;
-                                               fTokenLength++;
-                                               continue;
+                       case '\r':
+                               // emulate JavaPartitionScanner
+                               if (!fEmulate && fLast != CARRIAGE_RETURN) {
+                                       fLast = CARRIAGE_RETURN;
+                                       fTokenLength++;
+                                       continue;
+
+                               } else {
 
-                               } else {
-                                       
                                        switch (fState) {
                                        case SINGLE_LINE_COMMENT:
-                                       case CHARACTER:
-                                       case STRING:
+                                               // case CHARACTER:
+                                               // case STRING_DQ:
+                                               // case STRING_SQ:
                                                if (fTokenLength > 0) {
-                                                       IToken token= fTokens[fState];
-                                                       
-                                                       // emulate JavaPartitionScanner
-                                                       if (fgEmulate) {
+                                                       IToken token = fTokens[fState];
+
+                                                       // emulate JavaPartitionScanner
+                                                       if (fEmulate) {
                                                                fTokenLength++;
-                                                               fLast= NONE;
-                                                               fPrefixLength= 0;
-                                                       } else {                                                                
-                                                               fLast= CARRIAGE_RETURN; 
-                                                               fPrefixLength= 1;
+                                                               fLast = NONE;
+                                                               fPrefixLength = 0;
+                                                       } else {
+                                                               fLast = CARRIAGE_RETURN;
+                                                               fPrefixLength = 1;
                                                        }
-                                                       
-                                                       fState= JAVA;
+
+                                                       fState = PHP;
                                                        return token;
 
                                                } else {
                                                        consume();
-                                                       continue;       
+                                                       continue;
                                                }
 
                                        default:
                                                consume();
                                                continue;
-                                       }                                       
-                               }
-       
-                       case '\n':                              
+                                       }
+                               }
+
+                       case '\n':
                                switch (fState) {
                                case SINGLE_LINE_COMMENT:
-                               case CHARACTER:
-                               case STRING:                            
+                                       // case CHARACTER:
+                                       // case STRING_DQ:
+                                       // case STRING_SQ:
                                        // assert(fTokenLength > 0);
                                        return postFix(fState);
 
@@ -159,90 +191,113 @@ public class FastJavaPartitionScanner implements IPartitionTokenScanner {
                                        continue;
                                }
 
+                       case '?':
+                               if (fState == SINGLE_LINE_COMMENT) {
+                                       int nextch = fScanner.read();
+                                       if (nextch == '>') {
+                                               // <h1>This is an <?php # echo 'simple' ?> example.</h1>
+                                               fTokenLength--;
+                                               fScanner.unread();
+                                               fScanner.unread();
+                                               return postFix(fState);
+                                       }
+                                       // bug #1404228: Crash on <?php // comment ?>
+                                       // fScanner.unread();
+                               }
+
                        default:
-                               if (!fgEmulate && fLast == CARRIAGE_RETURN) {                   
+                               if (!fEmulate && fLast == CARRIAGE_RETURN) {
                                        switch (fState) {
                                        case SINGLE_LINE_COMMENT:
-                                       case CHARACTER:
-                                       case STRING:
-
+                                               // case CHARACTER:
+                                               // case STRING_DQ:
+                                               // case STRING_SQ:
                                                int last;
                                                int newState;
                                                switch (ch) {
                                                case '/':
-                                                       last= SLASH;
-                                                       newState= JAVA;
+                                                       last = SLASH;
+                                                       newState = PHP;
                                                        break;
 
                                                case '*':
-                                                       last= STAR;
-                                                       newState= JAVA;
+                                                       last = STAR;
+                                                       newState = PHP;
                                                        break;
-                                               
+
                                                case '\'':
-                                                       last= NONE;
-                                                       newState= CHARACTER;
+                                                       last = NONE;
+                                                       newState = STRING_SQ;
                                                        break;
 
                                                case '"':
-                                                       last= NONE;
-                                                       newState= STRING;
+                                                       last = NONE;
+                                                       newState = STRING_DQ;
                                                        break;
 
                                                case '\r':
-                                                       last= CARRIAGE_RETURN;
-                                                       newState= JAVA;
+                                                       last = CARRIAGE_RETURN;
+                                                       newState = PHP;
                                                        break;
 
                                                case '\\':
-                                                       last= BACKSLASH;
-                                                       newState= JAVA;
+                                                       last = BACKSLASH;
+                                                       newState = PHP;
                                                        break;
 
                                                default:
-                                                       last= NONE;
-                                                       newState= JAVA;
+                                                       last = NONE;
+                                                       newState = PHP;
                                                        break;
                                                }
-                                               
-                                               fLast= NONE; // ignore fLast
+
+                                               fLast = NONE; // ignore fLast
                                                return preFix(fState, newState, last, 1);
-       
+
                                        default:
                                                break;
                                        }
                                }
                        }
 
-                       // states        
-                       switch (fState) {
-                       case JAVA:
+                       // states
+                       switch (fState) {
+                       case PHP:
                                switch (ch) {
+                               case '#':
+                                       if (fTokenLength > 0) {
+                                               return preFix(PHP, SINGLE_LINE_COMMENT, NONE, 1);
+                                       } else {
+                                               preFix(PHP, SINGLE_LINE_COMMENT, NONE, 1);
+                                               fTokenOffset += fTokenLength;
+                                               fTokenLength = fPrefixLength;
+                                               break;
+                                       }
                                case '/':
                                        if (fLast == SLASH) {
                                                if (fTokenLength - getLastLength(fLast) > 0) {
-                                                       return preFix(JAVA, SINGLE_LINE_COMMENT, NONE, 2);
-                                               } else {                                                        
-                                                       preFix(JAVA, SINGLE_LINE_COMMENT, NONE, 2);
+                                                       return preFix(PHP, SINGLE_LINE_COMMENT, NONE, 2);
+                                               } else {
+                                                       preFix(PHP, SINGLE_LINE_COMMENT, NONE, 2);
                                                        fTokenOffset += fTokenLength;
-                                                       fTokenLength= fPrefixLength;
+                                                       fTokenLength = fPrefixLength;
                                                        break;
                                                }
-       
+
                                        } else {
                                                fTokenLength++;
-                                               fLast= SLASH;
+                                               fLast = SLASH;
                                                break;
                                        }
-       
+
                                case '*':
                                        if (fLast == SLASH) {
                                                if (fTokenLength - getLastLength(fLast) > 0)
-                                                       return preFix(JAVA, MULTI_LINE_COMMENT, SLASH_STAR, 2);
+                                                       return preFix(PHP, MULTI_LINE_COMMENT, SLASH_STAR, 2);
                                                else {
-                                                       preFix(JAVA, MULTI_LINE_COMMENT, SLASH_STAR, 2);
+                                                       preFix(PHP, MULTI_LINE_COMMENT, SLASH_STAR, 2);
                                                        fTokenOffset += fTokenLength;
-                                                       fTokenLength= fPrefixLength;
+                                                       fTokenLength = fPrefixLength;
                                                        break;
                                                }
 
@@ -250,48 +305,48 @@ public class FastJavaPartitionScanner implements IPartitionTokenScanner {
                                                consume();
                                                break;
                                        }
-                                       
+
                                case '\'':
-                                       fLast= NONE; // ignore fLast
+                                       fLast = NONE; // ignore fLast
                                        if (fTokenLength > 0)
-                                               return preFix(JAVA, CHARACTER, NONE, 1);
-                                       else {                                          
-                                               preFix(JAVA, CHARACTER, NONE, 1);
+                                               return preFix(PHP, STRING_SQ, NONE, 1);
+                                       else {
+                                               preFix(PHP, STRING_SQ, NONE, 1);
                                                fTokenOffset += fTokenLength;
-                                               fTokenLength= fPrefixLength;
+                                               fTokenLength = fPrefixLength;
                                                break;
                                        }
 
                                case '"':
-                                       fLast= NONE; // ignore fLast                            
+                                       fLast = NONE; // ignore fLast
                                        if (fTokenLength > 0)
-                                               return preFix(JAVA, STRING, NONE, 1);
+                                               return preFix(PHP, STRING_DQ, NONE, 1);
                                        else {
-                                               preFix(JAVA, STRING, NONE, 1);
+                                               preFix(PHP, STRING_DQ, NONE, 1);
                                                fTokenOffset += fTokenLength;
-                                               fTokenLength= fPrefixLength;
+                                               fTokenLength = fPrefixLength;
                                                break;
                                        }
-       
+
                                default:
                                        consume();
                                        break;
                                }
                                break;
-       
-                       case SINGLE_LINE_COMMENT:
+
+                       case SINGLE_LINE_COMMENT:
                                consume();
                                break;
-                               
-                       case JAVADOC:
+
+                       case PHPDOC:
                                switch (ch) {
                                case '/':
                                        switch (fLast) {
                                        case SLASH_STAR_STAR:
                                                return postFix(MULTI_LINE_COMMENT);
-       
+
                                        case STAR:
-                                               return postFix(JAVADOC);
+                                               return postFix(PHPDOC);
 
                                        default:
                                                consume();
@@ -301,7 +356,7 @@ public class FastJavaPartitionScanner implements IPartitionTokenScanner {
 
                                case '*':
                                        fTokenLength++;
-                                       fLast= STAR;
+                                       fLast = STAR;
                                        break;
 
                                default:
@@ -309,20 +364,20 @@ public class FastJavaPartitionScanner implements IPartitionTokenScanner {
                                        break;
                                }
                                break;
-       
-                       case MULTI_LINE_COMMENT:
+
+                       case MULTI_LINE_COMMENT:
                                switch (ch) {
                                case '*':
                                        if (fLast == SLASH_STAR) {
-                                               fLast= SLASH_STAR_STAR;
+                                               fLast = SLASH_STAR_STAR;
                                                fTokenLength++;
-                                               fState= JAVADOC;
+                                               fState = PHPDOC;
                                        } else {
                                                fTokenLength++;
-                                               fLast= STAR;
+                                               fLast = STAR;
                                        }
                                        break;
-       
+
                                case '/':
                                        if (fLast == STAR) {
                                                return postFix(MULTI_LINE_COMMENT);
@@ -330,59 +385,79 @@ public class FastJavaPartitionScanner implements IPartitionTokenScanner {
                                                consume();
                                                break;
                                        }
-       
+
                                default:
                                        consume();
-                                       break;                  
+                                       break;
                                }
                                break;
-                               
-                       case STRING:
-                               switch (ch) {
-                               case '\\':
-                                       fLast= (fLast == BACKSLASH) ? NONE : BACKSLASH;
+
+                       case STRING_DQ:
+                               switch (ch) {
+                               case '\\':
+                                       fLast = (fLast == BACKSLASH) ? NONE : BACKSLASH;
                                        fTokenLength++;
                                        break;
-                                       
-                               case '\"':                                                      
-                                       if (fLast != BACKSLASH) {
-                                               return postFix(STRING);
 
-                                       } else {
+                               case '\"':
+                                       if (fLast != BACKSLASH) {
+                                               return postFix(STRING_DQ);
+
+                                       } else {
                                                consume();
-                                               break;                                  
-                                       }
-                               
-                               default:
+                                               break;
+                                       }
+
+                               default:
                                        consume();
-                                       break;
-                               }
-                               break;
-       
-                       case CHARACTER:
-                               switch (ch) {
+                                       break;
+                               }
+                               break;
+                       case STRING_SQ:
+                               switch (ch) {
                                case '\\':
-                                       fLast= (fLast == BACKSLASH) ? NONE : BACKSLASH;
+                                       fLast = (fLast == BACKSLASH) ? NONE : BACKSLASH;
                                        fTokenLength++;
                                        break;
-       
-                               case '\'':
-                                       if (fLast != BACKSLASH) {
-                                               return postFix(CHARACTER);
-       
-                                       } else {
+
+                               case '\'':
+                                       if (fLast != BACKSLASH) {
+                                               return postFix(STRING_SQ);
+
+                                       } else {
                                                consume();
-                                               break;
-                                       }
-       
-                               default:
+                                               break;
+                                       }
+
+                               default:
                                        consume();
-                                       break;
-                               }
-                               break;
-                       }
-               } 
-       }               
+                                       break;
+                               }
+                               break;
+                       // case CHARACTER:
+                       // switch (ch) {
+                       // case '\\':
+                       // fLast= (fLast == BACKSLASH) ? NONE : BACKSLASH;
+                       // fTokenLength++;
+                       // break;
+                       //
+                       // case '\'':
+                       // if (fLast != BACKSLASH) {
+                       // return postFix(CHARACTER);
+                       //
+                       // } else {
+                       // consume();
+                       // break;
+                       // }
+                       //
+                       // default:
+                       // consume();
+                       // break;
+                       // }
+                       // break;
+                       }
+               }
+       }
 
        private static final int getLastLength(int last) {
                switch (last) {
@@ -391,7 +466,7 @@ public class FastJavaPartitionScanner implements IPartitionTokenScanner {
 
                case NONE:
                        return 0;
-                       
+
                case CARRIAGE_RETURN:
                case BACKSLASH:
                case SLASH:
@@ -403,40 +478,40 @@ public class FastJavaPartitionScanner implements IPartitionTokenScanner {
 
                case SLASH_STAR_STAR:
                        return 3;
-               }       
+               }
        }
 
        private final void consume() {
                fTokenLength++;
-               fLast= NONE;    
+               fLast = NONE;
        }
-       
+
        private final IToken postFix(int state) {
                fTokenLength++;
-               fLast= NONE;
-               fState= JAVA;
-               fPrefixLength= 0;               
+               fLast = NONE;
+               fState = PHP;
+               fPrefixLength = 0;
                return fTokens[state];
        }
 
        private final IToken preFix(int state, int newState, int last, int prefixLength) {
                // emulate JavaPartitionScanner
-               if (fgEmulate && state == JAVA && (fTokenLength - getLastLength(fLast) > 0)) {
+               if (fEmulate && state == PHP && (fTokenLength - getLastLength(fLast) > 0)) {
                        fTokenLength -= getLastLength(fLast);
-                       fJavaOffset= fTokenOffset;
-                       fJavaLength= fTokenLength;
-                       fTokenLength= 1;
-                       fState= newState;
-                       fPrefixLength= prefixLength;
-                       fLast= last;
+                       fJavaOffset = fTokenOffset;
+                       fJavaLength = fTokenLength;
+                       fTokenLength = 1;
+                       fState = newState;
+                       fPrefixLength = prefixLength;
+                       fLast = last;
                        return fTokens[state];
 
                } else {
                        fTokenLength -= getLastLength(fLast);
-                       fLast= last;
-                       fPrefixLength= prefixLength;
-                       IToken token= fTokens[state];           
-                       fState= newState;
+                       fLast = last;
+                       fPrefixLength = prefixLength;
+                       IToken token = fTokens[state];
+                       fState = newState;
                        return token;
                }
        }
@@ -444,49 +519,56 @@ public class FastJavaPartitionScanner implements IPartitionTokenScanner {
        private static int getState(String contentType) {
 
                if (contentType == null)
-                       return JAVA;
+                       return PHP;
 
-               else if (contentType.equals(JAVA_SINGLE_LINE_COMMENT))
+               else if (contentType.equals(PHP_SINGLELINE_COMMENT))
                        return SINGLE_LINE_COMMENT;
 
-               else if (contentType.equals(JAVA_MULTI_LINE_COMMENT))
+               else if (contentType.equals(PHP_MULTILINE_COMMENT))
                        return MULTI_LINE_COMMENT;
 
-               else if (contentType.equals(JAVA_DOC))
-                       return JAVADOC;
+               else if (contentType.equals(PHP_PHPDOC_COMMENT))
+                       return PHPDOC;
+
+               else if (contentType.equals(PHP_STRING_DQ))
+                       return STRING_DQ;
 
-               else if (contentType.equals(JAVA_STRING))
-                       return STRING;
+               else if (contentType.equals(PHP_STRING_SQ))
+                       return STRING_SQ;
+
+               else if (contentType.equals(PHP_STRING_HEREDOC))
+                       return STRING_HEREDOC;
+
+               // else if (contentType.equals(JAVA_CHARACTER))
+               // return CHARACTER;
 
-               else if (contentType.equals(SKIP))
-                       return CHARACTER;
-                       
                else
-                       return JAVA;
+                       return PHP;
        }
 
        /*
-        * @see IPartitionTokenScanner#setPartialRange(IDocument, int, int, String, int)
+        * @see IPartitionTokenScanner#setPartialRange(IDocument, int, int, String,
+        *      int)
         */
        public void setPartialRange(IDocument document, int offset, int length, String contentType, int partitionOffset) {
-
                fScanner.setRange(document, offset, length);
-               fTokenOffset= partitionOffset;
-               fTokenLength= 0;
-               fPrefixLength= offset - partitionOffset;
-               fLast= NONE;
-               
+               setRange(document, offset, length);
+               fTokenOffset = partitionOffset;
+               fTokenLength = 0;
+               fPrefixLength = offset - partitionOffset;
+               fLast = NONE;
+
                if (offset == partitionOffset) {
                        // restart at beginning of partition
-                       fState= JAVA;
+                       fState = PHP;
                } else {
-                       fState= getState(contentType);                  
+                       fState = getState(contentType);
                }
 
                // emulate JavaPartitionScanner
-               if (fgEmulate) {
-                       fJavaOffset= -1;
-                       fJavaLength= 0;
+               if (fEmulate) {
+                       fJavaOffset = -1;
+                       fJavaLength = 0;
                }
        }
 
@@ -494,18 +576,17 @@ public class FastJavaPartitionScanner implements IPartitionTokenScanner {
         * @see ITokenScanner#setRange(IDocument, int, int)
         */
        public void setRange(IDocument document, int offset, int length) {
-
                fScanner.setRange(document, offset, length);
-               fTokenOffset= offset;
-               fTokenLength= 0;                
-               fPrefixLength= 0;
-               fLast= NONE;
-               fState= JAVA;
+               fTokenOffset = offset;
+               fTokenLength = 0;
+               fPrefixLength = 0;
+               fLast = NONE;
+               fState = PHP;
 
                // emulate JavaPartitionScanner
-               if (fgEmulate) {
-                       fJavaOffset= -1;
-                       fJavaLength= 0;
+               if (fEmulate) {
+                       fJavaOffset = -1;
+                       fJavaLength = 0;
                }
        }
 
@@ -520,7 +601,10 @@ public class FastJavaPartitionScanner implements IPartitionTokenScanner {
         * @see ITokenScanner#getTokenOffset()
         */
        public int getTokenOffset() {
+               if (AbstractPartitioner.DEBUG) {
+                       Assert.isTrue(fTokenOffset >= 0, Integer.toString(fTokenOffset));
+               }
                return fTokenOffset;
        }
 
-}
+}
\ No newline at end of file