Download
Getting Started
Members
Projects
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
More
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
Toggle navigation
Bugzilla – Attachment 212430 Details for
Bug 372128
[syntax highlighting] "Highlight enclosing brackets" has massive performance problems
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
Log In
[x]
|
Terms of Use
|
Copyright Agent
[patch]
patch for platform text
text-performance.txt (text/plain), 21.07 KB, created by
Deepak Azad
on 2012-03-11 10:33:49 EDT
(
hide
)
Description:
patch for platform text
Filename:
MIME Type:
Creator:
Deepak Azad
Created:
2012-03-11 10:33:49 EDT
Size:
21.07 KB
patch
obsolete
>diff --git a/org.eclipse.jface.text/src/org/eclipse/jface/text/source/DefaultCharacterPairMatcher.java b/org.eclipse.jface.text/src/org/eclipse/jface/text/source/DefaultCharacterPairMatcher.java >index 4983562..9dd7a01 100644 >--- a/org.eclipse.jface.text/src/org/eclipse/jface/text/source/DefaultCharacterPairMatcher.java >+++ b/org.eclipse.jface.text/src/org/eclipse/jface/text/source/DefaultCharacterPairMatcher.java >@@ -9,9 +9,6 @@ > * Christian Plesner Hansen (plesner@quenta.org) - initial API and implementation > *******************************************************************************/ > package org.eclipse.jface.text.source; >-import java.util.HashSet; >-import java.util.Set; >- > import org.eclipse.core.runtime.Assert; > > import org.eclipse.jface.text.BadLocationException; >@@ -132,38 +129,75 @@ > if (document == null || offset < 0 || offset > document.getLength()) > return null; > >- int start; >- int end; >- if (length >= 0) { >- start= offset; >- end= offset + length; >- } else { >- end= offset; >- start= offset + length; >+ //maybe a bracket is selected >+ IRegion region= match(document, offset, length); >+ fAnchor= ICharacterPairMatcher.LEFT; //always set the anchor to LEFT >+ if (region != null) { >+ return region; > } > >- int sourceCaretOffset= offset + length; >- int adjustment= getOffsetAdjustment(document, sourceCaretOffset, length); >- sourceCaretOffset+= adjustment; >- >+ //bracket is not selected > try { >- for (int offset1= sourceCaretOffset; offset1 >= 0; offset1--) { >- char prevChar= document.getChar(Math.max(offset1 - 1, 0)); >- if (fPairs.contains(prevChar) && fPairs.isStartCharacter(prevChar)) { >- IRegion match= performMatch(document, offset1); >- if (match != null) { >- int matchOffset= match.getOffset(); >- int matchLength= match.getLength(); >- if ((matchOffset <= start) && (matchOffset + matchLength > start) && (matchOffset < end) && (matchOffset + matchLength >= end)) { >- return match; >- } >- } >- } >- } >+ final String partition1= TextUtilities.getContentType(document, fPartitioning, offset, false); >+ final DocumentPartitionAccessor partDoc= new DocumentPartitionAccessor(document, fPartitioning, partition1); >+ return findEnclosingPeers(document, partDoc, offset, length, 0, document.getLength()); > } catch (BadLocationException ble) { >+ fAnchor= -1; > return null; > } >- return null; >+ } >+ >+ /** >+ * @see org.eclipse.jface.text.source.ICharacterPairMatcherExtension#isMatchedChar(char) >+ * @since 3.8 >+ */ >+ public boolean isMatchedChar(char ch) { >+ return fPairs.contains(ch); >+ } >+ >+ /** >+ * @see org.eclipse.jface.text.source.ICharacterPairMatcherExtension#isMatchedChar(char, >+ * org.eclipse.jface.text.IDocument, int) >+ * @since 3.8 >+ */ >+ public boolean isMatchedChar(char ch, IDocument document, int offset) { >+ return isMatchedChar(ch); >+ } >+ >+ /** >+ * @see org.eclipse.jface.text.source.ICharacterPairMatcherExtension#isRecomputationOfEnclosingPairRequired(org.eclipse.jface.text.IDocument, >+ * org.eclipse.jface.text.IRegion, org.eclipse.jface.text.IRegion) >+ * @since 3.8 >+ */ >+ public boolean isRecomputationOfEnclosingPairRequired(IDocument document, IRegion currentSelection, IRegion previousSelection) { >+ int previousCaretOffset= previousSelection.getOffset() + previousSelection.getLength(); >+ int currentCaretOffset= currentSelection.getOffset() + currentSelection.getLength(); >+ >+ try { >+ String prevContentType= TextUtilities.getContentType(document, fPartitioning, previousCaretOffset, false); >+ String currContentType= TextUtilities.getContentType(document, fPartitioning, currentCaretOffset, false); >+ >+ if (!prevContentType.equals(currContentType)) >+ return true; >+ >+ int start; >+ int end; >+ if (currentCaretOffset > previousCaretOffset) { >+ start= previousCaretOffset; >+ end= currentCaretOffset; >+ } else { >+ start= currentCaretOffset; >+ end= previousCaretOffset; >+ } >+ for (int i= start; i < end; i++) { >+ if (isMatchedChar(document.getChar(i))) { >+ return true; >+ } >+ } >+ } catch (BadLocationException e) { >+ //do nothing >+ } >+ return false; > } > > /** >@@ -261,6 +295,106 @@ > return -1; > } > >+ /* >+ * Performs the actual work of finding enclosing peer characters for #findEnclosingPeerCharacters(IDocument, int, int). >+ */ >+ private IRegion findEnclosingPeers(IDocument document, DocumentPartitionAccessor doc, int offset, int length, int lowerBoundary, int upperBoundary) throws BadLocationException { >+ char[] pairs= fPairs.fPairs; >+ >+ int start; >+ int end; >+ if (length >= 0) { >+ start= offset; >+ end= offset + length; >+ } else { >+ end= offset; >+ start= offset + length; >+ } >+ >+ boolean lowerFound= false; >+ boolean upperFound= false; >+ int[][] counts= new int[pairs.length][2]; >+ int pos1= doc.getNextPosition(start, false); >+ int pos2= start; >+ >+ while ((pos1 >= lowerBoundary && !lowerFound) || (pos2 < upperBoundary && !upperFound)) { >+ for (int i= 0; i < counts.length; i++) { >+ counts[i][0]= counts[i][1]= 0; >+ } >+ >+ outer1: while (pos1 >= lowerBoundary && !lowerFound) { >+ final char c= doc.getChar(pos1); >+ int i= getCharacterIndex(c, document, pos1); >+ if (i != -1 && doc.inPartition(pos1)) { >+ if (i % 2 == 0) { >+ counts[i / 2][0]--; //start >+ } else { >+ counts[i / 2][0]++; //end >+ } >+ for (int j= 0; j < counts.length; j++) { >+ if (counts[j][0] == -1) { >+ lowerFound= true; >+ break outer1; >+ } >+ } >+ } >+ pos1= doc.getNextPosition(pos1, false); >+ } >+ >+ outer2: while (pos2 < upperBoundary && !upperFound) { >+ final char c= doc.getChar(pos2); >+ int i= getCharacterIndex(c, document, pos2); >+ if (i != -1 && doc.inPartition(pos2)) { >+ if (i % 2 == 0) { >+ counts[i / 2][1]++; //start >+ } else { >+ counts[i / 2][1]--; //end >+ } >+ for (int j= 0; j < counts.length; j++) { >+ if (counts[j][1] == -1 && counts[j][0] == -1) { >+ upperFound= true; >+ break outer2; >+ } >+ } >+ } >+ pos2= doc.getNextPosition(pos2, true); >+ } >+ >+ if (pos1 > start || pos2 < end) { >+ //match inside selection => discard >+ pos1= doc.getNextPosition(pos1, false); >+ pos2= doc.getNextPosition(pos2, true); >+ lowerFound= false; >+ upperFound= false; >+ } >+ } >+ pos2++; >+ if (pos1 < lowerBoundary || pos2 > upperBoundary) >+ return null; >+ return new Region(pos1, pos2 - pos1); >+ } >+ >+ /** >+ * Determines the index of the character in the char array passed to the constructor of the pair >+ * matcher. >+ * >+ * @param ch the character >+ * @param document the document >+ * @param offset the offset in document >+ * @return the index of the character in the char array passed to the constructor of the pair >+ * matcher, and -1 if the character is not one of the matched characters. >+ * @since 3.8 >+ */ >+ private int getCharacterIndex(char ch, IDocument document, int offset) { >+ char[] pairs= fPairs.fPairs; >+ for (int i= 0; i < pairs.length; i++) { >+ if (pairs[i] == ch && isMatchedChar(ch, document, offset)) { >+ return i; >+ } >+ } >+ return -1; >+ } >+ > /* @see ICharacterPairMatcher#getAnchor() */ > public int getAnchor() { > return fAnchor; >@@ -285,6 +419,7 @@ > private final IDocument fDocument; > private final String fPartitioning, fPartition; > private ITypedRegion fCachedPartition; >+ private int fLength; > > /** > * Creates a new partitioned document for the specified document. >@@ -298,6 +433,7 @@ > fDocument= doc; > fPartitioning= partitioning; > fPartition= partition; >+ fLength= doc.getLength(); > } > > /** >@@ -338,7 +474,7 @@ > } > > /** >- * Returns the next position to query in the search. The position >+ * Returns the next position to query in the search. The position > * is not guaranteed to be in this document's partition. > * > * @param pos an offset within the document >@@ -347,8 +483,7 @@ > */ > public int getNextPosition(int pos, boolean searchForward) { > final ITypedRegion partition= getPartition(pos); >- if (partition == null) return simpleIncrement(pos, searchForward); >- if (fPartition.equals(partition.getType())) >+ if (partition == null || fPartition.equals(partition.getType())) > return simpleIncrement(pos, searchForward); > if (searchForward) { > int end= partition.getOffset() + partition.getLength(); >@@ -376,7 +511,7 @@ > */ > private ITypedRegion getPartition(int pos) { > if (fCachedPartition == null || !contains(fCachedPartition, pos)) { >- Assert.isTrue(pos >= 0 && pos <= fDocument.getLength()); >+ Assert.isTrue(pos >= 0 && pos <= fLength); > try { > fCachedPartition= TextUtilities.getPartition(fDocument, fPartitioning, pos, false); > } catch (BadLocationException e) { >@@ -405,28 +540,18 @@ > } > > /** >- * Returns true if the specified character pair occurs in one >- * of the character pairs. >- * >+ * Returns true if the specified character occurs in one of the character pairs. >+ * > * @param c a character > * @return true exactly if the character occurs in one of the pairs > */ > public boolean contains(char c) { >- return getAllCharacters().contains(new Character(c)); >- } >- >- private Set/*<Character>*/ fCharsCache= null; >- /** >- * @return A set containing all characters occurring in character pairs. >- */ >- private Set/*<Character>*/ getAllCharacters() { >- if (fCharsCache == null) { >- Set/*<Character>*/ set= new HashSet/*<Character>*/(); >- for (int i= 0; i < fPairs.length; i++) >- set.add(new Character(fPairs[i])); >- fCharsCache= set; >+ char[] pairs= fPairs; >+ for (int i= 0, n= pairs.length; i < n; i++) { >+ if (c == pairs[i]) >+ return true; > } >- return fCharsCache; >+ return false; > } > > /** >diff --git a/org.eclipse.jface.text/src/org/eclipse/jface/text/source/ICharacterPairMatcherExtension.java b/org.eclipse.jface.text/src/org/eclipse/jface/text/source/ICharacterPairMatcherExtension.java >index ef87038..aacbb88 100644 >--- a/org.eclipse.jface.text/src/org/eclipse/jface/text/source/ICharacterPairMatcherExtension.java >+++ b/org.eclipse.jface.text/src/org/eclipse/jface/text/source/ICharacterPairMatcherExtension.java >@@ -49,4 +49,48 @@ > * enclosing pair > */ > IRegion findEnclosingPeerCharacters(IDocument document, int offset, int length); >+ >+ /** >+ * Checks whether the character is one of the characters matched by the pair matcher. >+ * >+ * @param ch the character >+ * @return <code>true</code> if the the character is one of the characters matched by the pair >+ * matcher, and <code>false</code> otherwise >+ */ >+ boolean isMatchedChar(char ch); >+ >+ /** >+ * Checks whether the character is one of the characters matched by the pair matcher. >+ * >+ * <p> >+ * Clients can use this method to handle characters which may have special meaning in some >+ * situations. E.g. in Java, '<' is used as an angular bracket and as well as less-than operator. >+ * </p> >+ * >+ * @param ch the character >+ * @param document the document >+ * @param offset the offset in document >+ * @return <code>true</code> if the the character is one of the characters matched by the pair >+ * matcher, and <code>false</code> otherwise >+ */ >+ boolean isMatchedChar(char ch, IDocument document, int offset); >+ >+ /** >+ * Computes whether a client needs to recompute the enclosing pair after a selection change in >+ * the document. >+ * >+ * <p> >+ * This is intended to be quick test to determine whether a re-computation of enclosing pair is >+ * required, as the re-computation after each selection change via a >+ * {@link #findEnclosingPeerCharacters(IDocument, int, int)} call can be expensive for some >+ * clients. >+ * </p> >+ * >+ * @param document the document to work on >+ * @param currentSelection the current selection in the document >+ * @param previousSelection the previous selection in the document >+ * @return <code>true</code> if the enclosing pair needs to be recomputed, <code>false</code> >+ * otherwise >+ */ >+ boolean isRecomputationOfEnclosingPairRequired(IDocument document, IRegion currentSelection, IRegion previousSelection); > } >diff --git a/org.eclipse.jface.text/src/org/eclipse/jface/text/source/MatchingCharacterPainter.java b/org.eclipse.jface.text/src/org/eclipse/jface/text/source/MatchingCharacterPainter.java >index f32f1a0..e6cfbda 100644 >--- a/org.eclipse.jface.text/src/org/eclipse/jface/text/source/MatchingCharacterPainter.java >+++ b/org.eclipse.jface.text/src/org/eclipse/jface/text/source/MatchingCharacterPainter.java >@@ -20,21 +20,27 @@ > import org.eclipse.swt.graphics.Rectangle; > > import org.eclipse.jface.text.BadLocationException; >+import org.eclipse.jface.text.DocumentEvent; > import org.eclipse.jface.text.IDocument; > import org.eclipse.jface.text.IPaintPositionManager; > import org.eclipse.jface.text.IPainter; > import org.eclipse.jface.text.IRegion; >+import org.eclipse.jface.text.ITextInputListener; >+import org.eclipse.jface.text.ITextListener; > import org.eclipse.jface.text.ITextViewerExtension5; > import org.eclipse.jface.text.Position; > import org.eclipse.jface.text.Region; >+import org.eclipse.jface.text.TextEvent; > > /** >- * Highlights the peer character matching the character near the caret position. >- * This painter can be configured with an >- * {@link org.eclipse.jface.text.source.ICharacterPairMatcher}. >+ * Highlights the peer character matching the character near the caret position, or a pair of peer >+ * characters enclosing the caret position. This painter can be configured with an >+ * {@link org.eclipse.jface.text.source.ICharacterPairMatcher} or an >+ * {@link org.eclipse.jface.text.source.ICharacterPairMatcherExtension}. > * <p> >- * Clients instantiate and configure object of this class.</p> >- * >+ * Clients instantiate and configure an object of this class. >+ * </p> >+ * > * @since 2.1 > */ > public final class MatchingCharacterPainter implements IPainter, PaintListener { >@@ -55,13 +61,62 @@ > private Position fPairPosition= new Position(0, 0); > /** The anchor indicating whether the character is left or right of the caret */ > private int fAnchor; >- /** Whether to highlight enclosing peer characters or not. */ >- private boolean fHighlightEnclosingPeerCharcters; >- /** Whether to highlight the character at caret location or not. */ >+ >+ /** >+ * Whether to highlight enclosing peer characters or not. >+ * >+ * @since 3.8 >+ */ >+ private boolean fHighlightEnclosingPeerCharacters; >+ >+ /** >+ * Whether to highlight the character at caret location or not. >+ * >+ * @since 3.8 >+ */ > private boolean fHighlightCharacterAtCaretLocation; >- /** Whether a character is present at caret location or not. */ >+ >+ /** >+ * Whether a character is present at caret location or not. >+ * >+ * @since 3.8 >+ */ > private boolean fCharacterPresentAtCaretLocation; > >+ /** >+ * The document this painter is associated with. >+ * >+ * @since 3.8 >+ */ >+ private IDocument fDocument; >+ >+ /** >+ * The previous selection, used to determine the need for computing enclosing brackets. >+ * >+ * @since 3.8 >+ */ >+ private IRegion fPreviousSelection; >+ >+ /** >+ * Previous length of the document this painter is associated with. >+ * >+ * @since 3.8 >+ */ >+ private int fPreviousLengthOfDocument; >+ >+ /** >+ * Whether the input document has been replaced or not. >+ * >+ * @since 3.8 >+ */ >+ private boolean fDocumentChanged; >+ >+ /** >+ * The text viewer change listener. >+ * >+ * @since 3.8 >+ */ >+ private TextListener fTextListener; > > /** > * Creates a new MatchingCharacterPainter for the given source viewer using the given character >@@ -75,6 +130,7 @@ > fSourceViewer= sourceViewer; > fMatcher= matcher; > fTextWidget= sourceViewer.getTextWidget(); >+ fDocument= fSourceViewer.getDocument(); > } > > /** >@@ -95,7 +151,8 @@ > * @since 3.8 > */ > public void setHighlightEnclosingPeerCharacters(boolean highlightEnclosingPeerCharcters) { >- fHighlightEnclosingPeerCharcters= highlightEnclosingPeerCharcters; >+ fHighlightEnclosingPeerCharacters= highlightEnclosingPeerCharcters; >+ installUninstallTextListener(highlightEnclosingPeerCharcters); > } > > /** >@@ -112,6 +169,10 @@ > */ > public void dispose() { > if (fMatcher != null) { >+ if (fMatcher instanceof ICharacterPairMatcherExtension && fTextListener != null) { >+ installUninstallTextListener(false); >+ } >+ > fMatcher.clear(); > fMatcher= null; > } >@@ -185,7 +246,7 @@ > offset -= region.getOffset(); > } > >- if (fHighlightCharacterAtCaretLocation || (fHighlightEnclosingPeerCharcters && !fCharacterPresentAtCaretLocation)) { >+ if (fHighlightCharacterAtCaretLocation || (fHighlightEnclosingPeerCharacters && !fCharacterPresentAtCaretLocation)) { > draw(gc, offset, 1); > draw(gc, offset + length - 1, 1); > } else { >@@ -262,7 +323,7 @@ > */ > public void paint(int reason) { > >- IDocument document= fSourceViewer.getDocument(); >+ IDocument document= fDocument; > if (document == null) { > deactivate(false); > return; >@@ -276,7 +337,28 @@ > ICharacterPairMatcherExtension matcher= (ICharacterPairMatcherExtension)fMatcher; > pair= matcher.match(document, selection.getOffset(), selection.getLength()); > characterPresentAtCaretLocation= (pair != null); >- if (pair == null && fHighlightEnclosingPeerCharcters) { >+ if (pair == null && fHighlightEnclosingPeerCharacters) { >+ >+ int length= document.getLength(); >+ boolean lengthChanged= length != fPreviousLengthOfDocument; >+ fPreviousLengthOfDocument= length; >+ >+ if (reason != IPainter.CONFIGURATION && !fDocumentChanged && !lengthChanged && selection.equals(fPreviousSelection)) { >+ return; >+ } >+ >+ if (reason == IPainter.TEXT_CHANGE) { >+ fPreviousSelection= selection; >+ return; >+ } >+ >+ fDocumentChanged= false; >+ if (reason != IPainter.CONFIGURATION && !lengthChanged && fPreviousSelection != null && reason != IPainter.INTERNAL) { >+ if (!matcher.isRecomputationOfEnclosingPairRequired(document, selection, fPreviousSelection)) { >+ fPreviousSelection= selection; >+ return; >+ } >+ } > pair= matcher.findEnclosingPeerCharacters(document, selection.getOffset(), selection.getLength()); > } > } else { >@@ -288,6 +370,7 @@ > characterPresentAtCaretLocation= (pair != null); > } > >+ fPreviousSelection= selection; > if (pair == null) { > deactivate(true); > return; >@@ -340,4 +423,100 @@ > public void setPositionManager(IPaintPositionManager manager) { > fPaintPositionManager= manager; > } >+ >+ /** >+ * Installs or uninstalls the text listener depending on the boolean parameter. >+ * >+ * @param install whether to install or uninstall the text listener >+ * >+ * @since 3.8 >+ */ >+ private void installUninstallTextListener(boolean install) { >+ if (!(fMatcher instanceof ICharacterPairMatcherExtension)) >+ return; >+ >+ if (install) { >+ fTextListener= new TextListener(); >+ fSourceViewer.addTextInputListener(fTextListener); >+ fSourceViewer.addTextListener(fTextListener); >+ } else { >+ if (fTextListener != null) { >+ fSourceViewer.removeTextInputListener(fTextListener); >+ fSourceViewer.removeTextListener(fTextListener); >+ fTextListener= null; >+ } >+ } >+ } >+ >+ /** >+ * Listens to document changes and if required by those document changes causes a re-computation >+ * of matching characters. >+ * >+ * @since 3.8 >+ */ >+ private class TextListener implements ITextListener, ITextInputListener { >+ >+ /** >+ * @see org.eclipse.jface.text.ITextInputListener#inputDocumentAboutToBeChanged(org.eclipse.jface.text.IDocument, >+ * org.eclipse.jface.text.IDocument) >+ * @since 3.8 >+ */ >+ public void inputDocumentAboutToBeChanged(IDocument oldInput, IDocument newInput) { >+ //do nothing >+ } >+ >+ /** >+ * @see org.eclipse.jface.text.ITextInputListener#inputDocumentChanged(org.eclipse.jface.text.IDocument, >+ * org.eclipse.jface.text.IDocument) >+ * @since 3.8 >+ */ >+ public void inputDocumentChanged(IDocument oldInput, IDocument newInput) { >+ fDocument= newInput; >+ fDocumentChanged= true; >+ } >+ >+ /** >+ * @see org.eclipse.jface.text.ITextListener#textChanged(org.eclipse.jface.text.TextEvent) >+ * @since 3.8 >+ */ >+ public void textChanged(TextEvent event) { >+ if (!fHighlightEnclosingPeerCharacters || !(fMatcher instanceof ICharacterPairMatcherExtension)) >+ return; >+ >+ String text= event.getText(); >+ String replacedText= event.getReplacedText(); >+ >+ boolean viewerRedrawState= event.getViewerRedrawState(); >+ DocumentEvent documentEvent= event.getDocumentEvent(); >+ if (documentEvent == null && !viewerRedrawState) >+ return; >+ >+ ICharacterPairMatcherExtension matcher= (ICharacterPairMatcherExtension)fMatcher; >+ boolean found= searchForCharacters(text, matcher) || searchForCharacters(replacedText, matcher); >+ >+ if (found || (documentEvent == null && viewerRedrawState)) { >+ paint(IPainter.INTERNAL); >+ } >+ } >+ >+ /** >+ * Searches for matched characters in the given string. >+ * >+ * @param text the string to search >+ * @param matcher the pair matcher >+ * @return <code>true</code> if a matched character is found, <code>false</code> otherwise >+ * >+ * @since 3.8 >+ */ >+ private boolean searchForCharacters(String text, ICharacterPairMatcherExtension matcher) { >+ if (text == null) >+ return false; >+ for (int i= 0; i < text.length(); i++) { >+ if (matcher.isMatchedChar(text.charAt(i))) { >+ return true; >+ } >+ } >+ return false; >+ } >+ } > }
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 372128
:
211936
|
212125
|
212126
|
212208
|
212214
|
212353
|
212364
|
212429
| 212430