mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-08-04 14:55:41 +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.IASTNodeSelector;
|
||||
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.ITranslationUnit;
|
||||
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.CEditor;
|
||||
import org.eclipse.cdt.internal.ui.editor.EditorHighlightingSynchronizer;
|
||||
import org.eclipse.cdt.internal.ui.search.OccurrencesFinder;
|
||||
import org.eclipse.cdt.internal.ui.search.IOccurrencesFinder.OccurrenceLocation;
|
||||
import org.eclipse.cdt.internal.ui.search.LinkedNamesFinder;
|
||||
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.ICommandAccess;
|
||||
|
@ -113,7 +111,7 @@ public class LinkedNamesAssistProposal implements ICCompletionProposal, IComplet
|
|||
private String fLabel;
|
||||
private String fValueSuggestion;
|
||||
private int fRelevance;
|
||||
private OccurrenceLocation[] fLocations;
|
||||
private IRegion[] fLocations;
|
||||
|
||||
public LinkedNamesAssistProposal(ITranslationUnit tu) {
|
||||
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 {
|
||||
IASTNodeSelector selector= astRoot.getNodeSelector(null);
|
||||
IASTName name= selector.findEnclosingName(secectionOffset, selectionLength);
|
||||
|
||||
if (name != null) {
|
||||
IBinding binding= name.resolveBinding();
|
||||
if (binding != null) {
|
||||
OccurrencesFinder occurrencesFinder= new OccurrencesFinder();
|
||||
if (occurrencesFinder.initialize(astRoot, name) == null) {
|
||||
fLocations= occurrencesFinder.getOccurrences();
|
||||
}
|
||||
}
|
||||
fLocations = LinkedNamesFinder.findByName(astRoot, name);
|
||||
}
|
||||
return Status.OK_STATUS;
|
||||
}
|
||||
|
@ -163,9 +154,9 @@ public class LinkedNamesAssistProposal implements ICCompletionProposal, IComplet
|
|||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
|
@ -176,7 +167,7 @@ public class LinkedNamesAssistProposal implements ICCompletionProposal, IComplet
|
|||
* @param location the location to compute the rank for
|
||||
* @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;
|
||||
if (relativeRank < 0)
|
||||
return Integer.MAX_VALUE + relativeRank;
|
||||
|
@ -188,7 +179,7 @@ public class LinkedNamesAssistProposal implements ICCompletionProposal, IComplet
|
|||
IDocument document= viewer.getDocument();
|
||||
LinkedPositionGroup group= new LinkedPositionGroup();
|
||||
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));
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue