From: axelcl Date: Sun, 15 May 2005 23:24:48 +0000 (+0000) Subject: Improved xml scanner for this bug X-Git-Url: http://git.phpeclipse.com?hp=535b4f479864063ce1d5f07fabc8a81c5d500684 Improved xml scanner for this bug See: http://garv.in/serendipity/archives/653-PHP-Eclipse-Bug.html --- diff --git a/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/PHPXMLPartitionScanner.java b/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/PHPXMLPartitionScanner.java new file mode 100644 index 0000000..37946aa --- /dev/null +++ b/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/PHPXMLPartitionScanner.java @@ -0,0 +1,557 @@ +/* + * Copyright (c) 2002-2004 Widespace, OU 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: + * Igor Malinin - initial contribution + * + * $Id: PHPXMLPartitionScanner.java,v 1.1 2005-05-15 23:23:02 axelcl Exp $ + */ + +package net.sourceforge.phpeclipse.xml.ui.internal.text; + +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.jface.text.Assert; +import org.eclipse.jface.text.BadLocationException; +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; + + +/** + * + * + * @author Igor Malinin + */ +public class PHPXMLPartitionScanner implements IPartitionTokenScanner { +// public static final String XML_PI = "__xml_processing_instruction"; + public static final String XML_COMMENT = "__xml_comment"; + public static final String XML_DECL = "__xml_declaration"; + public static final String XML_TAG = "__xml_tag"; + public static final String XML_ATTRIBUTE = "__xml_attribute"; + public static final String XML_CDATA = "__xml_cdata"; + + public static final String DTD_INTERNAL = "__dtd_internal"; +// public static final String DTD_INTERNAL_PI = "__dtd_internal_pi"; + public static final String DTD_INTERNAL_COMMENT = "__dtd_internal_comment"; + public static final String DTD_INTERNAL_DECL = "__dtd_internal_declaration"; + public static final String DTD_CONDITIONAL = "__dtd_conditional"; + + public static final int STATE_DEFAULT = 0; + public static final int STATE_TAG = 1; + public static final int STATE_DECL = 2; + public static final int STATE_CDATA = 4; + + public static final int STATE_INTERNAL = 8; + + protected IDocument document; + protected int end; + + protected int offset; + protected int length; + + protected int position; + protected int state; + + protected boolean parsedtd; + + protected Map tokens = new HashMap(); + + public PHPXMLPartitionScanner(boolean parsedtd) { + this.parsedtd = parsedtd; + } + + /* + * @see org.eclipse.jface.text.rules.ITokenScanner#nextToken() + */ + public IToken nextToken() { + offset += length; + + switch (state) { + case STATE_TAG: + return nextTagToken(); + + case STATE_DECL: + return nextDeclToken(); + + case STATE_CDATA: + return nextCDATAToken(); + } + + switch (read()) { + case ICharacterScanner.EOF: + state = STATE_DEFAULT; + return getToken(null); + + case '<': + switch (read()) { + case ICharacterScanner.EOF: + if (parsedtd || isInternal()) { + break; + } + + state = STATE_DEFAULT; + return getToken(XML_TAG); + + case '?': // ': + state = STATE_DEFAULT; + return getToken(XML_TAG); + + case '"': case '\'': + while (true) { + int ch = read(); + + if (ch == quot) { + state = STATE_TAG; + return getToken(XML_ATTRIBUTE); + } + + switch (ch) { + case '<': + unread(); + + case ICharacterScanner.EOF: + state = STATE_DEFAULT; + return getToken(XML_ATTRIBUTE); + } + } + default: + unread(); + } + + while (true) { + switch (read()) { + case '<': + unread(); + + case ICharacterScanner.EOF: + case '>': + state = STATE_DEFAULT; + return getToken(XML_TAG); + + case '"': case '\'': + unread(); + + state = STATE_TAG; + return getToken(XML_TAG); + } + } + } + + private IToken nextDeclToken() { + loop: while (true) { + switch (read()) { + case ICharacterScanner.EOF: + state = STATE_DEFAULT; + return getToken(isInternal() ? DTD_INTERNAL_DECL : XML_DECL); + + case '<': + if (parsedtd || isInternal()) { + switch (read()) { + case ICharacterScanner.EOF: + state = STATE_DEFAULT; + return getToken(isInternal() ? DTD_INTERNAL : null); + + case '!': + case '?': + unread(); + break; + + default: + continue loop; + } + } + + unread(); + + case '>': + state &= STATE_INTERNAL; + return getToken(isInternal() ? DTD_INTERNAL_DECL : XML_DECL); + + case '[': // + if (!isInternal()) { + state = STATE_INTERNAL; + return getToken(XML_DECL); + } + } + } + } + + private IToken nextCommentToken() { + state &= STATE_INTERNAL; + + loop: while (true) { + switch (read()) { + case ICharacterScanner.EOF: + break loop; + + case '-': // - --> + switch (read()) { + case ICharacterScanner.EOF: + break loop; + + case '-': // -- --> + switch (read()) { + case ICharacterScanner.EOF: + case '>': + break loop; + } + + unread(); + break loop; + } + } + } + + return getToken(isInternal() ? DTD_INTERNAL_COMMENT : XML_COMMENT); + } + + private IToken nextCDATAToken() { + state = STATE_DEFAULT; + +loop: + while (true) { + switch (read()) { + case ICharacterScanner.EOF: + break loop; + + case ']': // ] ]]> + switch (read()) { + case ICharacterScanner.EOF: + break loop; + + case ']': // ]] ]]> + switch (read()) { + case ICharacterScanner.EOF: + case '>': // ]]> + break loop; + } + + unread(); + unread(); + continue loop; + } + } + } + + return getToken(XML_CDATA); + } + + private IToken nextConditionalToken() { + state = STATE_DEFAULT; + + int level = 1; + +loop: + while (true) { + switch (read()) { + case ICharacterScanner.EOF: + break loop; + + case '<': // - --> + switch (read()) { + case ICharacterScanner.EOF: + break loop; + + case '!': // -- --> + switch (read()) { + case ICharacterScanner.EOF: + break loop; + + case '[': + ++level; + continue loop; + } + + unread(); + continue loop; + } + + unread(); + continue loop; + + case ']': // - --> + switch (read()) { + case ICharacterScanner.EOF: + break loop; + + case ']': // -- --> + switch (read()) { + case ICharacterScanner.EOF: + case '>': + if (--level == 0) { + break loop; + } + + continue loop; + } + + unread(); + unread(); + continue loop; + } + } + } + + return getToken(DTD_CONDITIONAL); + } + + private IToken getToken(String type) { + length = position - offset; + + if (length == 0) { + return Token.EOF; + } + + if (type == null) { + return Token.UNDEFINED; + } + + IToken token = (IToken) tokens.get(type); + if (token == null) { + token = new Token(type); + tokens.put(type, token); + } + + return token; + } + + private boolean isInternal() { + return (state & STATE_INTERNAL) != 0; + } + + private int read() { + if (position >= end) { + return ICharacterScanner.EOF; + } + + try { + return document.getChar(position++); + } catch (BadLocationException e) { + --position; + return ICharacterScanner.EOF; + } + } + + private void unread() { + --position; + } + + /* + * @see org.eclipse.jface.text.rules.ITokenScanner#getTokenOffset() + */ + public int getTokenOffset() { + Assert.isTrue(offset>=0, Integer.toString(offset)); + return offset; + } + + /* + * @see org.eclipse.jface.text.rules.ITokenScanner#getTokenLength() + */ + public int getTokenLength() { + return length; + } + + /* + * @see org.eclipse.jface.text.rules.ITokenScanner#setRange(IDocument, int, int) + */ + public void setRange(IDocument document, int offset, int length) { + this.document = document; + this.end = offset + length; + + this.offset = offset; + this.position = offset; + this.length = 0; + + this.state = STATE_DEFAULT; + } + + /* + * @see org.eclipse.jface.text.rules.IPartitionTokenScanner + */ +// public void setPartialRange(IDocument document, int offset, int length, String contentType, int partitionOffset) { +// state = STATE_DEFAULT; +// if (partitionOffset > -1) { +// int delta = offset - partitionOffset; +// if (delta > 0) { +// setRange(document, partitionOffset, length + delta); +// return; +// } +// } +// setRange(document, partitionOffset, length); +// } + /* + * @see org.eclipse.jface.text.rules.IPartitionTokenScanner + */ + public void setPartialRange( + IDocument document, int offset, int length, + String contentType, int partitionOffset + ) { +// boolean flag = false; + this.document = document; + this.end = offset + length; + + // NB! Undocumented value: -1 + if (partitionOffset >= 0) { + offset = partitionOffset; +// flag = true; + } + + this.offset = offset; + this.position = offset; + this.length = 0; + +// if (flag) { +// state = STATE_DEFAULT; +// return; +// } + if (contentType == XML_ATTRIBUTE) { + state = STATE_TAG; + return; + } + + if (contentType == XML_TAG) { + state = isContinuationPartition() ? STATE_TAG : STATE_DEFAULT; + return; + } + + if (contentType == XML_DECL) { + state = isContinuationPartition() ? STATE_DECL : STATE_DEFAULT; + return; + } + + if (contentType == DTD_INTERNAL || + contentType == DTD_INTERNAL_DECL || + contentType == DTD_INTERNAL_COMMENT + ) { + state = STATE_INTERNAL; + return; + } + + state = STATE_DEFAULT; + } + + private boolean isContinuationPartition() { + try { + String type = document.getContentType(offset - 1); + + if (type != IDocument.DEFAULT_CONTENT_TYPE) { + return true; + } + } catch (BadLocationException e) {} + + return false; + } +} diff --git a/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/XMLPartitionScanner.java b/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/XMLPartitionScanner.java index 1064ca3..c74cc32 100644 --- a/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/XMLPartitionScanner.java +++ b/net.sourceforge.phpeclipse.xml.ui/src/net/sourceforge/phpeclipse/xml/ui/internal/text/XMLPartitionScanner.java @@ -8,7 +8,7 @@ * Contributors: * Igor Malinin - initial contribution * - * $Id: XMLPartitionScanner.java,v 1.2 2005-05-15 23:09:09 axelcl Exp $ + * $Id: XMLPartitionScanner.java,v 1.3 2005-05-15 23:23:02 axelcl Exp $ */ package net.sourceforge.phpeclipse.xml.ui.internal.text; @@ -101,9 +101,7 @@ public class XMLPartitionScanner implements IPartitionTokenScanner { return getToken(XML_TAG); case '?': // - // ch = read(); - // switch (ch) { - // case ICharacterScanner.EOF: - // break loop; - // - // case '-': // -- --%> - // ch = read(); - // switch (ch) { - // case ICharacterScanner.EOF: - // break loop; - // - // case '%': // --% --%> - // ch = read(); - // switch (ch) { - // case ICharacterScanner.EOF: - // case '>': - // break loop; - // } - // - // continue loop; - // - // case '-': // --- ---%> - // unread(); - // continue loop; - // } - // - // ch = read(); - // continue loop; - // } - // } - // - // ch = read(); - // } - // - // return getToken(JSP_COMMENT); - // } - private IToken getToken(String type) { length = position - offset; @@ -422,13 +359,13 @@ public class PHPPartitionScanner implements IPartitionTokenScanner { */ public void setPartialRange(IDocument document, int offset, int length, String contentType, int partitionOffset) { state = STATE_DEFAULT; - // if (partitionOffset > -1) { - // int delta= offset - partitionOffset; - // if (delta > 0) { - // this.setRange(document, partitionOffset, length + delta); - // return; - // } - // } + if (partitionOffset > -1) { + int delta = offset - partitionOffset; + if (delta > 0) { + setRange(document, partitionOffset, length + delta); + return; + } + } setRange(document, partitionOffset, length); } diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/php/PHPPartition_delete_it.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/php/PHPPartition_delete_it.java deleted file mode 100644 index 541079a..0000000 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/php/PHPPartition_delete_it.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Created on 28.04.2003 - * - */ -package net.sourceforge.phpeclipse.phpeditor.php; - -import net.sourceforge.phpdt.internal.ui.text.IPHPPartitions; - -import org.eclipse.jface.text.IDocument; - -/** - * @author slanger - * @version $Revision: 1.2 $ - */ -public class PHPPartition_delete_it extends Partition -{ - private boolean fShortTagsEnabled = true; - - /** - * @param document - * @param delim - * @param contentType - * @param parentPartition - */ - public PHPPartition_delete_it(IDocument document, String parentPartition) - { - super( - document, - new char[] { '<', '>' }, - IPHPPartitions.PHP_PARTITIONING, - parentPartition); - } - - - - /* (non-Javadoc) - * @see net.sourceforge.phpeclipse.phpeditor.php.Partition#allowedPartition(java.lang.String) - */ - protected boolean allowedPartition(String type) - { - if(type.equals(IPHPPartitions.PHP_PHPDOC_COMMENT)) - return true; - - return false; - } - - /* (non-Javadoc) - * @see net.sourceforge.phpeclipse.phpeditor.php.Partition#scan() - */ - protected boolean scan() - { - int ch; - if(fShortTagsEnabled && checkPattern("", true)) - { - int offset = getOffset(); - if(checkPattern("/*", true)) - { - unread(2); - return; - } - } - } -} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/php/SmartyCodeScanner.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/php/SmartyCodeScanner.java index 99b3235..9240bbd 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/php/SmartyCodeScanner.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/php/SmartyCodeScanner.java @@ -134,7 +134,8 @@ public class SmartyCodeScanner extends AbstractJavaScanner { IPreferenceConstants.PHP_KEYWORD, IPreferenceConstants.PHP_FUNCTIONNAME, IPreferenceConstants.PHP_VARIABLE, - IPreferenceConstants.PHP_STRING, + IPreferenceConstants.PHP_STRING_DQ, + IPreferenceConstants.PHP_STRING_SQ, IPreferenceConstants.PHP_TYPE, IPreferenceConstants.PHP_CONSTANT, IPreferenceConstants.PHP_DEFAULT }; @@ -159,7 +160,7 @@ public class SmartyCodeScanner extends AbstractJavaScanner { protected List createRules() { List rules = new ArrayList(); // Add rule for strings and character constants. - Token token = getToken(IPreferenceConstants.PHP_STRING); + Token token = getToken(IPreferenceConstants.PHP_STRING_DQ); rules.add(new MultiLineRule("\"", "\"", token, '\\')); //$NON-NLS-2$ //$NON-NLS-1$ // Add generic whitespace rule. diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/util/PHPColorProvider.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/util/PHPColorProvider.java index 24c25ee..6f05c78 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/util/PHPColorProvider.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/util/PHPColorProvider.java @@ -29,7 +29,8 @@ public class PHPColorProvider { public static final RGB KEYWORD = new RGB(127, 0, 85); public static final RGB VARIABLE = new RGB(127, 159, 191); public static final RGB FUNCTION_NAME = new RGB(127, 127, 159); - public static final RGB STRING = new RGB(42, 0, 255); + public static final RGB STRING_DQ = new RGB(42, 0, 255); + public static final RGB STRING_SQ = new RGB(42, 0, 255); public static final RGB DEFAULT = new RGB(0, 0, 0); public static final RGB TYPE = new RGB(127, 0, 85); public static final RGB CONSTANT = new RGB(127, 0, 85);