Detect <?= as PHP start tag
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / internal / compiler / parser / Scanner.java
index 4f2832e..a483ee4 100644 (file)
@@ -126,15 +126,16 @@ public class Scanner implements IScanner, ITerminalSymbols {
       charArray_v = new char[] { 'v' }, charArray_w = new char[] { 'w' }, charArray_x = new char[] { 'x' },
       charArray_y = new char[] { 'y' }, charArray_z = new char[] { 'z' };
 
-  static final char[] charArray_va = new char[] { '$', 'a' }, charArray_vb = new char[] { '$', 'b' }, charArray_vc = new char[] { '$', 'c' },
-      charArray_vd = new char[] { '$', 'd' }, charArray_ve = new char[] { '$', 'e' }, charArray_vf = new char[] { '$', 'f' },
-      charArray_vg = new char[] { '$', 'g' }, charArray_vh = new char[] { '$', 'h' }, charArray_vi = new char[] { '$', 'i' },
-      charArray_vj = new char[] { '$', 'j' }, charArray_vk = new char[] { '$', 'k' }, charArray_vl = new char[] { '$', 'l' },
-      charArray_vm = new char[] { '$', 'm' }, charArray_vn = new char[] { '$', 'n' }, charArray_vo = new char[] { '$', 'o' },
-      charArray_vp = new char[] { '$', 'p' }, charArray_vq = new char[] { '$', 'q' }, charArray_vr = new char[] { '$', 'r' },
-      charArray_vs = new char[] { '$', 's' }, charArray_vt = new char[] { '$', 't' }, charArray_vu = new char[] { '$', 'u' },
-      charArray_vv = new char[] { '$', 'v' }, charArray_vw = new char[] { '$', 'w' }, charArray_vx = new char[] { '$', 'x' },
-      charArray_vy = new char[] { '$', 'y' }, charArray_vz = new char[] { '$', 'z' };
+  static final char[] charArray_va = new char[] { '$', 'a' }, charArray_vb = new char[] { '$', 'b' }, charArray_vc = new char[] {
+      '$',
+      'c' }, charArray_vd = new char[] { '$', 'd' }, charArray_ve = new char[] { '$', 'e' },
+      charArray_vf = new char[] { '$', 'f' }, charArray_vg = new char[] { '$', 'g' }, charArray_vh = new char[] { '$', 'h' },
+      charArray_vi = new char[] { '$', 'i' }, charArray_vj = new char[] { '$', 'j' }, charArray_vk = new char[] { '$', 'k' },
+      charArray_vl = new char[] { '$', 'l' }, charArray_vm = new char[] { '$', 'm' }, charArray_vn = new char[] { '$', 'n' },
+      charArray_vo = new char[] { '$', 'o' }, charArray_vp = new char[] { '$', 'p' }, charArray_vq = new char[] { '$', 'q' },
+      charArray_vr = new char[] { '$', 'r' }, charArray_vs = new char[] { '$', 's' }, charArray_vt = new char[] { '$', 't' },
+      charArray_vu = new char[] { '$', 'u' }, charArray_vv = new char[] { '$', 'v' }, charArray_vw = new char[] { '$', 'w' },
+      charArray_vx = new char[] { '$', 'x' }, charArray_vy = new char[] { '$', 'y' }, charArray_vz = new char[] { '$', 'z' };
 
   static final char[] initCharArray = new char[] { '\u0000', '\u0000', '\u0000', '\u0000', '\u0000', '\u0000' };
 
@@ -212,9 +213,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);
@@ -322,6 +333,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;
   }
@@ -932,6 +950,10 @@ public class Scanner implements IScanner, ITerminalSymbols {
               withoutUnicodePtr--;
             }
           }
+        } else if ((currentCharacter == '\r') || (currentCharacter == '\n')) {
+          if (recordLineSeparator) {
+            pushLineSeparator();
+          }
         }
         // consume next character
         unicodeAsBackSlash = false;
@@ -1028,6 +1050,10 @@ public class Scanner implements IScanner, ITerminalSymbols {
               withoutUnicodePtr--;
             }
           }
+        } else if ((currentCharacter == '\r') || (currentCharacter == '\n')) {
+          if (recordLineSeparator) {
+            pushLineSeparator();
+          }
         }
         // consume next character
         unicodeAsBackSlash = false;
@@ -1124,6 +1150,10 @@ public class Scanner implements IScanner, ITerminalSymbols {
               withoutUnicodePtr--;
             }
           }
+        } else if ((currentCharacter == '\r') || (currentCharacter == '\n')) {
+          if (recordLineSeparator) {
+            pushLineSeparator();
+          }
         }
         // consume next character
         unicodeAsBackSlash = false;
@@ -1222,6 +1252,12 @@ public class Scanner implements IScanner, ITerminalSymbols {
                   }
                 }
                 break;
+              case '\r':
+              case '\n':
+                if (recordLineSeparator) {
+                  pushLineSeparator();
+                }
+                break;
               case '$':
                 if (isPHPIdentifierStart(source[currentPosition]) || source[currentPosition] == '{') {
                   currentPosition--;
@@ -1854,7 +1890,6 @@ public class Scanner implements IScanner, ITerminalSymbols {
    * @throws InvalidInputException
    */
   private int getInlinedHTMLToken(int start) throws InvalidInputException {
-    //    int htmlPosition = start;
     if (currentPosition > source.length) {
       currentPosition = source.length;
       return TokenNameEOF;
@@ -1866,7 +1901,10 @@ public class Scanner implements IScanner, ITerminalSymbols {
         if (currentCharacter == '<') {
           if (getNextChar('?')) {
             currentCharacter = source[currentPosition++];
-            if ((currentCharacter == ' ') || Character.isWhitespace(currentCharacter)) {
+            if ((currentCharacter != 'P') && (currentCharacter != 'p')) {
+              if (currentCharacter != '=') { // <?=
+                currentPosition--;
+              }
               // <?
               if (ignorePHPOneLiner) {
                 if (lookAheadLinePHPTag() == TokenNameINLINE_HTML) {
@@ -1878,25 +1916,25 @@ public class Scanner implements IScanner, ITerminalSymbols {
                 return TokenNameINLINE_HTML;
               }
             } else {
-              boolean phpStart = (currentCharacter == 'P') || (currentCharacter == 'p');
-              if (phpStart) {
-                int test = getNextChar('H', 'h');
+              //              boolean phpStart = (currentCharacter == 'P') || (currentCharacter == 'p');
+              //              if (phpStart) {
+              int test = getNextChar('H', 'h');
+              if (test >= 0) {
+                test = getNextChar('P', 'p');
                 if (test >= 0) {
-                  test = getNextChar('P', 'p');
-                  if (test >= 0) {
-                    // <?PHP <?php
-                    if (ignorePHPOneLiner) {
-                      if (lookAheadLinePHPTag() == TokenNameINLINE_HTML) {
-                        phpMode = true;
-                        return TokenNameINLINE_HTML;
-                      }
-                    } else {
+                  // <?PHP <?php
+                  if (ignorePHPOneLiner) {
+                    if (lookAheadLinePHPTag() == TokenNameINLINE_HTML) {
                       phpMode = true;
                       return TokenNameINLINE_HTML;
                     }
+                  } else {
+                    phpMode = true;
+                    return TokenNameINLINE_HTML;
                   }
                 }
               }
+              //              }
             }
           }
         }
@@ -2495,7 +2533,7 @@ public class Scanner implements IScanner, ITerminalSymbols {
       switch (c1) {
       case 'a':
         return charArray_va;
-      case 'b':  
+      case 'b':
         return charArray_vb;
       case 'c':
         return charArray_vc;
@@ -4235,8 +4273,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;
             }
           }
@@ -4253,8 +4291,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) {