diff --git a/core/org.eclipse.cdt.ui/plugin.xml b/core/org.eclipse.cdt.ui/plugin.xml index 3a72f445685..713f45ea7da 100644 --- a/core/org.eclipse.cdt.ui/plugin.xml +++ b/core/org.eclipse.cdt.ui/plugin.xml @@ -548,6 +548,12 @@ label="%Dummy.label" value="0,0,0"> + + { + 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 result = new ArrayList(); + 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 result = new ArrayList(); + 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()]); + } +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/PDOMSearchLabelProvider.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/PDOMSearchLabelProvider.java index ceb2c6a15b0..952ecb5ba65 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/PDOMSearchLabelProvider.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/PDOMSearchLabelProvider.java @@ -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; + } } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/PDOMSearchListLabelProvider.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/PDOMSearchListLabelProvider.java index bf1c599bb27..a63782a2497 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/PDOMSearchListLabelProvider.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/PDOMSearchListLabelProvider.java @@ -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); + } } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/PDOMSearchPatternQuery.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/PDOMSearchPatternQuery.java index 2346b0fb14c..4115a44e255 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/PDOMSearchPatternQuery.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/PDOMSearchPatternQuery.java @@ -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 matchedBindings = new ArrayList(); 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) { diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/PDOMSearchQuery.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/PDOMSearchQuery.java index 106489f9d06..5c806707a24 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/PDOMSearchQuery.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/PDOMSearchQuery.java @@ -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> 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 matches = fileMatches.get(file); + if (matches == null) { + matches = new HashSet(); + fileMatches.put(file, matches); + } + matches.add(new Match(loc.getNodeOffset(), loc.getNodeLength(), isPolymorphicOnly)); + } + } + + } + } + + private Set convertMatchesPositions(IIndexFile file, Set matches) throws CoreException { + IPath path = IndexLocationFactory.getPath(file.getLocation()); + long timestamp = file.getTimestamp(); + IPositionConverter converter = CCorePlugin.getPositionTrackerManager().findPositionConverter(path, timestamp); + if (converter != null) { + Set convertedMatches = new HashSet(); + 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> fileMatches = new HashMap>(); + createMatchesFromNames(fileMatches, names, false); + createMatchesFromNames(fileMatches, polymorphicNames, true); + // compute mapping from paths to dirty text editors + IEditorPart[] dirtyEditors = CUIPlugin.getDirtyEditors(); + Map pathsDirtyEditors = new HashMap(); + 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> entry : fileMatches.entrySet()) { + IIndexFile file = entry.getKey(); + Set 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 localMatches = new HashSet(); 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); + } + } } } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/PDOMSearchResult.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/PDOMSearchResult.java index e33d4774a41..90f18033f7a 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/PDOMSearchResult.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/PDOMSearchResult.java @@ -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; } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/PDOMSearchTreeLabelProvider.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/PDOMSearchTreeLabelProvider.java index 8fc764bc5c5..2fc9192fc8b 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/PDOMSearchTreeLabelProvider.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/PDOMSearchTreeLabelProvider.java @@ -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)); + } } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/PDOMSearchViewPage.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/PDOMSearchViewPage.java index d01ba44de7e..2e40fdd5c45 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/PDOMSearchViewPage.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/PDOMSearchViewPage.java @@ -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); diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/util/EditorUtility.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/util/EditorUtility.java index e4524ce8b4f..2415149d7f2 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/util/EditorUtility.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/util/EditorUtility.java @@ -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 {