Wrong partition length raises exception.
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / internal / compiler / parser / Scanner.java
index 4ed6bf2..2965347 100644 (file)
@@ -38,7 +38,9 @@ public class Scanner implements IScanner, ITerminalSymbols {
   public boolean ignorePHPOneLiner = false;
 
   public boolean phpMode = false;
-
+  
+  public boolean phpExpressionTag = false;
+  
   public Stack encapsedStringStack = null;
 
   public char currentCharacter;
@@ -213,9 +215,19 @@ public class Scanner implements IScanner, ITerminalSymbols {
   public ICompilationUnit compilationUnit = null;
 
   /**
+   * Determines if the specified character is permissible as the first character in a PHP identifier or variable
+   * 
+   * The '$' character for PHP variables is regarded as a correct first character !
+   *  
+   */
+  public static boolean isPHPIdentOrVarStart(char ch) {
+    return Character.isLetter(ch) || (ch == '$') || (ch == '_') || (0x7F <= ch && ch <= 0xFF);
+  }
+
+  /**
    * Determines if the specified character is permissible as the first character in a PHP identifier.
    * 
-   * The '$' character for HP variables isn't regarded as the first character !
+   * The '$' character for PHP variables isn't regarded as the first character !
    */
   public static boolean isPHPIdentifierStart(char ch) {
     return Character.isLetter(ch) || (ch == '_') || (0x7F <= ch && ch <= 0xFF);
@@ -323,6 +335,13 @@ public class Scanner implements IScanner, ITerminalSymbols {
     return result;
   }
 
+  public final char[] getRawTokenSourceEnd() {
+    int length = this.eofPosition - this.currentPosition - 1;
+    char[] sourceEnd = new char[length];
+    System.arraycopy(this.source, this.currentPosition, sourceEnd, 0, length);
+    return sourceEnd;
+  }
+
   public int getCurrentTokenStartPosition() {
     return this.startPosition;
   }
@@ -933,6 +952,10 @@ public class Scanner implements IScanner, ITerminalSymbols {
               withoutUnicodePtr--;
             }
           }
+        } else if ((currentCharacter == '\r') || (currentCharacter == '\n')) {
+          if (recordLineSeparator) {
+            pushLineSeparator();
+          }
         }
         // consume next character
         unicodeAsBackSlash = false;
@@ -1029,6 +1052,10 @@ public class Scanner implements IScanner, ITerminalSymbols {
               withoutUnicodePtr--;
             }
           }
+        } else if ((currentCharacter == '\r') || (currentCharacter == '\n')) {
+          if (recordLineSeparator) {
+            pushLineSeparator();
+          }
         }
         // consume next character
         unicodeAsBackSlash = false;
@@ -1125,6 +1152,10 @@ public class Scanner implements IScanner, ITerminalSymbols {
               withoutUnicodePtr--;
             }
           }
+        } else if ((currentCharacter == '\r') || (currentCharacter == '\n')) {
+          if (recordLineSeparator) {
+            pushLineSeparator();
+          }
         }
         // consume next character
         unicodeAsBackSlash = false;
@@ -1171,8 +1202,9 @@ public class Scanner implements IScanner, ITerminalSymbols {
   }
 
   public int getNextToken() throws InvalidInputException {
+    phpExpressionTag = false;
     if (!phpMode) {
-      return getInlinedHTML(currentPosition);
+      return getInlinedHTMLToken(currentPosition);
     }
     if (phpMode) {
       this.wasAcr = false;
@@ -1223,6 +1255,12 @@ public class Scanner implements IScanner, ITerminalSymbols {
                   }
                 }
                 break;
+              case '\r':
+              case '\n':
+                if (recordLineSeparator) {
+                  pushLineSeparator();
+                }
+                break;
               case '$':
                 if (isPHPIdentifierStart(source[currentPosition]) || source[currentPosition] == '{') {
                   currentPosition--;
@@ -1518,7 +1556,7 @@ public class Scanner implements IScanner, ITerminalSymbols {
                 phpMode = true;
                 return TokenNameINLINE_HTML;
               }
-              return getInlinedHTML(currentPosition - 2);
+              return getInlinedHTMLToken(currentPosition - 2);
             }
             return TokenNameQUESTION;
           case ':':
@@ -1817,39 +1855,6 @@ public class Scanner implements IScanner, ITerminalSymbols {
     return TokenNameEOF;
   }
 
-  private int getInlinedHTML(int start) throws InvalidInputException {
-    int token = getInlinedHTMLToken(start);
-    if (token == TokenNameINLINE_HTML) {
-      //               Stack stack = new Stack();
-      //               // scan html for errors
-      //               Source inlinedHTMLSource = new Source(new String(source, startPosition, currentPosition - startPosition));
-      //               int lastPHPEndPos=0;
-      //               for (Iterator i=inlinedHTMLSource.getNextTagIterator(0); i.hasNext();) {
-      //                   Tag tag=(Tag)i.next();
-      //                   
-      //                   if (tag instanceof StartTag) {
-      //                       StartTag startTag=(StartTag)tag;
-      //                     // System.out.println("startTag: "+tag);
-      //                       if (startTag.isServerTag()) {
-      //                         // TODO : what to do with a server tag ?
-      //                       } else {
-      //                           // do whatever with HTML start tag
-      //                           // use startTag.getElement() to find the element corresponding
-      //                           // to this start tag which may be useful if you implement code
-      //                           // folding etc
-      //                               stack.push(startTag);
-      //                       }
-      //                   } else {
-      //                       EndTag endTag=(EndTag)tag;
-      //                       StartTag stag = (StartTag) stack.peek();
-      //// System.out.println("endTag: "+tag);
-      //                       // do whatever with HTML end tag.
-      //                   }
-      //               }
-    }
-    return token;
-  }
-
   /**
    * @return
    * @throws InvalidInputException
@@ -1867,10 +1872,13 @@ public class Scanner implements IScanner, ITerminalSymbols {
           if (getNextChar('?')) {
             currentCharacter = source[currentPosition++];
             if ((currentCharacter != 'P') && (currentCharacter != 'p')) {
-              currentPosition--;
-              // (currentCharacter == ' ') || Character.isWhitespace(currentCharacter)) {
+              if (currentCharacter != '=') { // <?=
+                currentPosition--;
+              } else {
+                phpExpressionTag = true; 
+              }
               // <?
-              if (ignorePHPOneLiner) {
+              if (ignorePHPOneLiner) { // for CodeFormatter
                 if (lookAheadLinePHPTag() == TokenNameINLINE_HTML) {
                   phpMode = true;
                   return TokenNameINLINE_HTML;
@@ -1946,11 +1954,15 @@ public class Scanner implements IScanner, ITerminalSymbols {
             return TokenNameEOF;
           }
           break;
+        case '\\':
+          if (doubleQuotedStringActive) {
+            // ignore escaped characters in double quoted strings
+            previousCharInLine = currentCharInLine;
+            currentCharInLine = source[currentPositionInLine++];
+          }
         case '\"':
           if (doubleQuotedStringActive) {
-            if (previousCharInLine != '\\') {
-              doubleQuotedStringActive = false;
-            }
+            doubleQuotedStringActive = false;
           } else {
             if (!singleQuotedStringActive) {
               doubleQuotedStringActive = true;
@@ -4237,8 +4249,8 @@ public class Scanner implements IScanner, ITerminalSymbols {
             continue nextTag;
 
           // ensure tag is not leaded with letter if tag starts with a letter
-          if (Character.isJavaIdentifierStart(tag[0])) {
-            if (Character.isJavaIdentifierPart(previous)) {
+          if (Scanner.isPHPIdentifierStart(tag[0])) {
+            if (Scanner.isPHPIdentifierPart(previous)) {
               continue nextTag;
             }
           }
@@ -4255,8 +4267,8 @@ public class Scanner implements IScanner, ITerminalSymbols {
             }
           }
           // ensure tag is not followed with letter if tag finishes with a letter
-          if (i + tagLength < commentEnd && Character.isJavaIdentifierPart(src[i + tagLength - 1])) {
-            if (Character.isJavaIdentifierPart(src[i + tagLength]))
+          if (i + tagLength < commentEnd && Scanner.isPHPIdentifierPart(src[i + tagLength - 1])) {
+            if (Scanner.isPHPIdentifierPart(src[i + tagLength]))
               continue nextTag;
           }
           if (this.foundTaskTags == null) {