1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-08-04 06:45:43 +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.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));
}