X-Git-Url: http://git.phpeclipse.com diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/php/PHPPartitionScanner.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/php/PHPPartitionScanner.java index 43970cd..85aa0d2 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/php/PHPPartitionScanner.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/php/PHPPartitionScanner.java @@ -30,10 +30,21 @@ import org.eclipse.jface.text.rules.WordRule; public class PHPPartitionScanner extends RuleBasedPartitionScanner { private final static String SKIP = "__skip"; //$NON-NLS-1$ - public final static String JAVA_MULTILINE_COMMENT = "__html_multiline_comment"; //$NON-NLS-1$ + public final static String HTML_MULTILINE_COMMENT = "__html_multiline_comment"; //$NON-NLS-1$ // public final static String JAVA_DOC= "__java_javadoc"; //$NON-NLS-1$ public final static String PHP = "__php"; + // public final static String HTML = "__html"; + + public final static IToken php = new Token(PHP); + // public final static IToken html = new Token(HTML); + public final static IToken comment = new Token(HTML_MULTILINE_COMMENT); + + protected final static char[] php0EndSequence = { '<', '?' }; + protected final static char[] php1EndSequence = { '<', '?', 'p', 'h', 'p' }; + protected final static char[] php2EndSequence = { '<', '?', 'P', 'H', 'P' }; + private StringBuffer test; + public class PHPMultiLineRule extends MultiLineRule { public PHPMultiLineRule(String startSequence, String endSequence, IToken token) { @@ -54,48 +65,65 @@ public class PHPPartitionScanner extends RuleBasedPartitionScanner { char[][] delimiters = scanner.getLegalLineDelimiters(); while ((c = scanner.read()) != ICharacterScanner.EOF) { - if (lineCommentMode && (c == '\n')) { - lineCommentMode = false; + if (c == '#') { // read until end of line - } else if ((!stringMode) && (c == '#')) { - // read until end of line - lineCommentMode = true; - continue; - } else if ((!stringMode) && (!multiLineCommentMode) && (c == '/')) { - c2 = scanner.read(); - if (c2 == '/') { - lineCommentMode = true; - continue; - } else if (c2 == '*') { - multiLineCommentMode = true; - continue; - } else { - scanner.unread(); + while ((c = scanner.read()) != ICharacterScanner.EOF) { + if (fEndSequence.length > 0 && c == fEndSequence[0]) { + // Check if the specified end sequence has been found. + if (sequenceDetected(scanner, fEndSequence, true)) + return true; + } else if (c == '\n') { + break; + } } - } else if (c == '*' && multiLineCommentMode) { - c2 = scanner.read(); - if (c2 == '/') { - multiLineCommentMode = false; + continue; + } else if (c == '/' && (c = scanner.read()) != ICharacterScanner.EOF) { + if (c == '/') { + // read until end of line + while ((c = scanner.read()) != ICharacterScanner.EOF) { + if (fEndSequence.length > 0 && c == fEndSequence[0]) { + // Check if the specified end sequence has been found. + if (sequenceDetected(scanner, fEndSequence, true)) + return true; + } else if (c == '\n') { + break; + } + } continue; - } else { - scanner.unread(); - } - } else if (c == '\\' && stringMode) { - c2 = scanner.read(); - if (c2 == '"') { + } else if (c == '*') { + // multi-line comment + while ((c = scanner.read()) != ICharacterScanner.EOF) { + if (c == '*' && (c = scanner.read()) != ICharacterScanner.EOF) { + if (c == '/') { + break; + } + scanner.unread(); + } + } + continue; } else { scanner.unread(); } - } else if ((!lineCommentMode) && (!multiLineCommentMode) && (c == '"')) { - if (stringMode) { - stringMode = false; - } else { - stringMode = true; + } else if (c == '"') { + // string mode + while ((c = scanner.read()) != ICharacterScanner.EOF) { + if (c == '\\') { + c = scanner.read(); + } else if (c == '"') { + break; + } } continue; - } - if (lineCommentMode || multiLineCommentMode || stringMode) { + } else if (c == '\'') { + // string mode + while ((c = scanner.read()) != ICharacterScanner.EOF) { + if (c == '\\') { + c = scanner.read(); + } else if (c == '\'') { + break; + } + } continue; } @@ -113,10 +141,293 @@ public class PHPPartitionScanner extends RuleBasedPartitionScanner { return true; } } + } + boolean phpMode = false; + if (c == ICharacterScanner.EOF) { + phpMode = true; + } + scanner.unread(); + return phpMode; + } + } + + // public class HTMLMultiLineRule extends MultiLineRule { + // + // public HTMLMultiLineRule(String startSequence, String endSequence, IToken token) { + // super(startSequence, endSequence, token); + // } + // + // public HTMLMultiLineRule(String startSequence, String endSequence, IToken token, char escapeCharacter) { + // super(startSequence, endSequence, token, escapeCharacter); + // } + // + // protected boolean endSequenceDetected(ICharacterScanner scanner) { + // int c; + // + // char[][] delimiters = scanner.getLegalLineDelimiters(); + // while ((c = scanner.read()) != ICharacterScanner.EOF) { + // if (c == '<') { + // // scanner.unread(); + // if (sequenceDetected(scanner, php2EndSequence, true)) { + // // null is a legal value + * @param token the token which will be returned on success + * @param escapeCharacter any character following this one will be ignored + * @param indicates whether the end of the line also termines the pattern + */ + public HTMLPatternRule(IToken token) { + fToken = token; + fEscapeCharacter = (char) 0; + fBreaksOnEOL = false; + } + + /** + * Sets a column constraint for this rule. If set, the rule's token + * will only be returned if the pattern is detected starting at the + * specified column. If the column is smaller then 0, the column + * constraint is considered removed. + * + * @param column the column in which the pattern starts + */ + public void setColumnConstraint(int column) { + if (column < 0) + column = UNDEFINED; + fColumn = column; + } + + /** + * Evaluates this rules without considering any column constraints. + * + * @param scanner the character scanner to be used + * @return the token resulting from this evaluation + */ + protected IToken doEvaluate(ICharacterScanner scanner) { + return doEvaluate(scanner, false); + } + + /** + * Evaluates this rules without considering any column constraints. Resumes + * detection, i.e. look sonly for the end sequence required by this rule if the + * resume flag is set. + * + * @param scanner the character scanner to be used + * @param resume true if detection should be resumed, false otherwise + * @return the token resulting from this evaluation + * @since 2.0 + */ + protected IToken doEvaluate(ICharacterScanner scanner, boolean resume) { + + if (resume) { + + if (endSequenceDetected(scanner)) + return fToken; + + } else { + + int c = scanner.read(); + // if (c == fStartSequence[0]) { + // if (sequenceDetected(scanner, fStartSequence, false)) { + if (endSequenceDetected(scanner)) + return fToken; + // } + // } } + scanner.unread(); + return Token.UNDEFINED; + } + + /* + * @see IRule#evaluate + */ + public IToken evaluate(ICharacterScanner scanner) { + return evaluate(scanner, false); + } + + /** + * Returns whether the end sequence was detected. As the pattern can be considered + * ended by a line delimiter, the result of this method is true if the + * rule breaks on the end of the line, or if the EOF character is read. + * + * @param scanner the character scanner to be used + * @return true if the end sequence has been detected + */ + protected boolean endSequenceDetected(ICharacterScanner scanner) { + int c; + + char[][] delimiters = scanner.getLegalLineDelimiters(); + while ((c = scanner.read()) != ICharacterScanner.EOF) { + if (c == '<') { + // scanner.unread(); + if (sequenceDetected(scanner, php2EndSequence, true)) { + // true if the given sequence has been detected + */ + protected boolean sequenceDetected(ICharacterScanner scanner, char[] sequence, boolean eofAllowed) { + for (int i = 1; i < sequence.length; i++) { + int c = scanner.read(); + if (c == ICharacterScanner.EOF && eofAllowed) { + return true; + } else if (c != sequence[i]) { + // Non-matching character detected, rewind the scanner back to the start. + scanner.unread(); + for (int j = i - 1; j > 0; j--) + scanner.unread(); + return false; + } + } + return true; } + + /* + * @see IPredicateRule#evaluate(ICharacterScanner, boolean) + * @since 2.0 + */ + public IToken evaluate(ICharacterScanner scanner, boolean resume) { + if (fColumn == UNDEFINED) + return doEvaluate(scanner, resume); + + int c = scanner.read(); + scanner.unread(); + // if (c == fStartSequence[0]) + return (fColumn == scanner.getColumn() ? doEvaluate(scanner, resume) : Token.UNDEFINED); + // else + // return Token.UNDEFINED; + } + + /* + * @see IPredicateRule#getSuccessToken() + * @since 2.0 + */ + public IToken getSuccessToken() { + return fToken; + } } /** * Detector for empty comments. @@ -172,9 +483,9 @@ public class PHPPartitionScanner extends RuleBasedPartitionScanner { public PHPPartitionScanner() { super(); - // IToken javaDoc= new Token(JAVA_DOC); - IToken comment = new Token(JAVA_MULTILINE_COMMENT); - IToken php = new Token(PHP); + // IToken php = new Token(PHP); + // IToken html = new Token(HTML); + // IToken comment = new Token(HTML_MULTILINE_COMMENT); List rules = new ArrayList(); @@ -186,10 +497,12 @@ public class PHPPartitionScanner extends RuleBasedPartitionScanner { // rules.add(new SingleLineRule("'", "'", Token.UNDEFINED, '\\')); // Add special case word rule. - rules.add(new WordPredicateRule(comment)); + // rules.add(new WordPredicateRule(comment)); // Add rules for multi-line comments and javadoc. //rules.add(new MultiLineRule("/**", "*/", javaDoc)); + // rules.add(new HTMLMultiLineRule("<", "", comment)); rules.add(new PHPMultiLineRule("", php)); rules.add(new PHPMultiLineRule("", php)); @@ -197,10 +510,67 @@ public class PHPPartitionScanner extends RuleBasedPartitionScanner { rules.add(new PHPMultiLineRule("", php)); rules.add(new PHPMultiLineRule("", php)); rules.add(new PHPMultiLineRule("", php)); + + // rules.add(new HTMLPatternRule(html)); // "<", "