From 333f92bbe5db04553a73d2329798a7eb0d61ead3 Mon Sep 17 00:00:00 2001 From: Sergey Prigogin Date: Mon, 22 Sep 2008 03:58:58 +0000 Subject: [PATCH] Bug 246936. --- .../internal/ui/search/LinkedNamesFinder.java | 137 ++++++++++++++++++ .../proposals/LinkedNamesAssistProposal.java | 23 +-- 2 files changed, 144 insertions(+), 16 deletions(-) create mode 100644 core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/LinkedNamesFinder.java diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/LinkedNamesFinder.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/LinkedNamesFinder.java new file mode 100644 index 00000000000..35ea98bb235 --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/LinkedNamesFinder.java @@ -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 locations; + + public BindingFinder(IASTTranslationUnit root) { + this.root = root; + locations = new ArrayList(); + } + + 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)); + } + } + } + } + } +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/correction/proposals/LinkedNamesAssistProposal.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/correction/proposals/LinkedNamesAssistProposal.java index 1444d67d1c4..ff8cc009073 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/correction/proposals/LinkedNamesAssistProposal.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/correction/proposals/LinkedNamesAssistProposal.java @@ -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() { + Arrays.sort(fLocations, new Comparator() { - 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)); }