/********************************************************************** Copyright (c) 2000, 2002 IBM Corp. 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 implementation Klaus Hartlage - www.eclipseproject.de **********************************************************************/ package net.sourceforge.phpeclipse.phpeditor.php; import java.util.ArrayList; import java.util.List; import org.eclipse.jface.text.rules.EndOfLineRule; import org.eclipse.jface.text.rules.ICharacterScanner; import org.eclipse.jface.text.rules.IPredicateRule; import org.eclipse.jface.text.rules.IRule; import org.eclipse.jface.text.rules.IToken; import org.eclipse.jface.text.rules.IWordDetector; import org.eclipse.jface.text.rules.MultiLineRule; import org.eclipse.jface.text.rules.RuleBasedPartitionScanner; import org.eclipse.jface.text.rules.RuleBasedScanner; import org.eclipse.jface.text.rules.SingleLineRule; import org.eclipse.jface.text.rules.Token; import org.eclipse.jface.text.rules.WordRule; /** * This scanner recognizes the JavaDoc comments and Java multi line comments. */ 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 JAVA_DOC= "__java_javadoc"; //$NON-NLS-1$ public final static String PHP = "__php"; public class PHPMultiLineRule extends MultiLineRule { public PHPMultiLineRule(String startSequence, String endSequence, IToken token) { super(startSequence, endSequence, token); } public PHPMultiLineRule(String startSequence, String endSequence, IToken token, char escapeCharacter) { super(startSequence, endSequence, token, escapeCharacter); } protected boolean endSequenceDetected(ICharacterScanner scanner) { int c; int c2; boolean lineCommentMode = false; boolean multiLineCommentMode = false; boolean stringMode = false; char[][] delimiters = scanner.getLegalLineDelimiters(); while ((c = scanner.read()) != ICharacterScanner.EOF) { if (c == '\n') { lineCommentMode = false; // read until end of line } else if (c == '#') { // read until end of line lineCommentMode = true; continue; } else if (c == '/') { c2 = scanner.read(); if (c2 == '/') { lineCommentMode = true; continue; } else if(c2 == '*') { multiLineCommentMode = true; continue; } else { scanner.unread(); } } else if (c == '*' && multiLineCommentMode) { c2 = scanner.read(); if (c2 == '/') { multiLineCommentMode = false; continue; } else { scanner.unread(); } } else if (c == '\\' && stringMode) { c2 = scanner.read(); if (c2 == '"') { continue; } else { scanner.unread(); } } else if (c == '"') { if (stringMode) { stringMode = false; } else { stringMode = true; } continue; } if (lineCommentMode || multiLineCommentMode || stringMode) { continue; } if (c == fEscapeCharacter) { // Skip the escaped character. scanner.read(); } else 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 (fBreaksOnEOL) { // Check for end of line since it can be used to terminate the pattern. for (int i = 0; i < delimiters.length; i++) { if (c == delimiters[i][0] && sequenceDetected(scanner, delimiters[i], false)) return true; } } } scanner.unread(); return true; } } /** * Detector for empty comments. */ static class EmptyCommentDetector implements IWordDetector { /* (non-Javadoc) * Method declared on IWordDetector */ public boolean isWordStart(char c) { return (c == '/'); } /* (non-Javadoc) * Method declared on IWordDetector */ public boolean isWordPart(char c) { return (c == '*' || c == '/'); } }; /** * */ static class WordPredicateRule extends WordRule implements IPredicateRule { private IToken fSuccessToken; public WordPredicateRule(IToken successToken) { super(new EmptyCommentDetector()); fSuccessToken = successToken; addWord("/**/", fSuccessToken); } /* * @see org.eclipse.jface.text.rules.IPredicateRule#evaluate(ICharacterScanner, boolean) */ public IToken evaluate(ICharacterScanner scanner, boolean resume) { return super.evaluate(scanner); } /* * @see org.eclipse.jface.text.rules.IPredicateRule#getSuccessToken() */ public IToken getSuccessToken() { return fSuccessToken; } }; /** * Creates the partitioner and sets up the appropriate rules. */ public PHPPartitionScanner() { super(); // IToken javaDoc= new Token(JAVA_DOC); IToken comment = new Token(JAVA_MULTILINE_COMMENT); IToken php = new Token(PHP); List rules = new ArrayList(); // Add rule for single line comments. // rules.add(new EndOfLineRule("//", Token.UNDEFINED)); // Add rule for strings and character constants. // rules.add(new SingleLineRule("\"", "\"", Token.UNDEFINED, '\\')); // rules.add(new SingleLineRule("'", "'", Token.UNDEFINED, '\\')); // Add special case word rule. rules.add(new WordPredicateRule(comment)); // Add rules for multi-line comments and javadoc. //rules.add(new MultiLineRule("/**", "*/", javaDoc)); rules.add(new MultiLineRule("", comment)); rules.add(new PHPMultiLineRule("", php)); rules.add(new PHPMultiLineRule("", php)); rules.add(new PHPMultiLineRule("", php)); //Add rule for processing instructions IPredicateRule[] result = new IPredicateRule[rules.size()]; rules.toArray(result); setPredicateRules(result); } }