mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-08-04 06:45:43 +02:00
Bug 246936.
This commit is contained in:
parent
d62a7dc8a6
commit
333f92bbe5
2 changed files with 144 additions and 16 deletions
|
@ -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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue