mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-23 08:55:25 +02:00
Patch by Andrey Eremchenko for bug 222495.
This commit is contained in:
parent
eff76a45d1
commit
7f394792a4
11 changed files with 560 additions and 53 deletions
|
@ -548,6 +548,12 @@
|
|||
label="%Dummy.label"
|
||||
value="0,0,0">
|
||||
</colorDefinition>
|
||||
<colorDefinition
|
||||
id="org.eclipse.cdt.ui.ColoredLabels.match_highlight"
|
||||
isEditable="false"
|
||||
label="%Dummy.label"
|
||||
value="206, 204, 247">
|
||||
</colorDefinition>
|
||||
<theme
|
||||
id="org.eclipse.ui.ide.systemDefault">
|
||||
<colorOverride
|
||||
|
|
|
@ -303,6 +303,7 @@ public class CPluginImages {
|
|||
//for search
|
||||
public static final String IMG_OBJS_SEARCH_REF = NAME_PREFIX + "search_ref_obj.gif"; //$NON-NLS-1$
|
||||
public static final String IMG_OBJS_SEARCH_DECL = NAME_PREFIX + "search_decl_obj.gif"; //$NON-NLS-1$
|
||||
public static final String IMG_OBJS_SEARCH_LINE = NAME_PREFIX + "searchm_obj.gif"; //$NON-NLS-1$
|
||||
public static final String IMG_OBJS_CSEARCH = NAME_PREFIX + "csearch_obj.gif"; //$NON-NLS-1$
|
||||
|
||||
public static final String IMG_OBJS_SEARCHFOLDER = NAME_PREFIX + "fldr_obj.gif"; //$NON-NLS-1$
|
||||
|
@ -310,6 +311,7 @@ public class CPluginImages {
|
|||
|
||||
public static final ImageDescriptor DESC_OBJS_SEARCH_DECL = createManaged(T_OBJ, IMG_OBJS_SEARCH_DECL);
|
||||
public static final ImageDescriptor DESC_OBJS_SEARCH_REF = createManaged(T_OBJ, IMG_OBJS_SEARCH_REF);
|
||||
public static final ImageDescriptor DESC_OBJS_SEARCH_LINE = createManaged(T_OBJ, IMG_OBJS_SEARCH_LINE);
|
||||
public static final ImageDescriptor DESC_OBJS_CSEARCH = createManaged(T_OBJ, IMG_OBJS_CSEARCH);
|
||||
|
||||
public static final ImageDescriptor DESC_OBJS_SEARCHHIERPROJECT = createManaged(T_OBJ,IMG_OBJS_SEARCHPROJECT);
|
||||
|
|
|
@ -0,0 +1,251 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2009 QNX Software Systems and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Andrey Eremchenko, kamre@ngs.ru - 222495 C/C++ search should show line matches and line numbers
|
||||
*
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.ui.search;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.jface.text.BadLocationException;
|
||||
import org.eclipse.jface.text.IDocument;
|
||||
|
||||
import org.eclipse.cdt.core.index.IIndexFileLocation;
|
||||
import org.eclipse.cdt.core.parser.CodeReader;
|
||||
import org.eclipse.cdt.ui.CUIPlugin;
|
||||
|
||||
/**
|
||||
* Element representing a line with one ore more matches.
|
||||
*
|
||||
*/
|
||||
public class LineSearchElement extends PDOMSearchElement {
|
||||
public static final class Match {
|
||||
private final int fOffset;
|
||||
private final int fLength;
|
||||
private final boolean fIsPolymorphicCall;
|
||||
|
||||
public Match(int offset, int length, boolean isPolymorphicCall) {
|
||||
fOffset = offset;
|
||||
fLength = length;
|
||||
fIsPolymorphicCall = isPolymorphicCall;
|
||||
}
|
||||
|
||||
public int getOffset() {
|
||||
return fOffset;
|
||||
}
|
||||
|
||||
public int getLength() {
|
||||
return fLength;
|
||||
}
|
||||
|
||||
public boolean isPolymorphicCall() {
|
||||
return fIsPolymorphicCall;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (!(obj instanceof Match))
|
||||
return false;
|
||||
Match m = (Match) obj;
|
||||
return (fOffset == m.fOffset) && (fLength == m.fLength);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return 31 * fOffset + fLength;
|
||||
}
|
||||
}
|
||||
|
||||
private static final class MatchesComparator implements Comparator<Match> {
|
||||
public int compare(Match m1, Match m2) {
|
||||
return m1.getOffset() - m2.getOffset();
|
||||
}
|
||||
}
|
||||
|
||||
private final int fOffset;
|
||||
private final int fNumber;
|
||||
private final String fContent;
|
||||
private final Match[] fMatches;
|
||||
private final static MatchesComparator MATCHES_COMPARATOR = new MatchesComparator();
|
||||
|
||||
private LineSearchElement(IIndexFileLocation file, Match[] matches, int number, String content, int offset) {
|
||||
super(file);
|
||||
fMatches = matches;
|
||||
fNumber = number;
|
||||
// skip whitespace at the beginning
|
||||
int index = 0;
|
||||
int length = content.length();
|
||||
int firstMatchOffset = matches[0].getOffset();
|
||||
while (offset < firstMatchOffset && length > 0) {
|
||||
if (content.charAt(index) != ' ')
|
||||
break;
|
||||
index++;
|
||||
offset++;
|
||||
length--;
|
||||
}
|
||||
fOffset = offset;
|
||||
fContent = content.substring(index);
|
||||
}
|
||||
|
||||
public int getOffset() {
|
||||
return fOffset;
|
||||
}
|
||||
|
||||
public int getLineNumber() {
|
||||
return fNumber;
|
||||
}
|
||||
|
||||
public String getContent() {
|
||||
return fContent;
|
||||
}
|
||||
|
||||
public Match[] getMatches() {
|
||||
return fMatches;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return fNumber + ": " + fContent; //$NON-NLS-1$
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (!(obj instanceof LineSearchElement))
|
||||
return false;
|
||||
LineSearchElement other = (LineSearchElement) obj;
|
||||
return (fOffset == other.fOffset) && (super.equals(obj)) && (fMatches.equals(other.fMatches));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return fOffset + 31 * (super.hashCode() + 31 * fMatches.hashCode());
|
||||
}
|
||||
|
||||
public static LineSearchElement[] createElements(IIndexFileLocation fileLocation, Match[] matches) {
|
||||
// sort matches according to their offsets
|
||||
Arrays.sort(matches, MATCHES_COMPARATOR);
|
||||
LineSearchElement[] result = {};
|
||||
try {
|
||||
String path = fileLocation.getURI().getPath();
|
||||
// read the content of file
|
||||
CodeReader reader = new CodeReader(path);
|
||||
result = collectLineElements(reader.buffer, matches, fileLocation);
|
||||
} catch (IOException e) {
|
||||
CUIPlugin.log(e);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static LineSearchElement[] createElements(IIndexFileLocation fileLocation, Match[] matches,
|
||||
IDocument document) {
|
||||
// sort matches according to their offsets
|
||||
Arrays.sort(matches, MATCHES_COMPARATOR);
|
||||
// group all matches by lines and create LineSearchElements
|
||||
List<LineSearchElement> result = new ArrayList<LineSearchElement>();
|
||||
int firstMatch = 0;
|
||||
while (firstMatch < matches.length) {
|
||||
try {
|
||||
int lineNumber = document.getLineOfOffset(matches[firstMatch].getOffset());
|
||||
int lineOffset = document.getLineOffset(lineNumber);
|
||||
int lineLength = document.getLineLength(lineNumber);
|
||||
int nextlineOffset = lineOffset + lineLength;
|
||||
int nextMatch = firstMatch;
|
||||
int nextMatchOffset = matches[nextMatch].getOffset();
|
||||
while (nextMatch < matches.length && nextMatchOffset < nextlineOffset) {
|
||||
nextMatch++;
|
||||
if (nextMatch < matches.length)
|
||||
nextMatchOffset = matches[nextMatch].getOffset();
|
||||
}
|
||||
int lineMatchesCount = nextMatch - firstMatch;
|
||||
Match[] lineMatches = new Match[lineMatchesCount];
|
||||
System.arraycopy(matches, firstMatch, lineMatches, 0, lineMatchesCount);
|
||||
String content = document.get(lineOffset, lineLength);
|
||||
result.add(new LineSearchElement(fileLocation, lineMatches, lineNumber + 1, content, lineOffset));
|
||||
firstMatch = nextMatch;
|
||||
} catch (BadLocationException e) {
|
||||
CUIPlugin.log(e);
|
||||
}
|
||||
}
|
||||
return result.toArray(new LineSearchElement[result.size()]);
|
||||
}
|
||||
|
||||
private static LineSearchElement[] collectLineElements(char[] buffer, Match[] matches,
|
||||
IIndexFileLocation fileLocation) {
|
||||
List<LineSearchElement> result = new ArrayList<LineSearchElement>();
|
||||
boolean skipLF = false;
|
||||
int lineNumber = 1;
|
||||
int lineOffset = 0;
|
||||
int lineFirstMatch = -1; // not matched
|
||||
int nextMatch = 0;
|
||||
int nextMatchOffset = matches[nextMatch].getOffset();
|
||||
for (int pos = 0; pos < buffer.length; pos++) {
|
||||
char c = buffer[pos];
|
||||
// consider '\n' and '\r'
|
||||
if (skipLF) {
|
||||
skipLF = false;
|
||||
if (c == '\n') {
|
||||
lineOffset = pos + 1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (c == '\n' || c == '\r') {
|
||||
// create new LineElement if there were matches
|
||||
if (lineFirstMatch != -1) {
|
||||
int lineLength = pos - lineOffset;
|
||||
int lineMatchesCount = nextMatch - lineFirstMatch;
|
||||
Match[] lineMatches = new Match[lineMatchesCount];
|
||||
System.arraycopy(matches, lineFirstMatch, lineMatches, 0, lineMatchesCount);
|
||||
String lineContent = new String(buffer, lineOffset, lineLength);
|
||||
result.add(new LineSearchElement(fileLocation, lineMatches, lineNumber, lineContent,
|
||||
lineOffset));
|
||||
lineFirstMatch = -1;
|
||||
if (nextMatch >= matches.length)
|
||||
break;
|
||||
if (matches[nextMatch].getOffset() < pos)
|
||||
lineFirstMatch = nextMatch;
|
||||
}
|
||||
lineNumber++;
|
||||
lineOffset = pos + 1;
|
||||
if (c == '\r')
|
||||
skipLF = true;
|
||||
continue;
|
||||
}
|
||||
// compare offset of next match with current position
|
||||
if (nextMatchOffset > pos)
|
||||
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();
|
||||
} else {
|
||||
// no more matches
|
||||
nextMatchOffset = buffer.length;
|
||||
}
|
||||
}
|
||||
// check if there were matches on the last line
|
||||
if (lineFirstMatch != -1) {
|
||||
int lineLength = buffer.length - lineOffset;
|
||||
int lineMatchesCount = nextMatch - lineFirstMatch;
|
||||
Match[] lineMatches = new Match[lineMatchesCount];
|
||||
System.arraycopy(matches, lineFirstMatch, lineMatches, 0, lineMatchesCount);
|
||||
String lineContent = new String(buffer, lineOffset, lineLength);
|
||||
result.add(new LineSearchElement(fileLocation, lineMatches, lineNumber, lineContent, lineOffset));
|
||||
}
|
||||
return result.toArray(new LineSearchElement[result.size()]);
|
||||
}
|
||||
}
|
|
@ -16,6 +16,9 @@ import java.net.URI;
|
|||
import org.eclipse.core.runtime.IPath;
|
||||
import org.eclipse.core.runtime.IStatus;
|
||||
import org.eclipse.jface.viewers.LabelProvider;
|
||||
import org.eclipse.jface.viewers.StyledString;
|
||||
import org.eclipse.jface.viewers.DelegatingStyledCellLabelProvider.IStyledLabelProvider;
|
||||
import org.eclipse.search.ui.text.AbstractTextSearchResult;
|
||||
import org.eclipse.search.ui.text.AbstractTextSearchViewPage;
|
||||
import org.eclipse.swt.graphics.Image;
|
||||
import org.eclipse.ui.ISharedImages;
|
||||
|
@ -26,9 +29,13 @@ import org.eclipse.cdt.core.index.IIndexFileLocation;
|
|||
import org.eclipse.cdt.core.index.IndexLocationFactory;
|
||||
import org.eclipse.cdt.ui.browser.typeinfo.TypeInfoLabelProvider;
|
||||
|
||||
import org.eclipse.cdt.internal.core.model.TranslationUnit;
|
||||
|
||||
import org.eclipse.cdt.internal.ui.CPluginImages;
|
||||
import org.eclipse.cdt.internal.ui.search.LineSearchElement.Match;
|
||||
import org.eclipse.cdt.internal.ui.viewsupport.CElementImageProvider;
|
||||
import org.eclipse.cdt.internal.ui.viewsupport.CUILabelProvider;
|
||||
import org.eclipse.cdt.internal.ui.viewsupport.ColoringLabelProvider;
|
||||
|
||||
/**
|
||||
* The content in the tree and list views may be either:
|
||||
|
@ -43,7 +50,7 @@ import org.eclipse.cdt.internal.ui.viewsupport.CUILabelProvider;
|
|||
* @author Ed Swartz
|
||||
*
|
||||
*/
|
||||
public class PDOMSearchLabelProvider extends LabelProvider {
|
||||
public class PDOMSearchLabelProvider extends LabelProvider implements IStyledLabelProvider {
|
||||
|
||||
private final AbstractTextSearchViewPage fPage;
|
||||
private final TypeInfoLabelProvider fTypeInfoLabelProvider;
|
||||
|
@ -57,6 +64,9 @@ public class PDOMSearchLabelProvider extends LabelProvider {
|
|||
|
||||
@Override
|
||||
public Image getImage(Object element) {
|
||||
if (element instanceof LineSearchElement)
|
||||
return CPluginImages.get(CPluginImages.IMG_OBJS_SEARCH_LINE);
|
||||
|
||||
if (element instanceof TypeInfoSearchElement)
|
||||
return fTypeInfoLabelProvider.getImage(((TypeInfoSearchElement)element).getTypeInfo());
|
||||
|
||||
|
@ -96,6 +106,10 @@ public class PDOMSearchLabelProvider extends LabelProvider {
|
|||
|
||||
@Override
|
||||
public String getText(Object element) {
|
||||
if (element instanceof LineSearchElement) {
|
||||
return element.toString();
|
||||
}
|
||||
|
||||
if (element instanceof TypeInfoSearchElement) {
|
||||
return fTypeInfoLabelProvider.getText(((TypeInfoSearchElement)element).getTypeInfo());
|
||||
}
|
||||
|
@ -128,6 +142,29 @@ public class PDOMSearchLabelProvider extends LabelProvider {
|
|||
}
|
||||
|
||||
protected int getMatchCount(Object element) {
|
||||
if (element instanceof TranslationUnit) {
|
||||
TranslationUnit translationUnit = (TranslationUnit) element;
|
||||
AbstractTextSearchResult searchResult = fPage.getInput();
|
||||
if (searchResult instanceof PDOMSearchResult) {
|
||||
PDOMSearchResult pdomSearchResult = (PDOMSearchResult)searchResult;
|
||||
return pdomSearchResult.computeContainedMatches(searchResult, translationUnit.getFile()).length;
|
||||
}
|
||||
}
|
||||
return fPage.getInput().getMatchCount(element);
|
||||
}
|
||||
|
||||
public StyledString getStyledText(Object element) {
|
||||
if (!(element instanceof LineSearchElement))
|
||||
return new StyledString(getText(element));
|
||||
LineSearchElement lineElement = (LineSearchElement) element;
|
||||
int lineOffset = lineElement.getOffset();
|
||||
String lineContent = lineElement.getContent();
|
||||
StyledString styled = new StyledString(lineContent);
|
||||
for (Match match : lineElement.getMatches()) {
|
||||
int offset = match.getOffset();
|
||||
int length = Math.min(match.getLength(), lineContent.length() - (offset - lineOffset));
|
||||
styled.setStyle(offset - lineOffset, length, ColoringLabelProvider.HIGHLIGHT_STYLE);
|
||||
}
|
||||
return styled;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
package org.eclipse.cdt.internal.ui.search;
|
||||
|
||||
import org.eclipse.core.runtime.IPath;
|
||||
import org.eclipse.jface.viewers.StyledString;
|
||||
import org.eclipse.search.ui.text.AbstractTextSearchViewPage;
|
||||
|
||||
import org.eclipse.cdt.core.index.IIndexFileLocation;
|
||||
|
@ -54,4 +55,16 @@ public class PDOMSearchListLabelProvider extends PDOMSearchLabelProvider {
|
|||
|
||||
return text;
|
||||
}
|
||||
|
||||
@Override
|
||||
public StyledString getStyledText(Object element) {
|
||||
if (!(element instanceof LineSearchElement))
|
||||
return new StyledString(getText(element));
|
||||
LineSearchElement lineElement = (LineSearchElement) element;
|
||||
int lineNumber = lineElement.getLineNumber();
|
||||
final String filename = " - " + IndexLocationFactory.getPath(lineElement.getLocation()); //$NON-NLS-1$
|
||||
final String lineNumberString = " (" + lineNumber + ")"; //$NON-NLS-1$ //$NON-NLS-2$
|
||||
StyledString styled = super.getStyledText(element);
|
||||
return styled.append(filename + lineNumberString, StyledString.QUALIFIER_STYLER);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -110,8 +110,7 @@ public class PDOMSearchPatternQuery extends PDOMSearchQuery {
|
|||
}
|
||||
}
|
||||
|
||||
if (buff.length() > 0)
|
||||
{
|
||||
if (buff.length() > 0) {
|
||||
if (isCaseSensitive)
|
||||
patternList.add(Pattern.compile(buff.toString()));
|
||||
else
|
||||
|
@ -126,6 +125,7 @@ public class PDOMSearchPatternQuery extends PDOMSearchQuery {
|
|||
try {
|
||||
IndexFilter filter= IndexFilter.ALL;
|
||||
IIndexBinding[] bindings = index.findBindings(pattern, false, filter, monitor);
|
||||
ArrayList<IIndexBinding> matchedBindings = new ArrayList<IIndexBinding>();
|
||||
for (int i = 0; i < bindings.length; ++i) {
|
||||
IIndexBinding pdomBinding = bindings[i];
|
||||
|
||||
|
@ -137,8 +137,7 @@ public class PDOMSearchPatternQuery extends PDOMSearchQuery {
|
|||
boolean matches= false;
|
||||
if ((flags & FIND_ALL_TYPES) == FIND_ALL_TYPES) {
|
||||
matches= true;
|
||||
}
|
||||
else if (pdomBinding instanceof ICompositeType) {
|
||||
} else if (pdomBinding instanceof ICompositeType) {
|
||||
ICompositeType ct= (ICompositeType) pdomBinding;
|
||||
switch (ct.getKey()) {
|
||||
case ICompositeType.k_struct:
|
||||
|
@ -149,41 +148,34 @@ public class PDOMSearchPatternQuery extends PDOMSearchQuery {
|
|||
matches= (flags & FIND_UNION) != 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (pdomBinding instanceof IEnumeration) {
|
||||
} else if (pdomBinding instanceof IEnumeration) {
|
||||
matches= (flags & FIND_ENUM) != 0;
|
||||
}
|
||||
else if (pdomBinding instanceof IEnumerator) {
|
||||
} else if (pdomBinding instanceof IEnumerator) {
|
||||
matches= (flags & FIND_ENUMERATOR) != 0;
|
||||
}
|
||||
else if (pdomBinding instanceof IField) {
|
||||
} else if (pdomBinding instanceof IField) {
|
||||
matches= (flags & FIND_FIELD) != 0;
|
||||
}
|
||||
else if (pdomBinding instanceof ICPPMethod) {
|
||||
} else if (pdomBinding instanceof ICPPMethod) {
|
||||
matches= (flags & FIND_METHOD) != 0;
|
||||
}
|
||||
else if (pdomBinding instanceof IVariable) {
|
||||
} else if (pdomBinding instanceof IVariable) {
|
||||
matches= (flags & FIND_VARIABLE) != 0;
|
||||
}
|
||||
else if (pdomBinding instanceof IFunction) {
|
||||
} else if (pdomBinding instanceof IFunction) {
|
||||
matches= (flags & FIND_FUNCTION) != 0;
|
||||
}
|
||||
else if (pdomBinding instanceof ICPPNamespace || pdomBinding instanceof ICPPNamespaceAlias) {
|
||||
} else if (pdomBinding instanceof ICPPNamespace || pdomBinding instanceof ICPPNamespaceAlias) {
|
||||
matches= (flags & FIND_NAMESPACE) != 0;
|
||||
}
|
||||
else if (pdomBinding instanceof ITypedef) {
|
||||
} else if (pdomBinding instanceof ITypedef) {
|
||||
matches= (flags & FIND_TYPEDEF) != 0;
|
||||
}
|
||||
if (matches) {
|
||||
createMatches(index, pdomBinding);
|
||||
matchedBindings.add(pdomBinding);
|
||||
}
|
||||
}
|
||||
if ((flags & FIND_MACRO) != 0 && pattern.length == 1) {
|
||||
bindings = index.findMacroContainers(pattern[0], filter, monitor);
|
||||
for (IIndexBinding indexBinding : bindings) {
|
||||
createMatches(index, indexBinding);
|
||||
matchedBindings.add(indexBinding);
|
||||
}
|
||||
}
|
||||
createMatches(index, matchedBindings.toArray(new IIndexBinding[matchedBindings.size()]));
|
||||
} catch (CoreException e) {
|
||||
return e.getStatus();
|
||||
} catch (DOMException e) {
|
||||
|
|
|
@ -17,16 +17,26 @@ import java.util.HashMap;
|
|||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.IPath;
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
import org.eclipse.core.runtime.IStatus;
|
||||
import org.eclipse.core.runtime.OperationCanceledException;
|
||||
import org.eclipse.core.runtime.Status;
|
||||
import org.eclipse.jface.text.IDocument;
|
||||
import org.eclipse.jface.text.IRegion;
|
||||
import org.eclipse.jface.text.Region;
|
||||
import org.eclipse.search.ui.ISearchQuery;
|
||||
import org.eclipse.search.ui.ISearchResult;
|
||||
import org.eclipse.ui.IEditorInput;
|
||||
import org.eclipse.ui.IEditorPart;
|
||||
import org.eclipse.ui.IPathEditorInput;
|
||||
import org.eclipse.ui.texteditor.ITextEditor;
|
||||
|
||||
import org.eclipse.cdt.core.CCorePlugin;
|
||||
import org.eclipse.cdt.core.IPositionConverter;
|
||||
import org.eclipse.cdt.core.browser.ITypeReference;
|
||||
import org.eclipse.cdt.core.dom.ast.DOMException;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTFileLocation;
|
||||
|
@ -35,8 +45,10 @@ import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
|
|||
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
|
||||
import org.eclipse.cdt.core.index.IIndex;
|
||||
import org.eclipse.cdt.core.index.IIndexBinding;
|
||||
import org.eclipse.cdt.core.index.IIndexFile;
|
||||
import org.eclipse.cdt.core.index.IIndexFileLocation;
|
||||
import org.eclipse.cdt.core.index.IIndexName;
|
||||
import org.eclipse.cdt.core.index.IndexLocationFactory;
|
||||
import org.eclipse.cdt.core.model.CoreModel;
|
||||
import org.eclipse.cdt.core.model.ICElement;
|
||||
import org.eclipse.cdt.core.model.ICProject;
|
||||
|
@ -46,6 +58,8 @@ import org.eclipse.cdt.ui.CUIPlugin;
|
|||
import org.eclipse.cdt.internal.core.browser.ASTTypeInfo;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.ClassTypeHelper;
|
||||
|
||||
import org.eclipse.cdt.internal.ui.search.LineSearchElement.Match;
|
||||
|
||||
|
||||
/**
|
||||
* @author Doug Schaefer
|
||||
|
@ -130,18 +144,92 @@ public abstract class PDOMSearchQuery implements ISearchQuery {
|
|||
return false; // i.e. keep it
|
||||
}
|
||||
|
||||
private void collectNames(IIndex index, IIndexName[] names, boolean polymorphicCallsOnly) throws CoreException {
|
||||
private void createMatchesFromNames(Map<IIndexFile, Set<Match>> fileMatches, IIndexName[] names, boolean isPolymorphicOnly)
|
||||
throws CoreException {
|
||||
if (names == null)
|
||||
return;
|
||||
for (IIndexName name : names) {
|
||||
if (!filterName(name)) {
|
||||
if (!polymorphicCallsOnly || name.couldBePolymorphicMethodCall()) {
|
||||
if (!isPolymorphicOnly || name.couldBePolymorphicMethodCall()) {
|
||||
IASTFileLocation loc = name.getFileLocation();
|
||||
IIndexBinding binding= index.findBinding(name);
|
||||
final PDOMSearchMatch match = new PDOMSearchMatch(
|
||||
new TypeInfoSearchElement(index, name, binding),
|
||||
loc.getNodeOffset(), loc.getNodeLength());
|
||||
if (polymorphicCallsOnly)
|
||||
IIndexFile file = name.getFile();
|
||||
Set<Match> matches = fileMatches.get(file);
|
||||
if (matches == null) {
|
||||
matches = new HashSet<Match>();
|
||||
fileMatches.put(file, matches);
|
||||
}
|
||||
matches.add(new Match(loc.getNodeOffset(), loc.getNodeLength(), isPolymorphicOnly));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private Set<Match> convertMatchesPositions(IIndexFile file, Set<Match> matches) throws CoreException {
|
||||
IPath path = IndexLocationFactory.getPath(file.getLocation());
|
||||
long timestamp = file.getTimestamp();
|
||||
IPositionConverter converter = CCorePlugin.getPositionTrackerManager().findPositionConverter(path, timestamp);
|
||||
if (converter != null) {
|
||||
Set<Match> convertedMatches = new HashSet<Match>();
|
||||
for (Match match : matches) {
|
||||
IRegion region = new Region(match.getOffset(), match.getLength());
|
||||
region = converter.historicToActual(region);
|
||||
int offset = region.getOffset();
|
||||
int length = region.getLength();
|
||||
boolean isPolymorphicCall = match.isPolymorphicCall();
|
||||
convertedMatches.add(new Match(offset, length, isPolymorphicCall));
|
||||
}
|
||||
matches = convertedMatches;
|
||||
}
|
||||
return matches;
|
||||
}
|
||||
|
||||
private void collectNames(IIndex index, IIndexName[] names, IIndexName[] polymorphicNames) throws CoreException {
|
||||
// group all matched names by files
|
||||
Map<IIndexFile, Set<Match>> fileMatches = new HashMap<IIndexFile, Set<Match>>();
|
||||
createMatchesFromNames(fileMatches, names, false);
|
||||
createMatchesFromNames(fileMatches, polymorphicNames, true);
|
||||
// compute mapping from paths to dirty text editors
|
||||
IEditorPart[] dirtyEditors = CUIPlugin.getDirtyEditors();
|
||||
Map<IPath, ITextEditor> pathsDirtyEditors = new HashMap<IPath, ITextEditor>();
|
||||
for (IEditorPart editorPart : dirtyEditors) {
|
||||
if (editorPart instanceof ITextEditor) {
|
||||
ITextEditor textEditor = (ITextEditor)editorPart;
|
||||
IEditorInput editorInput = editorPart.getEditorInput();
|
||||
if (editorInput instanceof IPathEditorInput) {
|
||||
IPathEditorInput pathEditorInput = (IPathEditorInput)editorInput;
|
||||
pathsDirtyEditors.put(pathEditorInput.getPath(), textEditor);
|
||||
}
|
||||
}
|
||||
}
|
||||
// for each file with matches create line elements with matches
|
||||
for (Entry<IIndexFile, Set<Match>> entry : fileMatches.entrySet()) {
|
||||
IIndexFile file = entry.getKey();
|
||||
Set<Match> matches = entry.getValue();
|
||||
LineSearchElement[] lineElements = {};
|
||||
// check if there is dirty text editor corresponding to file and convert matches
|
||||
IPath absolutePath = IndexLocationFactory.getAbsolutePath(file.getLocation());
|
||||
if (pathsDirtyEditors.containsKey(absolutePath)) {
|
||||
matches = convertMatchesPositions(file, matches);
|
||||
// scan dirty editor and group matches by line elements
|
||||
ITextEditor textEditor = pathsDirtyEditors.get(absolutePath);
|
||||
IEditorInput input = textEditor.getEditorInput();
|
||||
IDocument document = textEditor.getDocumentProvider().getDocument(input);
|
||||
Match[] matchesArray = matches.toArray(new Match[matches.size()]);
|
||||
lineElements = LineSearchElement.createElements(file.getLocation(), matchesArray, document);
|
||||
} else {
|
||||
// scan file and group matches by line elements
|
||||
Match[] matchesArray = matches.toArray(new Match[matches.size()]);
|
||||
lineElements = LineSearchElement.createElements(file.getLocation(), matchesArray);
|
||||
}
|
||||
// create real PDOMSearchMatch with corresponding line elements
|
||||
for (LineSearchElement searchElement : lineElements) {
|
||||
for (Match lineMatch : searchElement.getMatches()) {
|
||||
int offset = lineMatch.getOffset();
|
||||
int length = lineMatch.getLength();
|
||||
PDOMSearchMatch match = new PDOMSearchMatch(searchElement, offset, length);
|
||||
if (lineMatch.isPolymorphicCall())
|
||||
match.setIsPolymorphicCall();
|
||||
|
||||
result.addMatch(match);
|
||||
}
|
||||
}
|
||||
|
@ -149,24 +237,45 @@ public abstract class PDOMSearchQuery implements ISearchQuery {
|
|||
}
|
||||
|
||||
protected void createMatches(IIndex index, IBinding binding) throws CoreException {
|
||||
if (binding != null) {
|
||||
IIndexName[] names= index.findNames(binding, flags);
|
||||
collectNames(index, names, false);
|
||||
if ((flags & FIND_REFERENCES) != 0) {
|
||||
if (binding instanceof ICPPMethod) {
|
||||
ICPPMethod m= (ICPPMethod) binding;
|
||||
try {
|
||||
ICPPMethod[] msInBases = ClassTypeHelper.findOverridden(m);
|
||||
for (ICPPMethod mInBase : msInBases) {
|
||||
names= index.findNames(mInBase, FIND_REFERENCES);
|
||||
collectNames(index, names, true);
|
||||
createMatches(index, new IBinding[] { binding });
|
||||
}
|
||||
|
||||
protected void createMatches(IIndex index, IBinding[] bindings) throws CoreException {
|
||||
if (bindings == null)
|
||||
return;
|
||||
IIndexName[] names= null;
|
||||
IIndexName[] polymorphicNames= null;
|
||||
for (IBinding binding : bindings) {
|
||||
if (binding != null) {
|
||||
IIndexName[] bindingNames= index.findNames(binding, flags);
|
||||
if (names == null) {
|
||||
names = bindingNames;
|
||||
} else {
|
||||
names= (IIndexName[]) ArrayUtil.addAll(IIndexName.class, names, bindingNames);
|
||||
}
|
||||
if ((flags & FIND_REFERENCES) != 0) {
|
||||
if (binding instanceof ICPPMethod) {
|
||||
ICPPMethod m= (ICPPMethod) binding;
|
||||
try {
|
||||
ICPPMethod[] msInBases = ClassTypeHelper.findOverridden(m);
|
||||
for (ICPPMethod mInBase : msInBases) {
|
||||
bindingNames= index.findNames(mInBase, FIND_REFERENCES);
|
||||
if (polymorphicNames == null) {
|
||||
polymorphicNames = bindingNames;
|
||||
} else {
|
||||
polymorphicNames= (IIndexName[]) ArrayUtil.addAll(IIndexName.class, names, bindingNames);
|
||||
}
|
||||
}
|
||||
} catch (DOMException e) {
|
||||
CUIPlugin.log(e);
|
||||
}
|
||||
} catch (DOMException e) {
|
||||
CUIPlugin.log(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (names != null) {
|
||||
collectNames(index, names, polymorphicNames);
|
||||
}
|
||||
}
|
||||
|
||||
protected void createLocalMatches(IASTTranslationUnit ast, IBinding binding) {
|
||||
|
@ -175,7 +284,9 @@ public abstract class PDOMSearchQuery implements ISearchQuery {
|
|||
names.addAll(Arrays.asList(ast.getDeclarationsInAST(binding)));
|
||||
names.addAll(Arrays.asList(ast.getDefinitionsInAST(binding)));
|
||||
names.addAll(Arrays.asList(ast.getReferences(binding)));
|
||||
|
||||
// collect local matches from AST
|
||||
IIndexFileLocation fileLocation = null;
|
||||
Set<Match> localMatches = new HashSet<Match>();
|
||||
for (IASTName name : names) {
|
||||
if (((flags & FIND_DECLARATIONS) != 0 && name.isDeclaration()) ||
|
||||
((flags & FIND_DEFINITIONS) != 0 && name.isDefinition()) ||
|
||||
|
@ -184,12 +295,48 @@ public abstract class PDOMSearchQuery implements ISearchQuery {
|
|||
if (typeInfo != null) {
|
||||
ITypeReference ref= typeInfo.getResolvedReference();
|
||||
if (ref != null) {
|
||||
result.addMatch(new PDOMSearchMatch(
|
||||
new TypeInfoSearchElement(typeInfo), ref.getOffset(), ref.getLength()));
|
||||
localMatches.add(new Match(ref.getOffset(), ref.getLength(), false));
|
||||
fileLocation = typeInfo.getIFL();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// search for dirty editor
|
||||
ITextEditor dirtyTextEditor = null;
|
||||
String fullPath = ast.getFilePath();
|
||||
for (IEditorPart editorPart : CUIPlugin.getDirtyEditors()) {
|
||||
if (editorPart instanceof ITextEditor) {
|
||||
ITextEditor textEditor = (ITextEditor)editorPart;
|
||||
IEditorInput editorInput = editorPart.getEditorInput();
|
||||
if (editorInput instanceof IPathEditorInput) {
|
||||
IPathEditorInput pathEditorInput = (IPathEditorInput)editorInput;
|
||||
IPath path = pathEditorInput.getPath();
|
||||
if (fullPath.equals(path.toOSString())) {
|
||||
dirtyTextEditor = textEditor;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// create line search elements
|
||||
Match[] matchesArray = localMatches.toArray(new Match[localMatches.size()]);
|
||||
LineSearchElement[] lineElements;
|
||||
if (dirtyTextEditor != null) {
|
||||
IEditorInput input = dirtyTextEditor.getEditorInput();
|
||||
IDocument document = dirtyTextEditor.getDocumentProvider().getDocument(input);
|
||||
lineElements = LineSearchElement.createElements(fileLocation, matchesArray, document);
|
||||
} else {
|
||||
lineElements = LineSearchElement.createElements(fileLocation, matchesArray);
|
||||
}
|
||||
// create real PDOMSearchMatch with corresponding line elements
|
||||
for (LineSearchElement searchElement : lineElements) {
|
||||
for (Match lineMatch : searchElement.getMatches()) {
|
||||
int offset = lineMatch.getOffset();
|
||||
int length = lineMatch.getLength();
|
||||
PDOMSearchMatch match = new PDOMSearchMatch(searchElement, offset, length);
|
||||
result.addMatch(match);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -156,6 +156,12 @@ public class PDOMSearchResult extends AbstractTextSearchResult implements IEdito
|
|||
return ResourcesPlugin.getWorkspace().getRoot().getFile(new Path(location.getFullPath()));
|
||||
}
|
||||
} catch(CoreException ce) { /* fall-through to return null */ }
|
||||
} else if (element instanceof PDOMSearchElement) {
|
||||
PDOMSearchElement searchElement = (PDOMSearchElement)element;
|
||||
IIndexFileLocation location = searchElement.getLocation();
|
||||
if(location.getFullPath()!=null) {
|
||||
return ResourcesPlugin.getWorkspace().getRoot().getFile(new Path(location.getFullPath()));
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -12,8 +12,11 @@
|
|||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.ui.search;
|
||||
|
||||
import org.eclipse.jface.viewers.StyledString;
|
||||
import org.eclipse.search.ui.text.AbstractTextSearchViewPage;
|
||||
|
||||
import org.eclipse.cdt.internal.core.model.TranslationUnit;
|
||||
|
||||
import org.eclipse.cdt.internal.ui.util.Messages;
|
||||
|
||||
/**
|
||||
|
@ -36,4 +39,26 @@ public class PDOMSearchTreeLabelProvider extends PDOMSearchLabelProvider {
|
|||
return text + " " //$NON-NLS-1$
|
||||
+ Messages.format(CSearchMessages.CSearchResultCollector_matches, new Integer(count));
|
||||
}
|
||||
|
||||
@Override
|
||||
public StyledString getStyledText(Object element) {
|
||||
if (element instanceof TranslationUnit) {
|
||||
StyledString styled = new StyledString(super.getText(element));
|
||||
final int count= getMatchCount(element);
|
||||
if (count > 1) {
|
||||
final String matchesCount = " " //$NON-NLS-1$
|
||||
+ Messages.format(CSearchMessages.CSearchResultCollector_matches, new Integer(count));
|
||||
styled.append(matchesCount, StyledString.COUNTER_STYLER);
|
||||
return styled;
|
||||
}
|
||||
}
|
||||
if (element instanceof LineSearchElement) {
|
||||
LineSearchElement lineElement = (LineSearchElement) element;
|
||||
int lineNumber = lineElement.getLineNumber();
|
||||
String lineNumberString = Messages.format("{0}: ", Integer.valueOf(lineNumber)); //$NON-NLS-1$
|
||||
StyledString styled = new StyledString(lineNumberString, StyledString.QUALIFIER_STYLER);
|
||||
return styled.append(super.getStyledText(element));
|
||||
}
|
||||
return new StyledString(getText(element));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,6 +32,7 @@ import org.eclipse.cdt.core.model.ICElement;
|
|||
import org.eclipse.cdt.ui.CUIPlugin;
|
||||
|
||||
import org.eclipse.cdt.internal.ui.util.EditorUtility;
|
||||
import org.eclipse.cdt.internal.ui.viewsupport.ColoringLabelProvider;
|
||||
|
||||
/**
|
||||
* Implementation of the search view page for index based searches.
|
||||
|
@ -81,6 +82,26 @@ public class PDOMSearchViewPage extends AbstractTextSearchViewPage {
|
|||
*
|
||||
*/
|
||||
private class SearchViewerComparator extends ViewerComparator {
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.jface.viewers.ViewerComparator#compare(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public int compare(Viewer viewer, Object e1, Object e2) {
|
||||
if (e1 instanceof LineSearchElement && e2 instanceof LineSearchElement) {
|
||||
LineSearchElement l1 = (LineSearchElement) e1;
|
||||
LineSearchElement l2 = (LineSearchElement) e2;
|
||||
if (viewer instanceof TableViewer) {
|
||||
String p1 = l1.getLocation().getURI().getPath();
|
||||
String p2 = l2.getLocation().getURI().getPath();
|
||||
int cmp = p1.compareTo(p2);
|
||||
if (cmp != 0)
|
||||
return cmp;
|
||||
}
|
||||
return l1.getLineNumber() - l2.getLineNumber();
|
||||
}
|
||||
return super.compare(viewer, e1, e2);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.jface.viewers.ViewerComparator#category(java.lang.Object)
|
||||
*/
|
||||
|
@ -128,7 +149,9 @@ public class PDOMSearchViewPage extends AbstractTextSearchViewPage {
|
|||
contentProvider = new PDOMSearchTreeContentProvider(this);
|
||||
viewer.setComparator(new SearchViewerComparator());
|
||||
viewer.setContentProvider((PDOMSearchTreeContentProvider)contentProvider);
|
||||
viewer.setLabelProvider(new PDOMSearchTreeLabelProvider(this));
|
||||
PDOMSearchTreeLabelProvider innerLabelProvider = new PDOMSearchTreeLabelProvider(this);
|
||||
ColoringLabelProvider labelProvider = new ColoringLabelProvider(innerLabelProvider);
|
||||
viewer.setLabelProvider(labelProvider);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -136,7 +159,9 @@ public class PDOMSearchViewPage extends AbstractTextSearchViewPage {
|
|||
contentProvider = new PDOMSearchListContentProvider(this);
|
||||
viewer.setComparator(new SearchViewerComparator());
|
||||
viewer.setContentProvider((PDOMSearchListContentProvider)contentProvider);
|
||||
viewer.setLabelProvider(new PDOMSearchListLabelProvider(this));
|
||||
PDOMSearchListLabelProvider innerLabelProvider = new PDOMSearchListLabelProvider(this);
|
||||
ColoringLabelProvider labelProvider = new ColoringLabelProvider(innerLabelProvider);
|
||||
viewer.setLabelProvider(labelProvider);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -148,7 +173,7 @@ public class PDOMSearchViewPage extends AbstractTextSearchViewPage {
|
|||
Object element= ((PDOMSearchMatch)match).getElement();
|
||||
IIndexFileLocation ifl= ((PDOMSearchElement)element).getLocation();
|
||||
IPath path = IndexLocationFactory.getPath(ifl);
|
||||
IEditorPart editor = EditorUtility.openInEditor(path, null);
|
||||
IEditorPart editor = EditorUtility.openInEditor(path, null, activate);
|
||||
if (editor instanceof ITextEditor) {
|
||||
ITextEditor textEditor = (ITextEditor)editor;
|
||||
textEditor.selectAndReveal(currentOffset, currentLength);
|
||||
|
|
|
@ -243,7 +243,6 @@ public class EditorUtility {
|
|||
String desc= CUIPlugin.getResourceString("Editorutility.closedproject.description"); //$NON-NLS-1$
|
||||
errorMsg.setMessage(MessageFormat.format(desc, new Object[]{project.getName()}));
|
||||
errorMsg.open();
|
||||
|
||||
}
|
||||
|
||||
private static IEditorPart openInEditor(IEditorInput input, String editorID, boolean activate) throws PartInitException {
|
||||
|
@ -316,8 +315,12 @@ public class EditorUtility {
|
|||
* @throws PartInitException
|
||||
*/
|
||||
public static IEditorPart openInEditor(IPath location, ICElement element) throws PartInitException {
|
||||
return openInEditor(location, element, true);
|
||||
}
|
||||
|
||||
public static IEditorPart openInEditor(IPath location, ICElement element, boolean activate) throws PartInitException {
|
||||
IEditorInput input= getEditorInputForLocation(location, element);
|
||||
return EditorUtility.openInEditor(input, getEditorID(input, element), true);
|
||||
return EditorUtility.openInEditor(input, getEditorID(input, element), activate);
|
||||
}
|
||||
|
||||
public static IEditorPart openInEditor(URI locationURI, ICElement element) throws PartInitException {
|
||||
|
|
Loading…
Add table
Reference in a new issue