1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-08-01 13:25:45 +02:00

Bug 325385: Duplicate search results.

This commit is contained in:
Markus Schorn 2010-09-27 15:48:04 +00:00
parent 3bbf54e9da
commit 8ff177d648
4 changed files with 122 additions and 69 deletions

View file

@ -357,4 +357,28 @@ public class BasicSearchTest extends BaseUITestCase {
PDOMSearchResult result= (PDOMSearchResult) query.getSearchResult(); PDOMSearchResult result= (PDOMSearchResult) query.getSearchResult();
assertEquals(expected, result.getMatchCount()); assertEquals(expected, result.getMatchCount());
} }
// template<typename T> class CT {};
// template<typename T> class CT<T*> {};
// template<typename T> void f(T) {};
// template<typename T> void f(T*) {};
// void a() {
// CT<int>* r1;
// CT<char>* r2;
// CT<int*>* r3;
//
// int a;
// f(a);
// f(&a);
// f<int>(a);
// f<int>(&a);
// }
public void testSearchAndTemplateIDs() throws Exception {
PDOMSearchQuery query= makeProjectQuery("CT");
assertOccurrences(query, 5);
query= makeProjectQuery("f");
assertOccurrences(query, 6);
}
} }

View file

@ -77,7 +77,10 @@ public class LineSearchElement extends PDOMSearchElement {
private static final class MatchesComparator implements Comparator<Match> { private static final class MatchesComparator implements Comparator<Match> {
public int compare(Match m1, Match m2) { public int compare(Match m1, Match m2) {
return m1.getOffset() - m2.getOffset(); int diff= m1.getOffset() - m2.getOffset();
if (diff == 0)
diff= m2.getLength() -m1.getLength();
return diff;
} }
} }
@ -158,47 +161,88 @@ public class LineSearchElement extends PDOMSearchElement {
public static LineSearchElement[] createElements(IIndexFileLocation fileLocation, Match[] matches, public static LineSearchElement[] createElements(IIndexFileLocation fileLocation, Match[] matches,
IDocument document) { IDocument document) {
// sort matches according to their offsets // Sort matches according to their offsets
Arrays.sort(matches, MATCHES_COMPARATOR); Arrays.sort(matches, MATCHES_COMPARATOR);
// group all matches by lines and create LineSearchElements // Group all matches by lines and create LineSearchElements
List<LineSearchElement> result = new ArrayList<LineSearchElement>(); List<LineSearchElement> result = new ArrayList<LineSearchElement>();
int firstMatch = 0; List<Match> matchCollector= new ArrayList<Match>();
while (firstMatch < matches.length) { int minOffset = 0;
try { int lineNumber = 0;
int lineNumber = document.getLineOfOffset(matches[firstMatch].getOffset()); int lineOffset = 0;
int lineOffset = document.getLineOffset(lineNumber); int lineLength = 0;
int lineLength = document.getLineLength(lineNumber); int lineEndOffset = 0;
int nextlineOffset = lineOffset + lineLength;
int nextMatch = firstMatch; try {
int nextMatchOffset = matches[nextMatch].getOffset(); for (final Match match : matches) {
while (nextMatch < matches.length && nextMatchOffset < nextlineOffset) { final int offset= match.getOffset();
nextMatch++; if (offset < lineEndOffset) {
if (nextMatch < matches.length) // Match on same line
nextMatchOffset = matches[nextMatch].getOffset(); if (offset < minOffset) {
} // Match is not overlapped by previous one.
int lineMatchesCount = nextMatch - firstMatch; matchCollector.add(match);
Match[] lineMatches = new Match[lineMatchesCount]; minOffset= offset + match.getLength();
System.arraycopy(matches, firstMatch, lineMatches, 0, lineMatchesCount); }
String content = document.get(lineOffset, lineLength); } else {
result.add(new LineSearchElement(fileLocation, lineMatches, lineNumber + 1, content, lineOffset)); // Match is on a new line
firstMatch = nextMatch; if (!matchCollector.isEmpty()) {
} catch (BadLocationException e) { // Complete a line
CUIPlugin.log(e); String content = document.get(lineOffset, lineLength);
Match[] lineMatches= matchCollector.toArray(new Match[matchCollector.size()]);
result.add(new LineSearchElement(fileLocation, lineMatches, lineNumber + 1, content, lineOffset));
matchCollector.clear();
}
// Setup next line
lineNumber = document.getLineOfOffset(offset);
lineOffset = document.getLineOffset(lineNumber);
lineLength = document.getLineLength(lineNumber);
lineEndOffset = lineOffset + lineLength;
matchCollector.add(match);
}
} }
if (!matchCollector.isEmpty()) {
// Complete a line
String content = document.get(lineOffset, lineLength);
Match[] lineMatches= matchCollector.toArray(new Match[matchCollector.size()]);
result.add(new LineSearchElement(fileLocation, lineMatches, lineNumber + 1, content, lineOffset));
matchCollector.clear();
}
} catch (BadLocationException e) {
CUIPlugin.log(e);
} }
return result.toArray(new LineSearchElement[result.size()]); return result.toArray(new LineSearchElement[result.size()]);
} }
private static LineSearchElement[] collectLineElements(AbstractCharArray buf, Match[] matches, private static LineSearchElement[] collectLineElements(AbstractCharArray buf, Match[] matches,
IIndexFileLocation fileLocation) { IIndexFileLocation fileLocation) {
List<LineSearchElement> result = new ArrayList<LineSearchElement>(); List<LineSearchElement> result = new ArrayList<LineSearchElement>();
List<Match> matchCollector= new ArrayList<Match>();
boolean skipLF = false; boolean skipLF = false;
int lineNumber = 1; int lineNumber = 1;
int lineOffset = 0; int lineOffset = 0;
int lineFirstMatch = -1; // not matched int i = 0;
int nextMatch = 0; Match match= matches[i];
int nextMatchOffset = matches[nextMatch].getOffset(); int matchOffset = match.getOffset();
for (int pos = 0; buf.isValidOffset(pos); pos++) { for (int pos = 0; buf.isValidOffset(pos); pos++) {
if (matchOffset <= pos && match != null) {
// We are on the line of the match, store it.
matchCollector.add(match);
final int minOffset= matchOffset + match.getLength();
match= null;
matchOffset= Integer.MAX_VALUE;
for(i=i+1; i<matches.length; i++) {
// Advance to next match that is not overlapped
final Match nextMatch= matches[i];
final int nextOffset= nextMatch.getOffset();
if (nextOffset >= minOffset) {
match= nextMatch;
matchOffset= nextOffset;
break;
}
}
}
char c = buf.get(pos); char c = buf.get(pos);
// consider '\n' and '\r' // consider '\n' and '\r'
if (skipLF) { if (skipLF) {
@ -209,22 +253,18 @@ public class LineSearchElement extends PDOMSearchElement {
} }
} }
if (c == '\n' || c == '\r') { if (c == '\n' || c == '\r') {
// create new LineElement if there were matches // Create new LineElement for collected matches on this line
if (lineFirstMatch != -1) { if (!matchCollector.isEmpty()) {
int lineLength = pos - lineOffset; int lineLength = pos - lineOffset;
int lineMatchesCount = nextMatch - lineFirstMatch; Match[] lineMatches= matchCollector.toArray(new Match[matchCollector.size()]);
Match[] lineMatches = new Match[lineMatchesCount];
System.arraycopy(matches, lineFirstMatch, lineMatches, 0, lineMatchesCount);
char[] lineChars= new char[lineLength]; char[] lineChars= new char[lineLength];
buf.arraycopy(lineOffset, lineChars, 0, lineLength); buf.arraycopy(lineOffset, lineChars, 0, lineLength);
String lineContent = new String(lineChars); String lineContent = new String(lineChars);
result.add(new LineSearchElement(fileLocation, lineMatches, lineNumber, lineContent, result.add(new LineSearchElement(fileLocation, lineMatches, lineNumber, lineContent,
lineOffset)); lineOffset));
lineFirstMatch = -1; matchCollector.clear();
if (nextMatch >= matches.length) if (match == null)
break; break;
if (matches[nextMatch].getOffset() < pos)
lineFirstMatch = nextMatch;
} }
lineNumber++; lineNumber++;
lineOffset = pos + 1; lineOffset = pos + 1;
@ -232,31 +272,16 @@ public class LineSearchElement extends PDOMSearchElement {
skipLF = true; skipLF = true;
continue; continue;
} }
// compare offset of next match with current position
if (nextMatchOffset > pos || nextMatch >= matches.length)
continue;
// next match was reached
// check if this match is the first for current line
if (lineFirstMatch == -1)
lineFirstMatch = nextMatch;
// goto to next match
nextMatch++;
if (nextMatch < matches.length) {
// update offset of next match
nextMatchOffset = matches[nextMatch].getOffset();
}
} }
// check if there were matches on the last line // Create new LineElement for matches on the last line
if (lineFirstMatch != -1) { if (!matchCollector.isEmpty()) {
int lineLength = buf.getLength() - lineOffset; int lineLength = buf.getLength() - lineOffset;
int lineMatchesCount = nextMatch - lineFirstMatch; Match[] lineMatches= matchCollector.toArray(new Match[matchCollector.size()]);
Match[] lineMatches = new Match[lineMatchesCount];
System.arraycopy(matches, lineFirstMatch, lineMatches, 0, lineMatchesCount);
char[] lineChars= new char[lineLength]; char[] lineChars= new char[lineLength];
buf.arraycopy(lineOffset, lineChars, 0, lineLength); buf.arraycopy(lineOffset, lineChars, 0, lineLength);
String lineContent = new String(lineChars); String lineContent = new String(lineChars);
result.add(new LineSearchElement(fileLocation, lineMatches, lineNumber, lineContent, lineOffset)); result.add(new LineSearchElement(fileLocation, lineMatches, lineNumber, lineContent,
lineOffset));
} }
return result.toArray(new LineSearchElement[result.size()]); return result.toArray(new LineSearchElement[result.size()]);
} }

View file

@ -145,11 +145,7 @@ public class PDOMSearchPatternQuery extends PDOMSearchQuery {
for (int i = 0; i < bindings.length; ++i) { for (int i = 0; i < bindings.length; ++i) {
IIndexBinding pdomBinding = bindings[i]; IIndexBinding pdomBinding = bindings[i];
//check for the element type of this binding and create matches if // Select the requested bindings
//the element type checkbox is checked in the C/C++ Search Page
//TODO search for macro
boolean matches= false; boolean matches= false;
if ((flags & FIND_ALL_TYPES) == FIND_ALL_TYPES) { if ((flags & FIND_ALL_TYPES) == FIND_ALL_TYPES) {
matches= true; matches= true;

View file

@ -21,8 +21,8 @@ import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.Set;
import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IPath;
@ -310,14 +310,20 @@ public abstract class PDOMSearchQuery implements ISearchQuery {
return; return;
List<IIndexName> names= new ArrayList<IIndexName>(); List<IIndexName> names= new ArrayList<IIndexName>();
List<IIndexName> polymorphicNames= null; List<IIndexName> polymorphicNames= null;
HashSet<IBinding> handled= new HashSet<IBinding>();
for (IBinding binding : bindings) { for (IBinding binding : bindings) {
if (binding != null) { if (binding != null && handled.add(binding)) {
createMatches1(index, binding, names); createMatches1(index, binding, names);
}
if ((flags & FIND_REFERENCES) != 0) { }
if ((flags & FIND_REFERENCES) != 0) {
for (IBinding binding : bindings) {
if (binding != null) {
List<? extends IBinding> specializations = IndexUI.findSpecializations(binding); List<? extends IBinding> specializations = IndexUI.findSpecializations(binding);
if (!specializations.isEmpty()) { for (IBinding spec : specializations) {
for (IBinding spec : specializations) { if (spec != null && handled.add(spec)) {
createMatches1(index, spec, names); createMatches1(index, spec, names);
} }
} }
@ -331,7 +337,9 @@ public abstract class PDOMSearchQuery implements ISearchQuery {
polymorphicNames= new ArrayList<IIndexName>(); polymorphicNames= new ArrayList<IIndexName>();
} }
for (ICPPMethod mInBase : msInBases) { for (ICPPMethod mInBase : msInBases) {
createMatches1(index, mInBase, polymorphicNames); if (mInBase != null && handled.add(mInBase)) {
createMatches1(index, mInBase, polymorphicNames);
}
} }
} }
} catch (DOMException e) { } catch (DOMException e) {