From: axelcl Date: Fri, 13 May 2005 20:19:43 +0000 (+0000) Subject: Wrong partition length raises exception. X-Git-Url: http://git.phpeclipse.com Wrong partition length raises exception. See: http://garv.in/serendipity/archives/653-PHP-Eclipse-Bug.html Nasty workaround, which prevents cursor from moveing backwards in the editor, but doesn't really solve the partitioning problem --- diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/php/DefaultPHPPartitioner_delete_it.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/php/DefaultPHPPartitioner_delete_it.java deleted file mode 100644 index d746edd..0000000 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/php/DefaultPHPPartitioner_delete_it.java +++ /dev/null @@ -1,845 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2004 IBM Corporation 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 API and implementation - *******************************************************************************/ -package net.sourceforge.phpeclipse.phpeditor.php; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.jface.text.Assert; -import org.eclipse.jface.text.BadLocationException; -import org.eclipse.jface.text.BadPositionCategoryException; -import org.eclipse.jface.text.DefaultPositionUpdater; -import org.eclipse.jface.text.DocumentEvent; -import org.eclipse.jface.text.IDocument; -import org.eclipse.jface.text.IDocumentPartitioner; -import org.eclipse.jface.text.IDocumentPartitionerExtension; -import org.eclipse.jface.text.IDocumentPartitionerExtension2; -import org.eclipse.jface.text.IRegion; -import org.eclipse.jface.text.ITypedRegion; -import org.eclipse.jface.text.Position; -import org.eclipse.jface.text.Region; -import org.eclipse.jface.text.TypedPosition; -import org.eclipse.jface.text.TypedRegion; -import org.eclipse.jface.text.rules.IPartitionTokenScanner; -import org.eclipse.jface.text.rules.IToken; - -/** - * A standard implementation of a document partitioner. It uses a partition token scanner to scan the document and to determine the - * document's partitioning. The tokens returned by the scanner are supposed to return the partition type as their data. The - * partitioner remembers the document's partitions in the document itself rather than maintaining its own data structure. - * - * @see IPartitionTokenScanner - * @since 2.0 - */ -public class DefaultPHPPartitioner_delete_it implements IDocumentPartitioner, IDocumentPartitionerExtension, IDocumentPartitionerExtension2 { - - /** - * The position category this partitioner uses to store the document's partitioning information. - * - * @deprecated As of 3.0, use getManagingPositionCategories() instead. - */ - public final static String CONTENT_TYPES_CATEGORY = "__content_types_category"; //$NON-NLS-1$ - - /** The HTML areas partitioner's scanner */ - protected IPartitionTokenScanner fHTMLScanner; - - /** The PHP areas partitioner's scanner */ - protected IPartitionTokenScanner fPHPScanner; - - /** The legal content types of both partitioners */ - protected String[] fLegalContentTypes; - - /** The legal content types of the HTML partitioner */ - protected String[] fLegalHTMLContentTypes; - - /** The legal content types of the PHP partitioner */ - protected String[] fLegalPHPContentTypes; - - /** The partitioner's document */ - protected IDocument fDocument; - - /** The document length before a document change occurred */ - protected int fPreviousDocumentLength; - - /** The position updater used to for the default updating of partitions */ - protected DefaultPositionUpdater fPositionUpdater; - - /** The offset at which the first changed partition starts */ - protected int fStartOffset; - - /** The offset at which the last changed partition ends */ - protected int fEndOffset; - - /** The offset at which a partition has been deleted */ - protected int fDeleteOffset; - - /** - * The position category this partitioner uses to store the document's partitioning information. - * - * @since 3.0 - */ - private String fPositionCategory; - - /** - * Creates a new partitioner that uses the given scanner and may return partitions of the given legal content types. - * - * @param scanner - * the scanner this partitioner is supposed to use - * @param legalContentTypes - * the legal content types of this partitioner - */ - public DefaultPHPPartitioner_delete_it(IPartitionTokenScanner htmlScanner, IPartitionTokenScanner phpScanner, String[] legalContentTypes, - String[] legalHTMLContentTypes, String[] legalPHPContentTypes) { - fHTMLScanner = htmlScanner; - fPHPScanner = phpScanner; - fLegalContentTypes = legalContentTypes; - fLegalHTMLContentTypes = legalHTMLContentTypes; - fLegalPHPContentTypes = legalPHPContentTypes; - - fPositionCategory = CONTENT_TYPES_CATEGORY + hashCode(); - fPositionUpdater = new DefaultPositionUpdater(fPositionCategory); - } - - /* - * @see org.eclipse.jface.text.IDocumentPartitionerExtension2#getManagingPositionCategories() - * @since 3.0 - */ - public String[] getManagingPositionCategories() { - return new String[] { fPositionCategory }; - } - - /* - * @see IDocumentPartitioner#connect(IDocument) - */ - public void connect(IDocument document) { - Assert.isNotNull(document); - Assert.isTrue(!document.containsPositionCategory(fPositionCategory)); - - fDocument = document; - fDocument.addPositionCategory(fPositionCategory); - - initialize(fDocument.getLength()); - } - - /** - * Performs the initial partitioning of the partitioner's document. - */ - protected void initialize(int initialLength) { - char ch; - boolean htmlMode = true; - int startPosition = 0; - int length = 0; - int i = 0; - try { - - while (i < initialLength) { - ch = fDocument.getChar(i++); - if (htmlMode) { - if (ch == '<' && fDocument.getChar(i) == '?' && fDocument.getChar(i + 1) == ' ') { - length = i - startPosition - 1; - if (length != 0) { - initializeHTML(startPosition, length); - startPosition = i - 1; - } - htmlMode = false; - } else if (ch == '<' && fDocument.getChar(i) == '?' - && (fDocument.getChar(i + 1) == 'p' || fDocument.getChar(i + 1) == 'P') - && (fDocument.getChar(i + 2) == 'h' || fDocument.getChar(i + 2) == 'H') - && (fDocument.getChar(i + 3) == 'p' || fDocument.getChar(i + 3) == 'P')) { - length = i - startPosition - 1; - if (length != 0) { - initializeHTML(startPosition, length); - startPosition = i - 1; - } - htmlMode = false; - } - } else { - switch (ch) { - case '"': // double quoted string - // read until end of double quoted string - while (i < fDocument.getLength()) { - if (fDocument.getChar(i++) == '"') { - if (fDocument.getChar(i - 2) != '\\') { - break; - } - } - } - break; - case '\'': // single quoted string - // read until end of single quoted string - while (i < fDocument.getLength()) { - if (fDocument.getChar(i++) == '\'') { - if (fDocument.getChar(i - 2) != '\\') { - break; - } - } - } - break; - case '/': // line comment - if (fDocument.getChar(i) == '/') { - i++; - // read until end of line - while (i < fDocument.getLength()) { - if (fDocument.getChar(i++) == '\n') { - break; - } - } - } else if (fDocument.getChar(i) == '*') { - i++; - // read until end of comment - while (i < fDocument.getLength()) { - if (fDocument.getChar(i++) == '*') { - if (i < fDocument.getLength()) { - if (fDocument.getChar(i) == '/') { - break; - } - } - } - } - } - break; - case '#': // line comment - // read until end of line - while (i < fDocument.getLength()) { - if (fDocument.getChar(i++) == '\n') { - break; - } - } - break; - case '?': - if (fDocument.getChar(i) == '>') { - length = i - startPosition + 1; - if (length != 0) { - initializePHP(startPosition, length); - startPosition = i + 1; - } - htmlMode = true; - } - break; - } - } - } - } catch (BadLocationException x) { - // can happen but ignored - } finally { - if (startPositionoffset is smaller than the - * remembered offset, offset will from now on be remembered. If offset + length is greater than the - * remembered end offset, it will be remembered from now on. - * - * @param offset - * the offset - * @param length - * the length - */ - private void rememberRegion(int offset, int length) { - // remember start offset - if (fStartOffset == -1) - fStartOffset = offset; - else if (offset < fStartOffset) - fStartOffset = offset; - - // remember end offset - int endOffset = offset + length; - if (fEndOffset == -1) - fEndOffset = endOffset; - else if (endOffset > fEndOffset) - fEndOffset = endOffset; - } - - /** - * Remembers the given offset as the deletion offset. - * - * @param offset - * the offset - */ - private void rememberDeletedOffset(int offset) { - fDeleteOffset = offset; - } - - /** - * Creates the minimal region containing all partition changes using the remembered offset, end offset, and deletion offset. - * - * @return the minimal region containing all the partition changes - */ - private IRegion createRegion() { - if (fDeleteOffset == -1) { - if (fStartOffset == -1 || fEndOffset == -1) - return null; - return new Region(fStartOffset, fEndOffset - fStartOffset); - } else if (fStartOffset == -1 || fEndOffset == -1) { - return new Region(fDeleteOffset, 0); - } else { - int offset = Math.min(fDeleteOffset, fStartOffset); - int endOffset = Math.max(fDeleteOffset, fEndOffset); - return new Region(offset, endOffset - offset); - } - } - - /* - * @see IDocumentPartitionerExtension#documentChanged2(DocumentEvent) - * @since 2.0 - */ - public IRegion documentChanged2(DocumentEvent e) { - - try { - - IDocument d = e.getDocument(); - Position[] category = d.getPositions(fPositionCategory); - IRegion line = d.getLineInformationOfOffset(e.getOffset()); - int reparseStart = line.getOffset(); - int partitionStart = -1; - String contentType = null; - int newLength = e.getText() == null ? 0 : e.getText().length(); - - int first = d.computeIndexInCategory(fPositionCategory, reparseStart); - if (first > 0) { - TypedPosition partition = (TypedPosition) category[first - 1]; - if (partition.includes(reparseStart)) { - partitionStart = partition.getOffset(); - contentType = partition.getType(); - if (e.getOffset() == partition.getOffset() + partition.getLength()) - reparseStart = partitionStart; - --first; - } else if (reparseStart == e.getOffset() && reparseStart == partition.getOffset() + partition.getLength()) { - partitionStart = partition.getOffset(); - contentType = partition.getType(); - reparseStart = partitionStart; - --first; - } else { - partitionStart = partition.getOffset() + partition.getLength(); - contentType = IDocument.DEFAULT_CONTENT_TYPE; - } - } - - fPositionUpdater.update(e); - for (int i = first; i < category.length; i++) { - Position p = category[i]; - if (p.isDeleted) { - rememberDeletedOffset(e.getOffset()); - break; - } - } - category = d.getPositions(fPositionCategory); - - - fHTMLScanner.setPartialRange(d, reparseStart, d.getLength() - reparseStart, contentType, partitionStart); - - int lastScannedPosition = reparseStart; - IToken token = fHTMLScanner.nextToken(); - - while (!token.isEOF()) { - - contentType = getTokenContentType(token); - - if (!isSupportedContentType(contentType)) { - token = fHTMLScanner.nextToken(); - continue; - } - - int start = fHTMLScanner.getTokenOffset(); - int length = fHTMLScanner.getTokenLength(); - - lastScannedPosition = start + length - 1; - - // remove all affected positions - while (first < category.length) { - TypedPosition p = (TypedPosition) category[first]; - if (lastScannedPosition >= p.offset + p.length - || (p.overlapsWith(start, length) && (!d.containsPosition(fPositionCategory, start, length) || !contentType.equals(p - .getType())))) { - - rememberRegion(p.offset, p.length); - d.removePosition(fPositionCategory, p); - ++first; - - } else - break; - } - - // if position already exists and we have scanned at least the - // area covered by the event, we are done - if (d.containsPosition(fPositionCategory, start, length)) { - if (lastScannedPosition >= e.getOffset() + newLength) - return createRegion(); - ++first; - } else { - // insert the new type position - try { - d.addPosition(fPositionCategory, new TypedPosition(start, length, contentType)); - rememberRegion(start, length); - } catch (BadPositionCategoryException x) { - } catch (BadLocationException x) { - } - } - - token = fHTMLScanner.nextToken(); - } - - // remove all positions behind lastScannedPosition since there aren't any further types - if (lastScannedPosition != reparseStart) { - // if this condition is not met, nothing has been scanned because of a deletion - ++lastScannedPosition; - } - first = d.computeIndexInCategory(fPositionCategory, lastScannedPosition); - - TypedPosition p; - while (first < category.length) { - p = (TypedPosition) category[first++]; - d.removePosition(fPositionCategory, p); - rememberRegion(p.offset, p.length); - } - - } catch (BadPositionCategoryException x) { - // should never happen on connected documents - } catch (BadLocationException x) { - } - - return createRegion(); - } - - /** - * Returns the position in the partitoner's position category which is close to the given offset. This is, the position has either - * an offset which is the same as the given offset or an offset which is smaller than the given offset. This method profits from - * the knowledge that a partitioning is a ordered set of disjoint position. - * - * @param offset - * the offset for which to search the closest position - * @return the closest position in the partitioner's category - */ - protected TypedPosition findClosestPosition(int offset) { - - try { - - int index = fDocument.computeIndexInCategory(fPositionCategory, offset); - Position[] category = fDocument.getPositions(fPositionCategory); - - if (category.length == 0) - return null; - - if (index < category.length) { - if (offset == category[index].offset) - return (TypedPosition) category[index]; - } - - if (index > 0) - index--; - - return (TypedPosition) category[index]; - - } catch (BadPositionCategoryException x) { - } catch (BadLocationException x) { - } - - return null; - } - - /* - * @see IDocumentPartitioner#getContentType(int) - */ - public String getContentType(int offset) { - - TypedPosition p = findClosestPosition(offset); - if (p != null && p.includes(offset)) - return p.getType(); - - return IDocument.DEFAULT_CONTENT_TYPE; - } - - /* - * @see IDocumentPartitioner#getPartition(int) - */ - public ITypedRegion getPartition(int offset) { - - try { - - Position[] category = fDocument.getPositions(fPositionCategory); - - if (category == null || category.length == 0) - return new TypedRegion(0, fDocument.getLength(), IDocument.DEFAULT_CONTENT_TYPE); - - int index = fDocument.computeIndexInCategory(fPositionCategory, offset); - - if (index < category.length) { - - TypedPosition next = (TypedPosition) category[index]; - - if (offset == next.offset) - return new TypedRegion(next.getOffset(), next.getLength(), next.getType()); - - if (index == 0) - return new TypedRegion(0, next.offset, IDocument.DEFAULT_CONTENT_TYPE); - - TypedPosition previous = (TypedPosition) category[index - 1]; - if (previous.includes(offset)) - return new TypedRegion(previous.getOffset(), previous.getLength(), previous.getType()); - - int endOffset = previous.getOffset() + previous.getLength(); - return new TypedRegion(endOffset, next.getOffset() - endOffset, IDocument.DEFAULT_CONTENT_TYPE); - } - - TypedPosition previous = (TypedPosition) category[category.length - 1]; - if (previous.includes(offset)) - return new TypedRegion(previous.getOffset(), previous.getLength(), previous.getType()); - - int endOffset = previous.getOffset() + previous.getLength(); - return new TypedRegion(endOffset, fDocument.getLength() - endOffset, IDocument.DEFAULT_CONTENT_TYPE); - - } catch (BadPositionCategoryException x) { - } catch (BadLocationException x) { - } - - return new TypedRegion(0, fDocument.getLength(), IDocument.DEFAULT_CONTENT_TYPE); - } - - /* - * @see IDocumentPartitioner#computePartitioning(int, int) - */ - public ITypedRegion[] computePartitioning(int offset, int length) { - return computePartitioning(offset, length, false); - } - - /* - * @see IDocumentPartitioner#getLegalContentTypes() - */ - public String[] getLegalContentTypes() { - return fLegalContentTypes; - } - - public String[] getLegalHTMLContentTypes() { - return fLegalHTMLContentTypes; - } - - public String[] getLegalPHPContentTypes() { - return fLegalPHPContentTypes; - } - - /** - * Returns whether the given type is one of the legal content types. - * - * @param contentType - * the content type to check - * @return true if the content type is a legal content type - */ - protected boolean isSupportedContentType(String contentType) { - if (contentType != null) { - for (int i = 0; i < fLegalContentTypes.length; i++) { - if (fLegalHTMLContentTypes[i].equals(contentType)) - return true; - } - } - - return false; - } - - /** - * Returns whether the given type is one of the legal content types. - * - * @param contentType - * the content type to check - * @return true if the content type is a legal content type - */ - protected boolean isSupportedHTMLContentType(String contentType) { - if (contentType != null) { - for (int i = 0; i < fLegalHTMLContentTypes.length; i++) { - if (fLegalHTMLContentTypes[i].equals(contentType)) - return true; - } - } - - return false; - } - - /** - * Returns whether the given type is one of the legal content types. - * - * @param contentType - * the content type to check - * @return true if the content type is a legal content type - */ - protected boolean isSupportedPHPContentType(String contentType) { - if (contentType != null) { - for (int i = 0; i < fLegalHTMLContentTypes.length; i++) { - if (fLegalHTMLContentTypes[i].equals(contentType)) - return true; - } - } - - return false; - } - - /** - * Returns a content type encoded in the given token. If the token's data is not null and a string it is assumed - * that it is the encoded content type. - * - * @param token - * the token whose content type is to be determined - * @return the token's content type - */ - protected String getTokenContentType(IToken token) { - Object data = token.getData(); - if (data instanceof String) - return (String) data; - return null; - } - - /* zero-length partition support */ - - /* - * @see org.eclipse.jface.text.IDocumentPartitionerExtension2#getContentType(int) - * @since 3.0 - */ - public String getContentType(int offset, boolean preferOpenPartitions) { - return getPartition(offset, preferOpenPartitions).getType(); - } - - /* - * @see org.eclipse.jface.text.IDocumentPartitionerExtension2#getPartition(int) - * @since 3.0 - */ - public ITypedRegion getPartition(int offset, boolean preferOpenPartitions) { - ITypedRegion region = getPartition(offset); - if (preferOpenPartitions) { - if (region.getOffset() == offset && !region.getType().equals(IDocument.DEFAULT_CONTENT_TYPE)) { - if (offset > 0) { - region = getPartition(offset - 1); - if (region.getType().equals(IDocument.DEFAULT_CONTENT_TYPE)) - return region; - } - return new TypedRegion(offset, 0, IDocument.DEFAULT_CONTENT_TYPE); - } - } - return region; - } - - /* - * @see org.eclipse.jface.text.IDocumentPartitionerExtension2#computePartitioning(int, int, boolean) - * @since 3.0 - */ - public ITypedRegion[] computePartitioning(int offset, int length, boolean includeZeroLengthPartitions) { - List list = new ArrayList(); - - try { - - int endOffset = offset + length; - - Position[] category = fDocument.getPositions(fPositionCategory); - - TypedPosition previous = null, current = null; - int start, end, gapOffset; - Position gap = new Position(0); - - int startIndex = getFirstIndexEndingAfterOffset(category, offset); - int endIndex = getFirstIndexStartingAfterOffset(category, endOffset); - for (int i = startIndex; i < endIndex; i++) { - - current = (TypedPosition) category[i]; - - gapOffset = (previous != null) ? previous.getOffset() + previous.getLength() : 0; - gap.setOffset(gapOffset); - gap.setLength(current.getOffset() - gapOffset); - if ((includeZeroLengthPartitions && overlapsOrTouches(gap, offset, length)) - || (gap.getLength() > 0 && gap.overlapsWith(offset, length))) { - start = Math.max(offset, gapOffset); - end = Math.min(endOffset, gap.getOffset() + gap.getLength()); - list.add(new TypedRegion(start, end - start, IDocument.DEFAULT_CONTENT_TYPE)); - } - - if (current.overlapsWith(offset, length)) { - start = Math.max(offset, current.getOffset()); - end = Math.min(endOffset, current.getOffset() + current.getLength()); - list.add(new TypedRegion(start, end - start, current.getType())); - } - - previous = current; - } - - if (previous != null) { - gapOffset = previous.getOffset() + previous.getLength(); - gap.setOffset(gapOffset); - gap.setLength(fDocument.getLength() - gapOffset); - if ((includeZeroLengthPartitions && overlapsOrTouches(gap, offset, length)) - || (gap.getLength() > 0 && gap.overlapsWith(offset, length))) { - start = Math.max(offset, gapOffset); - end = Math.min(endOffset, fDocument.getLength()); - list.add(new TypedRegion(start, end - start, IDocument.DEFAULT_CONTENT_TYPE)); - } - } - - if (list.isEmpty()) - list.add(new TypedRegion(offset, length, IDocument.DEFAULT_CONTENT_TYPE)); - - } catch (BadPositionCategoryException x) { - } - - TypedRegion[] result = new TypedRegion[list.size()]; - list.toArray(result); - return result; - } - - /** - * Returns true if the given ranges overlap with or touch each other. - * - * @param gap - * the first range - * @param offset - * the offset of the second range - * @param length - * the length of the second range - * @return true if the given ranges overlap with or touch each other - * @since 3.0 - */ - private boolean overlapsOrTouches(Position gap, int offset, int length) { - return gap.getOffset() <= offset + length && offset <= gap.getOffset() + gap.getLength(); - } - - /** - * Returns the index of the first position which ends after the given offset. - * - * @param positions - * the positions in linear order - * @param offset - * the offset - * @return the index of the first position which ends after the offset - * - * @since 3.0 - */ - private int getFirstIndexEndingAfterOffset(Position[] positions, int offset) { - int i = -1, j = positions.length; - while (j - i > 1) { - int k = (i + j) >> 1; - Position p = positions[k]; - if (p.getOffset() + p.getLength() > offset) - j = k; - else - i = k; - } - return j; - } - - /** - * Returns the index of the first position which starts at or after the given offset. - * - * @param positions - * the positions in linear order - * @param offset - * the offset - * @return the index of the first position which starts after the offset - * - * @since 3.0 - */ - private int getFirstIndexStartingAfterOffset(Position[] positions, int offset) { - int i = -1, j = positions.length; - while (j - i > 1) { - int k = (i + j) >> 1; - Position p = positions[k]; - if (p.getOffset() >= offset) - j = k; - else - i = k; - } - return j; - } -} \ No newline at end of file diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/php/PHPCodeScanner.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/php/PHPCodeScanner.java index bd6c715..250fdc1 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/php/PHPCodeScanner.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/php/PHPCodeScanner.java @@ -22,6 +22,7 @@ import net.sourceforge.phpeclipse.phpeditor.util.PHPWhitespaceDetector; import net.sourceforge.phpeclipse.phpeditor.util.PHPWordDetector; import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.jface.text.BadLocationException; import org.eclipse.jface.text.rules.EndOfLineRule; import org.eclipse.jface.text.rules.ICharacterScanner; import org.eclipse.jface.text.rules.IRule; @@ -31,6 +32,7 @@ import org.eclipse.jface.text.rules.MultiLineRule; import org.eclipse.jface.text.rules.Token; import org.eclipse.jface.text.rules.WhitespaceRule; import org.eclipse.jface.text.rules.WordRule; + /** * PHP Code Scanner */ @@ -159,6 +161,114 @@ public class PHPCodeScanner extends AbstractJavaScanner { } } + protected class SingleQuoteStringRule implements IRule { + + /** Token to return for this rule */ + private final IToken fToken; + + public SingleQuoteStringRule(IToken token) { + fToken = token; + + } + + /* + * @see org.eclipse.jface.text.rules.IRule#evaluate(org.eclipse.jface.text.rules.ICharacterScanner) + */ + public IToken evaluate(ICharacterScanner scanner) { + + int character = scanner.read(); + + if (character=='\'') { + + while (true) { + character = scanner.read(); + if (character == '\\') { + character = scanner.read(); + } else if (character == '\'') { + return fToken; + } + } + + } else { + scanner.unread(); + return Token.UNDEFINED; + } + } + + } + + protected class AccentStringRule implements IRule { + + /** Token to return for this rule */ + private final IToken fToken; + + public AccentStringRule(IToken token) { + fToken = token; + + } + + /* + * @see org.eclipse.jface.text.rules.IRule#evaluate(org.eclipse.jface.text.rules.ICharacterScanner) + */ + public IToken evaluate(ICharacterScanner scanner) { + + int character = scanner.read(); + + if (character=='`') { + + while (true) { + character = scanner.read(); + if (character == '\\') { + character = scanner.read(); + } else if (character == '`') { + return fToken; + } + } + + } else { + scanner.unread(); + return Token.UNDEFINED; + } + } + + } + + protected class DoubleQuoteStringRule implements IRule { + + /** Token to return for this rule */ + private final IToken fToken; + + public DoubleQuoteStringRule(IToken token) { + fToken = token; + + } + + /* + * @see org.eclipse.jface.text.rules.IRule#evaluate(org.eclipse.jface.text.rules.ICharacterScanner) + */ + public IToken evaluate(ICharacterScanner scanner) { + + int character = scanner.read(); + + if (character=='"') { + + while (true) { + character = scanner.read(); + if (character == '\\') { + character = scanner.read(); + } else if (character == '"') { + return fToken; + } + } + + } else { + scanner.unread(); + return Token.UNDEFINED; + } + } + + } + private class PHPWordRule extends WordRule { private StringBuffer fBuffer = new StringBuffer(); @@ -292,9 +402,12 @@ public class PHPCodeScanner extends AbstractJavaScanner { rules.add(new EndOfLineRule("#", token)); //$NON-NLS-1$ // Add rule for strings and character constants. token = getToken(IPreferenceConstants.PHP_STRING); - rules.add(new MultiLineRule("\"", "\"", token, '\\')); //$NON-NLS-2$ //$NON-NLS-1$ - rules.add(new MultiLineRule("`", "`", token, '\\')); //$NON-NLS-2$ //$NON-NLS-1$ - rules.add(new MultiLineRule("'", "'", token, '\\')); //$NON-NLS-2$ //$NON-NLS-1$ +// rules.add(new MultiLineRule("\"", "\"", token, '\\')); //$NON-NLS-2$ //$NON-NLS-1$ +// rules.add(new MultiLineRule("`", "`", token, '\\')); //$NON-NLS-2$ //$NON-NLS-1$ +// rules.add(new MultiLineRule("'", "'", token, '\\')); //$NON-NLS-2$ //$NON-NLS-1$ + rules.add(new SingleQuoteStringRule(token)); + rules.add(new DoubleQuoteStringRule(token)); + rules.add(new AccentStringRule(token)); token = getToken(IPreferenceConstants.PHP_MULTILINE_COMMENT); rules.add(new MultiLineRule("/*", "*/", token)); //$NON-NLS-2$ //$NON-NLS-1$ 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 4b163e0..5f1c3a7 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 @@ -8,7 +8,7 @@ Contributors: Igor Malinin - initial contribution - $Id: PHPPartitionScanner.java,v 1.27 2005-05-06 00:57:28 stefanbjarni Exp $ + $Id: PHPPartitionScanner.java,v 1.28 2005-05-13 20:19:42 axelcl Exp $ **********************************************************************/ package net.sourceforge.phpeclipse.phpeditor.php; @@ -169,11 +169,17 @@ public class PHPPartitionScanner implements IPartitionTokenScanner { break; case '/': // read until end of line - readSingleLine(); + if (!readSingleLine()) { + state = STATE_DEFAULT; + return getToken(token); + } break; case '*': // read until end of comment - readMultiLineComment(); + if (!readMultiLineComment()) { + state = STATE_DEFAULT; + return getToken(token); + } break; default: continue; @@ -181,7 +187,10 @@ public class PHPPartitionScanner implements IPartitionTokenScanner { break; case '#': // line comment // read until end of line - readSingleLine(); + if (!readSingleLine()) { + state = STATE_DEFAULT; + return getToken(token); + } break; case '?': ch = read(); @@ -193,6 +202,8 @@ public class PHPPartitionScanner implements IPartitionTokenScanner { case '?': continue; + default: + continue; } } @@ -252,6 +263,14 @@ public class PHPPartitionScanner implements IPartitionTokenScanner { return Token.EOF; } +// if (length<0) { +// try { +// System.out.println("Length<0:"+document.get(offset,5)+""+length); +// } catch (BadLocationException e) { +// e.printStackTrace(); +// } +// } + if (type == null) { return Token.UNDEFINED; } @@ -280,14 +299,17 @@ public class PHPPartitionScanner implements IPartitionTokenScanner { private boolean readUntilEscapedDQ() { // search last double quoted character - if (position >= end) { - return false; - } try { char ch; while (true) { + if (position >= end) { + return false; + } ch = document.getChar(position++); if (ch == '\\') { + if (position >= end) { + return false; + } ch = document.getChar(position++); // ignore escaped character } else if (ch == '"') { return true; @@ -301,14 +323,17 @@ public class PHPPartitionScanner implements IPartitionTokenScanner { private boolean readUntilEscapedSQ() { // search last single quoted character - if (position >= end) { - return false; - } try { char ch; while (true) { + if (position >= end) { + return false; + } ch = document.getChar(position++); if (ch == '\\') { + if (position >= end) { + return false; + } ch = document.getChar(position++); // ignore escaped character } else if (ch == '\'') { return true; @@ -320,39 +345,42 @@ public class PHPPartitionScanner implements IPartitionTokenScanner { return false; } - private void readSingleLine() { - if (position >= end) { - return; - } + private boolean readSingleLine() { try { - while (document.getChar(position++) != '\n') { - - } + do { + if (position >= end) { + return false; + } + } while (document.getChar(position++) != '\n'); + return true; } catch (BadLocationException e) { --position; - return; } + return false; } - private void readMultiLineComment() { - if (position >= end) { - return; - } + private boolean readMultiLineComment() { try { char ch; while (true) { + if (position >= end) { + return false; + } ch = document.getChar(position++); if (ch == '*') { + if (position >= end) { + return false; + } if (document.getChar(position) == '/') { position++; - break; + return true; } } } } catch (BadLocationException e) { --position; - return; } + return false; } private void unread() {