1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-08-04 14:55:41 +02:00

Bug 246936.

This commit is contained in:
Sergey Prigogin 2008-09-22 03:58:58 +00:00
parent d62a7dc8a6
commit 333f92bbe5
2 changed files with 144 additions and 16 deletions

View file

@ -0,0 +1,137 @@
/*******************************************************************************
* Copyright (c) 2007, 2008 Google, Inc 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:
* Sergey Prigogin (Google) - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.ui.search;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.Region;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTFileLocation;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
/**
* Finds locations of linked names. Used by Rename in File.
*/
public class LinkedNamesFinder {
private static final IRegion[] EMPTY_LOCATIONS_ARRAY = new IRegion[0];
public LinkedNamesFinder() {
super();
}
public static IRegion[] findByName(IASTTranslationUnit root, IASTName name) {
IBinding target = name.resolveBinding();
if (target == null) {
return EMPTY_LOCATIONS_ARRAY;
}
BindingFinder bindingFinder = new BindingFinder(root);
bindingFinder.find(target);
return bindingFinder.getLocations();
}
private static class BindingFinder {
private final IASTTranslationUnit root;
private final List<IRegion> locations;
public BindingFinder(IASTTranslationUnit root) {
this.root = root;
locations = new ArrayList<IRegion>();
}
public void find(IBinding target) {
try {
if (target instanceof ICPPConstructor ||
target instanceof ICPPMethod && ((ICPPMethod) target).isDestructor()) {
target = ((ICPPMethod) target).getClassOwner();
}
} catch (DOMException e1) {
}
findBinding(target);
if (target instanceof ICPPClassType) {
try {
ICPPConstructor[] constructors = ((ICPPClassType) target).getConstructors();
for (IBinding ctor : constructors) {
findBinding(ctor);
}
ICPPMethod[] methods = ((ICPPClassType) target).getMethods();
for (ICPPMethod method : methods) {
if (method.isDestructor()) {
findBinding(method);
}
}
} catch (DOMException e) {
}
}
}
public IRegion[] getLocations() {
if (locations.isEmpty()) {
return EMPTY_LOCATIONS_ARRAY;
}
return locations.toArray(new IRegion[locations.size()]);
}
private void findBinding(IBinding target) {
IASTName[] names= root.getDeclarationsInAST(target);
for (int i= 0; i < names.length; i++) {
IASTName candidate= names[i];
if (candidate.isPartOfTranslationUnitFile()) {
addLocation(candidate);
}
}
names= root.getReferences(target);
for (int i= 0; i < names.length; i++) {
IASTName candidate= names[i];
if (candidate.isPartOfTranslationUnitFile()) {
addLocation(candidate);
}
}
}
private void addLocation(IASTName name) {
IBinding binding = name.resolveBinding();
if (binding != null) {
if (name instanceof ICPPASTTemplateId) {
name= ((ICPPASTTemplateId) name).getTemplateName();
}
IASTFileLocation fileLocation= name.getImageLocation();
if (fileLocation == null || !root.getFilePath().equals(fileLocation.getFileName())) {
fileLocation= name.getFileLocation();
}
if (fileLocation != null) {
int offset= fileLocation.getNodeOffset();
int length= fileLocation.getNodeLength();
try {
if (binding instanceof ICPPMethod && ((ICPPMethod) binding).isDestructor()) {
// Skip tilde.
offset++;
length--;
}
} catch (DOMException e) {
}
if (offset >= 0 && length > 0) {
locations.add(new Region(offset, length));
}
}
}
}
}
}

View file

@ -46,7 +46,6 @@ import org.eclipse.ui.texteditor.link.EditorLinkedModeUI;
import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNodeSelector; import org.eclipse.cdt.core.dom.ast.IASTNodeSelector;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.model.ILanguage; import org.eclipse.cdt.core.model.ILanguage;
import org.eclipse.cdt.core.model.ITranslationUnit; import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.cdt.ui.CUIPlugin; import org.eclipse.cdt.ui.CUIPlugin;
@ -58,8 +57,7 @@ import org.eclipse.cdt.internal.ui.CPluginImages;
import org.eclipse.cdt.internal.ui.editor.ASTProvider; import org.eclipse.cdt.internal.ui.editor.ASTProvider;
import org.eclipse.cdt.internal.ui.editor.CEditor; import org.eclipse.cdt.internal.ui.editor.CEditor;
import org.eclipse.cdt.internal.ui.editor.EditorHighlightingSynchronizer; import org.eclipse.cdt.internal.ui.editor.EditorHighlightingSynchronizer;
import org.eclipse.cdt.internal.ui.search.OccurrencesFinder; import org.eclipse.cdt.internal.ui.search.LinkedNamesFinder;
import org.eclipse.cdt.internal.ui.search.IOccurrencesFinder.OccurrenceLocation;
import org.eclipse.cdt.internal.ui.text.correction.CorrectionCommandHandler; import org.eclipse.cdt.internal.ui.text.correction.CorrectionCommandHandler;
import org.eclipse.cdt.internal.ui.text.correction.CorrectionMessages; import org.eclipse.cdt.internal.ui.text.correction.CorrectionMessages;
import org.eclipse.cdt.internal.ui.text.correction.ICommandAccess; import org.eclipse.cdt.internal.ui.text.correction.ICommandAccess;
@ -113,7 +111,7 @@ public class LinkedNamesAssistProposal implements ICCompletionProposal, IComplet
private String fLabel; private String fLabel;
private String fValueSuggestion; private String fValueSuggestion;
private int fRelevance; private int fRelevance;
private OccurrenceLocation[] fLocations; private IRegion[] fLocations;
public LinkedNamesAssistProposal(ITranslationUnit tu) { public LinkedNamesAssistProposal(ITranslationUnit tu) {
this(CorrectionMessages.LinkedNamesAssistProposal_description, tu, null); this(CorrectionMessages.LinkedNamesAssistProposal_description, tu, null);
@ -144,15 +142,8 @@ public class LinkedNamesAssistProposal implements ICCompletionProposal, IComplet
public IStatus runOnAST(ILanguage lang, IASTTranslationUnit astRoot) throws CoreException { public IStatus runOnAST(ILanguage lang, IASTTranslationUnit astRoot) throws CoreException {
IASTNodeSelector selector= astRoot.getNodeSelector(null); IASTNodeSelector selector= astRoot.getNodeSelector(null);
IASTName name= selector.findEnclosingName(secectionOffset, selectionLength); IASTName name= selector.findEnclosingName(secectionOffset, selectionLength);
if (name != null) { if (name != null) {
IBinding binding= name.resolveBinding(); fLocations = LinkedNamesFinder.findByName(astRoot, name);
if (binding != null) {
OccurrencesFinder occurrencesFinder= new OccurrencesFinder();
if (occurrencesFinder.initialize(astRoot, name) == null) {
fLocations= occurrencesFinder.getOccurrences();
}
}
} }
return Status.OK_STATUS; return Status.OK_STATUS;
} }
@ -163,9 +154,9 @@ public class LinkedNamesAssistProposal implements ICCompletionProposal, IComplet
} }
// Sort the locations starting with the one @ offset. // Sort the locations starting with the one @ offset.
Arrays.sort(fLocations, new Comparator<OccurrenceLocation>() { Arrays.sort(fLocations, new Comparator<IRegion>() {
public int compare(OccurrenceLocation n1, OccurrenceLocation n2) { public int compare(IRegion n1, IRegion n2) {
return rank(n1) - rank(n2); return rank(n1) - rank(n2);
} }
@ -176,7 +167,7 @@ public class LinkedNamesAssistProposal implements ICCompletionProposal, IComplet
* @param location the location to compute the rank for * @param location the location to compute the rank for
* @return the rank of the location with respect to the invocation offset * @return the rank of the location with respect to the invocation offset
*/ */
private int rank(OccurrenceLocation location) { private int rank(IRegion location) {
int relativeRank= location.getOffset() + location.getLength() - offset; int relativeRank= location.getOffset() + location.getLength() - offset;
if (relativeRank < 0) if (relativeRank < 0)
return Integer.MAX_VALUE + relativeRank; return Integer.MAX_VALUE + relativeRank;
@ -188,7 +179,7 @@ public class LinkedNamesAssistProposal implements ICCompletionProposal, IComplet
IDocument document= viewer.getDocument(); IDocument document= viewer.getDocument();
LinkedPositionGroup group= new LinkedPositionGroup(); LinkedPositionGroup group= new LinkedPositionGroup();
for (int i= 0; i < fLocations.length; i++) { for (int i= 0; i < fLocations.length; i++) {
OccurrenceLocation item= fLocations[i]; IRegion item= fLocations[i];
group.addPosition(new LinkedPosition(document, item.getOffset(), item.getLength(), i)); group.addPosition(new LinkedPosition(document, item.getOffset(), item.getLength(), i));
} }