From c09268625c55f695d48039a90c52f34d0d70fe31 Mon Sep 17 00:00:00 2001 From: Markus Schorn Date: Mon, 4 Sep 2006 09:15:46 +0000 Subject: [PATCH] Call Hierarchy: When invoked from editor, allow for partial selections. --- .../ui/callhierarchy/CallHierarchyUI.java | 10 +- .../FindNameForSelectionVisitor.java | 91 +++++++++++++++++++ 2 files changed, 95 insertions(+), 6 deletions(-) create mode 100644 core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/viewsupport/FindNameForSelectionVisitor.java diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/callhierarchy/CallHierarchyUI.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/callhierarchy/CallHierarchyUI.java index fb551cf9655..2f4ebab55de 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/callhierarchy/CallHierarchyUI.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/callhierarchy/CallHierarchyUI.java @@ -36,6 +36,7 @@ import org.eclipse.cdt.internal.ui.editor.CEditor; import org.eclipse.cdt.internal.ui.missingapi.CIndexQueries; import org.eclipse.cdt.internal.ui.util.ExceptionHandler; import org.eclipse.cdt.internal.ui.viewsupport.CElementLabels; +import org.eclipse.cdt.internal.ui.viewsupport.FindNameForSelectionVisitor; public class CallHierarchyUI { @@ -138,11 +139,8 @@ public class CallHierarchyUI { int options= ILanguage.AST_SKIP_ALL_HEADERS | ILanguage.AST_USE_INDEX; IASTTranslationUnit ast = workingCopy.getLanguage().getASTTranslationUnit(workingCopy, options); - IASTName[] selectedNames = workingCopy.getLanguage().getSelectedNames(ast, selectionStart, selectionLength); - - if (selectedNames.length > 0 && selectedNames[0] != null) { // just right, only one name selected - return selectedNames[0]; - } - return null; + FindNameForSelectionVisitor finder= new FindNameForSelectionVisitor(ast.getFilePath(), selectionStart, selectionLength); + ast.accept(finder); + return finder.getSelectedName(); } } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/viewsupport/FindNameForSelectionVisitor.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/viewsupport/FindNameForSelectionVisitor.java new file mode 100644 index 00000000000..f76f83fcd6b --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/viewsupport/FindNameForSelectionVisitor.java @@ -0,0 +1,91 @@ +/******************************************************************************* + * Copyright (c) 2006 Wind River Systems, 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: + * Markus Schorn - initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.internal.ui.viewsupport; + +import org.eclipse.cdt.core.dom.ast.ASTVisitor; +import org.eclipse.cdt.core.dom.ast.IASTDeclaration; +import org.eclipse.cdt.core.dom.ast.IASTFileLocation; +import org.eclipse.cdt.core.dom.ast.IASTName; +import org.eclipse.cdt.core.dom.ast.IASTNode; + +/** + * Searches for a name related to the given selection. The first choice will be the + * largest name inside the selection. If it does not exist the smallest name + * surounding the selection is taken. + * @see IASTNode#accept(ASTVisitor) + * @since 4.0 + */ +public class FindNameForSelectionVisitor extends ASTVisitor { + + private String fFilePath; + private int fOffset; + private int fEndOffset; + private IASTName fSelectedName; + + public FindNameForSelectionVisitor(String filePath, int selectionStart, int selectionLength) { + fFilePath= filePath; + fOffset= selectionStart; + fEndOffset= selectionStart+selectionLength; + + shouldVisitDeclarations= true; + shouldVisitNames= true; + } + + /** + * After the visitor was accepted by an ast-node you can query the + * selected name. + * @return the name found for the selection, or null. + * @since 4.0 + */ + public IASTName getSelectedName() { + return fSelectedName; + } + + public int visit(IASTDeclaration declaration) { + IASTFileLocation loc= declaration.getFileLocation(); + if (!loc.getFileName().equals(fFilePath)) { + return PROCESS_SKIP; + } + int offset= loc.getNodeOffset(); + int endoffset= offset + loc.getNodeLength(); + if (endoffset < fOffset || fEndOffset < offset) { + return PROCESS_SKIP; + } + + return PROCESS_CONTINUE; + } + + public int visit(IASTName name) { + IASTFileLocation loc= name.getFileLocation(); + if (!loc.getFileName().equals(fFilePath)) { + return PROCESS_SKIP; + } + int offset= loc.getNodeOffset(); + int endoffset= offset + loc.getNodeLength(); + + // check if name is inside of selection + if (fOffset <= offset && endoffset <= fEndOffset) { + fSelectedName= name; + return PROCESS_ABORT; + } + + // check if name surrounds selection + if (offset <= fOffset && fEndOffset <= endoffset) { + fSelectedName= name; + // continue as we might find a name inside of the selection, + // which is preferred. + return PROCESS_CONTINUE; + } + + return PROCESS_CONTINUE; + } +}