Index: core extension/org/eclipse/jdt/internal/corext/callhierarchy/CallHierarchy.java =================================================================== RCS file: core extension/org/eclipse/jdt/internal/corext/callhierarchy/CallHierarchy.java diff -N core extension/org/eclipse/jdt/internal/corext/callhierarchy/CallHierarchy.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ core extension/org/eclipse/jdt/internal/corext/callhierarchy/CallHierarchy.java 16 Apr 2003 07:00:17 -0000 @@ -0,0 +1,240 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * Jesper Kamstrup Linnet (eclipse@kamstrup-linnet.dk) - initial API and implementation + * (report 36180: Callers/Callees view) + ******************************************************************************/ +package org.eclipse.jdt.internal.corext.callhierarchy; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.StringTokenizer; + +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.jdt.core.IJavaElement; +import org.eclipse.jdt.core.IMethod; +import org.eclipse.jdt.core.search.IJavaSearchScope; +import org.eclipse.jdt.core.search.SearchEngine; +import org.eclipse.jdt.internal.ui.JavaPlugin; +import org.eclipse.jdt.internal.ui.callhierarchy.ICallHierarchyPreferencesConstants; +import org.eclipse.jdt.internal.ui.util.StringMatcher; +import org.eclipse.jface.preference.IPreferenceStore; + +public class CallHierarchy { + private static final String PREF_USE_FILTERS = "PREF_USE_FILTERS"; + private static final String PREF_FILTERS_LIST = "PREF_FILTERS_LIST"; + + private static final String DEFAULT_IGNORE_FILTERS = "java.*,javax.*"; + private static CallHierarchy fgInstance; + private IJavaSearchScope fSearchScope; + private StringMatcher[] fFilters; + + public static CallHierarchy getDefault() { + if (fgInstance == null) { + fgInstance = new CallHierarchy(); + } + + return fgInstance; + } + + /** + * @return + */ + public boolean isSearchForCalleesUsingImplementorsEnabled() { + IPreferenceStore settings = JavaPlugin.getDefault().getPreferenceStore(); + + return settings.getBoolean(ICallHierarchyPreferencesConstants.PREF_USE_IMPLEMENTORS_FOR_CALLEE_SEARCH); + } + + /** + * @return + */ + public boolean isSearchForCallersUsingImplementorsEnabled() { + IPreferenceStore settings = JavaPlugin.getDefault().getPreferenceStore(); + + return settings.getBoolean(ICallHierarchyPreferencesConstants.PREF_USE_IMPLEMENTORS_FOR_CALLER_SEARCH); + } + + /** + * @param method + * + * @return + */ + public Collection getImplementingMethods(IMethod method) { + if (isSearchForCalleesUsingImplementorsEnabled()) { + IJavaElement[] result = Implementors.getInstance().searchForImplementors(new IJavaElement[] { + method + }, new NullProgressMonitor()); + + if ((result != null) && (result.length > 0)) { + return Arrays.asList(result); + } + } + + return new ArrayList(0); + } + + /** + * @param method + * + * @return + */ + public Collection getInterfaceMethods(IMethod method) { + if (isSearchForCallersUsingImplementorsEnabled()) { + IJavaElement[] result = Implementors.getInstance().searchForInterfaces(new IJavaElement[] { + method + }, new NullProgressMonitor()); + + if ((result != null) && (result.length > 0)) { + return Arrays.asList(result); + } + } + + return new ArrayList(0); + } + + public MethodWrapper getCallerRoot(IMethod method) { + return new CallerMethodWrapper(null, new MethodCall(method)); + } + + public MethodWrapper getCalleeRoot(IMethod method) { + return new CalleeMethodWrapper(null, new MethodCall(method)); + } + + public static CallLocation getCallLocation(Object element) { + CallLocation callLocation = null; + + if (element instanceof MethodWrapper) { + MethodWrapper methodWrapper = (MethodWrapper) element; + MethodCall methodCall = methodWrapper.getMethodCall(); + + if (methodCall != null) { + callLocation = methodCall.getFirstCallLocation(); + } + } else if (element instanceof CallLocation) { + callLocation = (CallLocation) element; + } + + return callLocation; + } + + public IJavaSearchScope getSearchScope() { + if (fSearchScope != null) { + return fSearchScope; + } + + Utility.logDebug("No search scope was set"); + + return SearchEngine.createWorkspaceScope(); + } + + public void setSearchScope(IJavaSearchScope searchScope) { + this.fSearchScope = searchScope; + } + + /** + * Checks whether the fully qualified name is ignored by the set filters. + * + * @param fullyQualifiedName + * + * @return True if the fully qualified name is ignored. + */ + public boolean isIgnored(String fullyQualifiedName) { + if ((getIgnoreFilters() != null) && (getIgnoreFilters().length > 0)) { + for (int i = 0; i < getIgnoreFilters().length; i++) { + String fullyQualifiedName1 = fullyQualifiedName; + + if (getIgnoreFilters()[i].match(fullyQualifiedName1)) { + return true; + } + } + } + + return false; + } + + /** + * @return + */ + public boolean isFilterEnabled() { + IPreferenceStore settings = JavaPlugin.getDefault().getPreferenceStore(); + return settings.getBoolean(PREF_USE_FILTERS); + } + + /** + * @param b + */ + public void setFilterEnabled(boolean filterEnabled) { + IPreferenceStore settings = JavaPlugin.getDefault().getPreferenceStore(); + settings.setValue(PREF_USE_FILTERS, filterEnabled); + } + + /** + * Returns the current filters as a string. + * + * @return + */ + public String getFilters() { + IPreferenceStore settings = JavaPlugin.getDefault().getPreferenceStore(); + + return settings.getString(PREF_FILTERS_LIST); + } + + public void setFilters(String filters) { + fFilters = null; + + IPreferenceStore settings = JavaPlugin.getDefault().getPreferenceStore(); + settings.setValue(PREF_FILTERS_LIST, filters); + } + + /** + * Returns filters for packages which should not be included in the search results. + * + * @return StringMatcher[] + */ + private StringMatcher[] getIgnoreFilters() { + if (fFilters == null) { + String filterString = null; + + if (isFilterEnabled()) { + filterString = getFilters(); + + if (filterString == null) { + filterString = DEFAULT_IGNORE_FILTERS; + } + } + + if (filterString != null) { + fFilters = parseList(filterString); + } else { + fFilters = null; + } + } + + return fFilters; + } + + /** + * Parses the comma separated string into an array of StringMatcher objects + * + * @return list + */ + private static StringMatcher[] parseList(String listString) { + List list = new ArrayList(10); + StringTokenizer tokenizer = new StringTokenizer(listString, ","); //$NON-NLS-1$ + + while (tokenizer.hasMoreTokens()) { + String textFilter = tokenizer.nextToken(); + list.add(new StringMatcher(textFilter, false, false)); + } + + return (StringMatcher[]) list.toArray(new StringMatcher[list.size()]); + } +} Index: core extension/org/eclipse/jdt/internal/corext/callhierarchy/CallLocation.java =================================================================== RCS file: core extension/org/eclipse/jdt/internal/corext/callhierarchy/CallLocation.java diff -N core extension/org/eclipse/jdt/internal/corext/callhierarchy/CallLocation.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ core extension/org/eclipse/jdt/internal/corext/callhierarchy/CallLocation.java 16 Apr 2003 07:00:17 -0000 @@ -0,0 +1,100 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * Jesper Kamstrup Linnet (eclipse@kamstrup-linnet.dk) - initial API and implementation + * (report 36180: Callers/Callees view) + ******************************************************************************/ +package org.eclipse.jdt.internal.corext.callhierarchy; + +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.jdt.core.IBuffer; +import org.eclipse.jdt.core.ICompilationUnit; +import org.eclipse.jdt.core.IJavaElement; +import org.eclipse.jdt.core.IMember; +import org.eclipse.jdt.core.JavaModelException; + +/** + * @author jl + */ +public class CallLocation implements IAdaptable { + private IMember fCalledMember; + private IMember fMember; + private String fCallText; + private int fEnd; + private int fStart; + + /** + * @param method + * @param cu + * @param start + * @param end + */ + public CallLocation(IMember member, IMember calledMember, int start, int end) { + this.fMember = member; + this.fCalledMember = calledMember; + this.fStart = start; + this.fEnd = end; + + fCallText = initializeCallText(); + } + + /** + * @return IMethod + */ + public IMember getCalledMember() { + return fCalledMember; + } + + /** + * + */ + public int getEnd() { + return fEnd; + } + + public IMember getMember() { + return fMember; + } + + /** + * + */ + public int getStart() { + return fStart; + } + + public String toString() { + return fCallText; + } + + private String initializeCallText() { + try { + ICompilationUnit compilationUnit = fMember.getCompilationUnit(); + + if ((fMember != null) && (compilationUnit != null)) { + IBuffer buffer = compilationUnit.getBuffer(); + + return buffer.getText(fStart, (fEnd - fStart)); + } else { + return fMember.getOpenable().getBuffer().getText(fStart, (fEnd - fStart)); + } + } catch (JavaModelException e) { + Utility.logError("CallLocation::toString: Error creating text", e); + + return "- error -"; + } + } + + public Object getAdapter(Class adapter) { + if (IJavaElement.class.isAssignableFrom(adapter)) { + return getMember(); + } + + return null; + } +} Index: core extension/org/eclipse/jdt/internal/corext/callhierarchy/CallSearchResultCollector.java =================================================================== RCS file: core extension/org/eclipse/jdt/internal/corext/callhierarchy/CallSearchResultCollector.java diff -N core extension/org/eclipse/jdt/internal/corext/callhierarchy/CallSearchResultCollector.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ core extension/org/eclipse/jdt/internal/corext/callhierarchy/CallSearchResultCollector.java 16 Apr 2003 07:00:18 -0000 @@ -0,0 +1,73 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * Jesper Kamstrup Linnet (eclipse@kamstrup-linnet.dk) - initial API and implementation + * (report 36180: Callers/Callees view) + ******************************************************************************/ +package org.eclipse.jdt.internal.corext.callhierarchy; + +import java.util.HashMap; +import java.util.Map; +import org.eclipse.jdt.core.IJavaElement; +import org.eclipse.jdt.core.IMember; +import org.eclipse.jdt.core.IType; + +/** + * @author jl + */ +class CallSearchResultCollector { + private Map fCalledMembers; + + public CallSearchResultCollector() { + this.fCalledMembers = createCalledMethodsData(); + } + + public Map getCallers() { + return fCalledMembers; + } + + protected void addMember(IMember member, IMember calledMember, int start, int end) { + if ((member != null) && (calledMember != null)) { + if (!isIgnored(calledMember)) { + MethodCall methodCall = (MethodCall) fCalledMembers.get(calledMember.getHandleIdentifier()); + + if (methodCall == null) { + methodCall = new MethodCall(calledMember); + fCalledMembers.put(calledMember.getHandleIdentifier(), methodCall); + } + + methodCall.addCallLocation(new CallLocation(member, calledMember, start, + end)); + } + } + } + + protected Map createCalledMethodsData() { + return new HashMap(); + } + + /** + * Method isIgnored. + * @param enclosingElement + * @return boolean + */ + private boolean isIgnored(IMember enclosingElement) { + String fullyQualifiedName = getTypeOfElement(enclosingElement) + .getFullyQualifiedName(); + + return CallHierarchy.getDefault().isIgnored(fullyQualifiedName); + } + + private IType getTypeOfElement(IMember element) { + if (element.getElementType() == IJavaElement.TYPE) { + return (IType) element; + } + + return element.getDeclaringType(); + } +} Index: core extension/org/eclipse/jdt/internal/corext/callhierarchy/CalleeAnalyzerVisitor.java =================================================================== RCS file: core extension/org/eclipse/jdt/internal/corext/callhierarchy/CalleeAnalyzerVisitor.java diff -N core extension/org/eclipse/jdt/internal/corext/callhierarchy/CalleeAnalyzerVisitor.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ core extension/org/eclipse/jdt/internal/corext/callhierarchy/CalleeAnalyzerVisitor.java 16 Apr 2003 07:00:18 -0000 @@ -0,0 +1,246 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * Jesper Kamstrup Linnet (eclipse@kamstrup-linnet.dk) - initial API and implementation + * (report 36180: Callers/Callees view) + ******************************************************************************/ +package org.eclipse.jdt.internal.corext.callhierarchy; + +import java.util.Collection; +import java.util.Map; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.SubProgressMonitor; +import org.eclipse.jdt.core.IMethod; +import org.eclipse.jdt.core.ISourceRange; +import org.eclipse.jdt.core.IType; +import org.eclipse.jdt.core.JavaModelException; +import org.eclipse.jdt.core.dom.ASTNode; +import org.eclipse.jdt.core.dom.ASTVisitor; +import org.eclipse.jdt.core.dom.ClassInstanceCreation; +import org.eclipse.jdt.core.dom.ConstructorInvocation; +import org.eclipse.jdt.core.dom.IMethodBinding; +import org.eclipse.jdt.core.dom.ITypeBinding; +import org.eclipse.jdt.core.dom.MethodDeclaration; +import org.eclipse.jdt.core.dom.MethodInvocation; +import org.eclipse.jdt.core.dom.SuperConstructorInvocation; +import org.eclipse.jdt.core.dom.SuperMethodInvocation; +import org.eclipse.jdt.core.search.IJavaSearchScope; +import org.eclipse.jdt.internal.corext.dom.Binding2JavaModel; + +/** + * @author jl + */ +class CalleeAnalyzerVisitor extends ASTVisitor { + private CallSearchResultCollector fSearchResults; + private IMethod fMethod; + private IProgressMonitor fProgressMonitor; + private int fMethodEndPosition; + private int fMethodStartPosition; + + CalleeAnalyzerVisitor(IMethod method, IProgressMonitor progressMonitor) { + fSearchResults = new CallSearchResultCollector(); + this.fMethod = method; + this.fProgressMonitor = progressMonitor; + + try { + ISourceRange sourceRange = method.getSourceRange(); + this.fMethodStartPosition = sourceRange.getOffset(); + this.fMethodEndPosition = fMethodStartPosition + sourceRange.getLength(); + } catch (JavaModelException jme) { + Utility.logError("Error getting start and end of method: " + + fMethod.getElementName(), jme); + } + } + + /** + * Method getCallees. + * + * @return CallerElement + */ + public Map getCallees() { + return fSearchResults.getCallers(); + } + + /* (non-Javadoc) + * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.ClassInstanceCreation) + */ + public boolean visit(ClassInstanceCreation node) { + if (!isNodeWithinMethod(node)) { + return false; + } + + addMethodCall(node.resolveConstructorBinding(), node); + + return true; + } + + /** + * Find all constructor invocations (this(...)) from the called method. + * Since we only traverse into the AST on the wanted method declaration, this method + * should not hit on more constructor invocations than those in the wanted method. + * + * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.ConstructorInvocation) + */ + public boolean visit(ConstructorInvocation node) { + if (!isNodeWithinMethod(node)) { + return false; + } + + addMethodCall(node.resolveConstructorBinding(), node); + + return true; + } + + /** + * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.MethodDeclaration) + */ + public boolean visit(MethodDeclaration node) { + return isNodeWithinMethod(node); + } + + /** + * Find all method invocations from the called method. Since we only traverse into + * the AST on the wanted method declaration, this method should not hit on more + * method invocations than those in the wanted method. + * + * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.MethodInvocation) + */ + public boolean visit(MethodInvocation node) { + if (!isNodeWithinMethod(node)) { + return false; + } + + addMethodCall(node.resolveMethodBinding(), node); + + return true; + } + + /** + * Find invocations of the supertype's constructor from the called method + * (=constructor). Since we only traverse into the AST on the wanted method + * declaration, this method should not hit on more method invocations than those in + * the wanted method. + * + * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.SuperConstructorInvocation) + */ + public boolean visit(SuperConstructorInvocation node) { + if (!isNodeWithinMethod(node)) { + return false; + } + + addMethodCall(node.resolveConstructorBinding(), node); + + return true; + } + + /** + * Find all method invocations from the called method. Since we only traverse into + * the AST on the wanted method declaration, this method should not hit on more + * method invocations than those in the wanted method. + * + * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.MethodInvocation) + */ + public boolean visit(SuperMethodInvocation node) { + if (!isNodeWithinMethod(node)) { + return false; + } + + addMethodCall(node.resolveMethodBinding(), node); + + return true; + } + + /** + * Adds the specified method binding to the search results. + * + * @param calledMethodBinding + * @param node + */ + protected void addMethodCall(IMethodBinding calledMethodBinding, ASTNode node) { + try { + if (calledMethodBinding != null) { + fProgressMonitor.worked(1); + + ITypeBinding calledTypeBinding = calledMethodBinding.getDeclaringClass(); + IType calledType = null; + + if (!calledTypeBinding.isAnonymous()) { + calledType = Binding2JavaModel.find(calledTypeBinding, + fMethod.getJavaProject()); + } else { + calledType = Binding2JavaModel.find(calledTypeBinding.getInterfaces()[0], + fMethod.getJavaProject()); + } + + IMethod calledMethod = Binding2JavaModel.findIncludingSupertypes(calledMethodBinding, + calledType, + new SubProgressMonitor(fProgressMonitor, 100, + SubProgressMonitor.SUPPRESS_SUBTASK_LABEL)); + + if ((calledMethod != null) && calledType.isInterface()) { + calledMethod = findImplementingMethods(calledMethod); + } + + if (!isIgnoredBySearchScope(calledMethod)) { + fSearchResults.addMember(fMethod, calledMethod, + node.getStartPosition(), + node.getStartPosition() + node.getLength()); + } + } + } catch (JavaModelException jme) { + Utility.logError("Error adding callee search result", jme); + } + } + + /** + * @param enclosingElement + * + * @return + */ + private boolean isIgnoredBySearchScope(IMethod enclosingElement) { + if (enclosingElement != null) { + return !getSearchScope().encloses(enclosingElement); + } else { + return false; + } + } + + private IJavaSearchScope getSearchScope() { + return CallHierarchy.getDefault().getSearchScope(); + } + + private boolean isNodeWithinMethod(ASTNode node) { + int nodeStartPosition = node.getStartPosition(); + int nodeEndPosition = nodeStartPosition + node.getLength(); + + if (nodeStartPosition < fMethodStartPosition) { + return false; + } + + if (nodeEndPosition > fMethodEndPosition) { + return false; + } + + return true; + } + + /** + * @param calledMethod + */ + private IMethod findImplementingMethods(IMethod calledMethod) { + Collection implementingMethods = CallHierarchy.getDefault() + .getImplementingMethods(calledMethod); + + if ((implementingMethods.size() == 0) || (implementingMethods.size() > 1)) { + return calledMethod; + } else { + return (IMethod) implementingMethods.iterator().next(); + } + } +} Index: core extension/org/eclipse/jdt/internal/corext/callhierarchy/CalleeMethodWrapper.java =================================================================== RCS file: core extension/org/eclipse/jdt/internal/corext/callhierarchy/CalleeMethodWrapper.java diff -N core extension/org/eclipse/jdt/internal/corext/callhierarchy/CalleeMethodWrapper.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ core extension/org/eclipse/jdt/internal/corext/callhierarchy/CalleeMethodWrapper.java 16 Apr 2003 07:00:19 -0000 @@ -0,0 +1,108 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * Jesper Kamstrup Linnet (eclipse@kamstrup-linnet.dk) - initial API and implementation + * (report 36180: Callers/Callees view) + ******************************************************************************/ +package org.eclipse.jdt.internal.corext.callhierarchy; + +import java.util.Arrays; +import java.util.Comparator; +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.jdt.core.ICompilationUnit; +import org.eclipse.jdt.core.IJavaElement; +import org.eclipse.jdt.core.IMethod; +import org.eclipse.jdt.core.dom.AST; +import org.eclipse.jdt.core.dom.CompilationUnit; + +/** + * @author jl + */ +class CalleeMethodWrapper extends MethodWrapper { + private Comparator fMethodWrapperComparator = new MethodWrapperComparator(); + + private class MethodWrapperComparator implements Comparator { + /* (non-Javadoc) + * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object) + */ + public int compare(Object o1, Object o2) { + MethodWrapper m1 = (MethodWrapper) o1; + MethodWrapper m2 = (MethodWrapper) o2; + + CallLocation callLocation1 = m1.getMethodCall().getFirstCallLocation(); + CallLocation callLocation2 = m2.getMethodCall().getFirstCallLocation(); + + if ((callLocation1 != null) && (callLocation2 != null)) { + if (callLocation1.getStart() == callLocation2.getStart()) { + return callLocation1.getEnd() - callLocation2.getEnd(); + } + + return callLocation1.getStart() - callLocation2.getStart(); + } + + return 0; + } + } + + /** + * Constructor for CalleeMethodWrapper. + * @param parent + * @param method + */ + public CalleeMethodWrapper(MethodWrapper parent, MethodCall methodCall) { + super(parent, methodCall); + } + + /* Returns the calls sorted after the call location + * @see dk.kamstruplinnet.callers.search.MethodWrapper#getCalls() + */ + public MethodWrapper[] getCalls() { + MethodWrapper[] result = super.getCalls(); + Arrays.sort(result, fMethodWrapperComparator); + + return result; + } + + /* (non-Javadoc) + * @see dk.kamstruplinnet.callers.search.MethodWrapper#getTaskName() + */ + protected String getTaskName() { + return null; + } + + /** + * @see dk.kamstruplinnet.callers.CallerMethodWrapper#createMethodWrapper(org.eclipse.jdt.core.IMethod) + */ + protected MethodWrapper createMethodWrapper(MethodCall methodCall) { + return new CalleeMethodWrapper(this, methodCall); + } + + /** + * Find callees called from the current method. + * @see dk.kamstruplinnet.callers.MethodWrapper#findChildren() + */ + protected Map findChildren(IProgressMonitor progressMonitor) { + if (getMember().getElementType() == IJavaElement.METHOD) { + CalleeAnalyzerVisitor visitor = new CalleeAnalyzerVisitor((IMethod) getMember(), + progressMonitor); + ICompilationUnit icu = getMember().getCompilationUnit(); + + if (icu != null) { + CompilationUnit cu = AST.parseCompilationUnit(icu, true); + cu.accept(visitor); + } + + return visitor.getCallees(); + } else { + return new HashMap(); + } + } +} Index: core extension/org/eclipse/jdt/internal/corext/callhierarchy/CallerMethodWrapper.java =================================================================== RCS file: core extension/org/eclipse/jdt/internal/corext/callhierarchy/CallerMethodWrapper.java diff -N core extension/org/eclipse/jdt/internal/corext/callhierarchy/CallerMethodWrapper.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ core extension/org/eclipse/jdt/internal/corext/callhierarchy/CallerMethodWrapper.java 16 Apr 2003 07:00:19 -0000 @@ -0,0 +1,93 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * Jesper Kamstrup Linnet (eclipse@kamstrup-linnet.dk) - initial API and implementation + * (report 36180: Callers/Callees view) + ******************************************************************************/ +package org.eclipse.jdt.internal.corext.callhierarchy; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.SubProgressMonitor; +import org.eclipse.jdt.core.IJavaElement; +import org.eclipse.jdt.core.IMember; +import org.eclipse.jdt.core.IMethod; +import org.eclipse.jdt.core.JavaModelException; +import org.eclipse.jdt.core.search.IJavaSearchConstants; +import org.eclipse.jdt.core.search.IJavaSearchScope; +import org.eclipse.jdt.core.search.SearchEngine; + +/** + * @author jl + */ +class CallerMethodWrapper extends MethodWrapper { + public CallerMethodWrapper(MethodWrapper parent, MethodCall methodCall) { + super(parent, methodCall); + } + + protected IJavaSearchScope getSearchScope() { + return CallHierarchy.getDefault().getSearchScope(); + } + + protected String getTaskName() { + return "Finding callers..."; + } + + /** + * @see dk.kamstruplinnet.callers.CallerMethodWrapper#createMethodWrapper(org.eclipse.jdt.core.IMethod) + */ + protected MethodWrapper createMethodWrapper(MethodCall methodCall) { + return new CallerMethodWrapper(this, methodCall); + } + + /** + * @see dk.kamstruplinnet.callers.MethodWrapper#findChildren() + * @return The result of the search for children + */ + protected Map findChildren(IProgressMonitor progressMonitor) { + try { + MethodReferencesSearchCollector searchCollector = new MethodReferencesSearchCollector(); + SearchEngine searchEngine = new SearchEngine(); + + for (Iterator iter = getMembers().iterator(); + iter.hasNext() && !progressMonitor.isCanceled();) { + IMember member = (IMember) iter.next(); + searchCollector.setProgressMonitor(new SubProgressMonitor( + progressMonitor, 10, SubProgressMonitor.SUPPRESS_SUBTASK_LABEL)); + searchEngine.search(ResourcesPlugin.getWorkspace(), member, + IJavaSearchConstants.REFERENCES, getSearchScope(), searchCollector); + } + + return searchCollector.getCallers(); + } catch (JavaModelException e) { + Utility.logError("Error finding callers", e); + + return new HashMap(0); + } + } + + /** + * Returns a collection of IMember instances representing what to search for + */ + private Collection getMembers() { + Collection result = new ArrayList(); + + result.add(getMember()); + if (getMember().getElementType() == IJavaElement.METHOD) { + result.addAll(CallHierarchy.getDefault().getInterfaceMethods((IMethod) getMember())); + } + + return result; + } +} Index: core extension/org/eclipse/jdt/internal/corext/callhierarchy/MethodCall.java =================================================================== RCS file: core extension/org/eclipse/jdt/internal/corext/callhierarchy/MethodCall.java diff -N core extension/org/eclipse/jdt/internal/corext/callhierarchy/MethodCall.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ core extension/org/eclipse/jdt/internal/corext/callhierarchy/MethodCall.java 16 Apr 2003 07:00:19 -0000 @@ -0,0 +1,73 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * Jesper Kamstrup Linnet (eclipse@kamstrup-linnet.dk) - initial API and implementation + * (report 36180: Callers/Callees view) + ******************************************************************************/ +package org.eclipse.jdt.internal.corext.callhierarchy; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import org.eclipse.jdt.core.IMember; + +/** + * @author jl + */ +public class MethodCall { + private IMember fMember; + private List fCallLocations; + + /** + * @param enclosingElement + */ + public MethodCall(IMember enclosingElement) { + this.fMember = enclosingElement; + } + + /** + * + */ + public Collection getCallLocations() { + return fCallLocations; + } + + public CallLocation getFirstCallLocation() { + if ((fCallLocations != null) && !fCallLocations.isEmpty()) { + return (CallLocation) fCallLocations.get(0); + } else { + return null; + } + } + + /** + * @return Object + */ + public Object getKey() { + return getMember().getHandleIdentifier(); + } + + /** + * + */ + public IMember getMember() { + return fMember; + } + + /** + * @param location + */ + public void addCallLocation(CallLocation location) { + if (fCallLocations == null) { + fCallLocations = new ArrayList(); + } + + fCallLocations.add(location); + } +} Index: core extension/org/eclipse/jdt/internal/corext/callhierarchy/MethodReferencesSearchCollector.java =================================================================== RCS file: core extension/org/eclipse/jdt/internal/corext/callhierarchy/MethodReferencesSearchCollector.java diff -N core extension/org/eclipse/jdt/internal/corext/callhierarchy/MethodReferencesSearchCollector.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ core extension/org/eclipse/jdt/internal/corext/callhierarchy/MethodReferencesSearchCollector.java 16 Apr 2003 07:00:19 -0000 @@ -0,0 +1,84 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * Jesper Kamstrup Linnet (eclipse@kamstrup-linnet.dk) - initial API and implementation + * (report 36180: Callers/Callees view) + ******************************************************************************/ +package org.eclipse.jdt.internal.corext.callhierarchy; + +import java.util.Map; + +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.SubProgressMonitor; +import org.eclipse.jdt.core.IJavaElement; +import org.eclipse.jdt.core.IMember; +import org.eclipse.jdt.core.search.IJavaSearchResultCollector; + +/** + * @author jl + */ +class MethodReferencesSearchCollector implements IJavaSearchResultCollector { + private CallSearchResultCollector fSearchResults; + private IProgressMonitor fProgressMonitor; + private boolean fRequireExactMatch = true; + + MethodReferencesSearchCollector() { + fSearchResults = new CallSearchResultCollector(); + } + + public Map getCallers() { + return fSearchResults.getCallers(); + } + + /** + * @see org.eclipse.jdt.core.search.IJavaSearchResultCollector#getProgressMonitor() + */ + public IProgressMonitor getProgressMonitor() { + return fProgressMonitor; + } + + /** + * @see org.eclipse.jdt.core.search.IJavaSearchResultCollector#aboutToStart() + */ + public void aboutToStart() {} + + /** + * @see org.eclipse.jdt.core.search.IJavaSearchResultCollector#accept(org.eclipse.core.resources.IResource, int, int, org.eclipse.jdt.core.IJavaElement, int) + */ + public void accept(IResource resource, int start, int end, + IJavaElement enclosingElement, int accuracy) throws CoreException { + if (fRequireExactMatch && (accuracy != IJavaSearchResultCollector.EXACT_MATCH)) { + return; + } + + if (enclosingElement != null && enclosingElement instanceof IMember) { + IMember member= (IMember) enclosingElement; + switch (enclosingElement.getElementType()) { + case IJavaElement.METHOD: + case IJavaElement.TYPE: + case IJavaElement.FIELD: + fSearchResults.addMember(member, member, start, end); + break; + } + } + } + + /** + * @see org.eclipse.jdt.core.search.IJavaSearchResultCollector#done() + */ + public void done() {} + + /** + * @param monitor + */ + void setProgressMonitor(SubProgressMonitor monitor) { + this.fProgressMonitor = monitor; + } +} Index: core extension/org/eclipse/jdt/internal/corext/callhierarchy/MethodWrapper.java =================================================================== RCS file: core extension/org/eclipse/jdt/internal/corext/callhierarchy/MethodWrapper.java diff -N core extension/org/eclipse/jdt/internal/corext/callhierarchy/MethodWrapper.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ core extension/org/eclipse/jdt/internal/corext/callhierarchy/MethodWrapper.java 16 Apr 2003 07:00:20 -0000 @@ -0,0 +1,331 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * Jesper Kamstrup Linnet (eclipse@kamstrup-linnet.dk) - initial API and implementation + * (report 36180: Callers/Callees view) + ******************************************************************************/ +package org.eclipse.jdt.internal.corext.callhierarchy; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.jdt.core.IJavaElement; +import org.eclipse.jdt.core.IMember; +import org.eclipse.jdt.core.IMethod; + +/** + * This class represents the general parts of a method call (either to or from a + * method). + * + * @author jl + */ +public abstract class MethodWrapper implements IAdaptable { + private Map fElements = null; + + /* + * A cache of previously found methods. This cache should be searched + * before adding a "new" method object reference to the list of elements. + * This way previously found methods won't be searched again. + */ + private Map fMethodCache; + private MethodCall fMethodCall; + private MethodWrapper fParent; + private int fLevel; + + /** + * Constructor CallerElement. + */ + public MethodWrapper(MethodWrapper parent, MethodCall methodCall) { + super(); + + if (methodCall == null) { + throw new IllegalArgumentException("Parameter method cannot be null"); + } + + if (parent == null) { + setMethodCache(new HashMap()); + fLevel = 1; + } else { + setMethodCache(parent.getMethodCache()); + fLevel = parent.getLevel() + 1; + } + + this.fMethodCall = methodCall; + this.fParent = parent; + } + + public Object getAdapter(Class adapter) { + if (adapter == IMethod.class) { + if (getMember().getElementType() == IJavaElement.METHOD) { + return getMember(); + } else { + return null; + } + } else { + if (IJavaElement.class.isAssignableFrom(adapter)) { + return getMember(); + } + } + + return null; + } + + /** + * Method getCallerElements. + * @return The child caller elements of this element + */ + public MethodWrapper[] getCalls() { + if (fElements == null) { + doFindChildren(); + } + + MethodWrapper[] result = new MethodWrapper[fElements.size()]; + int i = 0; + + for (Iterator iter = fElements.keySet().iterator(); iter.hasNext();) { + MethodCall methodCall = getMethodCallFromMap(fElements, iter.next()); + result[i++] = createMethodWrapper(methodCall); + } + + return result; + } + + /** + * @return int + */ + public int getLevel() { + return fLevel; + } + + /** + * Method getMethod. + * @return Object + */ + public IMember getMember() { + return getMethodCall().getMember(); + } + + /** + * @return MethodCall + */ + public MethodCall getMethodCall() { + return fMethodCall; + } + + /** + * Method getName. + */ + public String getName() { + if (getMethodCall() != null) { + return getMethodCall().getMember().getElementName(); + } else { + return ""; + } + } + + /** + * Method getParent. + * @return + */ + public MethodWrapper getParent() { + return fParent; + } + + public boolean equals(Object oth) { + if (this == oth) { + return true; + } + + if (oth == null) { + return false; + } + + if (oth.getClass() != getClass()) { + return false; + } + + MethodWrapper other = (MethodWrapper) oth; + + if (this.fParent == null) { + if (other.fParent != null) { + return false; + } + } else { + if (!this.fParent.equals(other.fParent)) { + return false; + } + } + + if (this.getMethodCall() == null) { + if (other.getMethodCall() != null) { + return false; + } + } else { + if (!this.getMethodCall().equals(other.getMethodCall())) { + return false; + } + } + + return true; + } + + public int hashCode() { + final int PRIME = 1000003; + int result = 0; + + if (fParent != null) { + result = (PRIME * result) + fParent.hashCode(); + } + + if (getMethodCall() != null) { + result = (PRIME * result) + getMethodCall().getMember().hashCode(); + } + + return result; + } + + /** + * @see java.lang.Object#toString() + */ + public String toString() { + String result; + + result = "CallerElement[name=" + getName() + ", children="; + + if (fElements == null) { + result += "unknown]"; + } else { + result += (fElements.size() + "]"); + } + + return result; + } + + private void setMethodCache(Map methodCache) { + fMethodCache = methodCache; + } + + protected abstract String getTaskName(); + + private void addCallToCache(MethodCall methodCall) { + Map cachedCalls = lookupMethod(this.getMethodCall()); + cachedCalls.put(methodCall.getKey(), methodCall); + } + + /** + * Method createMethodWrapper. + * @param method + * @return MethodWrapper + */ + protected abstract MethodWrapper createMethodWrapper(MethodCall methodCall); + + private void doFindChildren() { + Map existingResults = lookupMethod(getMethodCall()); + + if (existingResults != null) { + fElements = new HashMap(); + fElements.putAll(existingResults); + } else { + initCalls(); + + try { + IProgressMonitor progressMonitor = getProgressMonitor(); + + if (progressMonitor != null) { + progressMonitor.beginTask(getTaskName(), IProgressMonitor.UNKNOWN); + } + + try { + performSearch(progressMonitor); + } finally { + if (progressMonitor != null) { + progressMonitor.done(); + } + } + + // ModalContext.run(getRunnableWithProgress(), true, getProgressMonitor(), + // Display.getCurrent()); + } catch (Exception e) { + Utility.logError("Error searching in modal context", e); + } + } + } + + /** + * Determines if the method represents a recursion call (i.e. whether the + * method call is already in the cache.) + * + * @return True if the call is part of a recursion + */ + public boolean isRecursive() { + MethodWrapper current = getParent(); + + while (current != null) { + if (getMember().getHandleIdentifier().equals(current.getMember() + .getHandleIdentifier())) { + return true; + } + + current = current.getParent(); + } + + return false; + } + + /** + * This method finds the children of the current IMethod (either callers or + * callees, depending on the concrete subclass. + * @return The result of the search for children + */ + protected abstract Map findChildren(IProgressMonitor progressMonitor); + + private Map getMethodCache() { + return fMethodCache; + } + + private void initCalls() { + this.fElements = new HashMap(); + + initCacheForMethod(); + } + + /** + * Looks up a previously created search result in the "global" cache. + * @param method + * @return List List of previously found search results + */ + private Map lookupMethod(MethodCall methodCall) { + return (Map) getMethodCache().get(methodCall.getKey()); + } + + private void performSearch(IProgressMonitor progressMonitor) { + fElements = findChildren(progressMonitor); + + for (Iterator iter = fElements.keySet().iterator(); iter.hasNext();) { + MethodCall methodCall = getMethodCallFromMap(fElements, iter.next()); + addCallToCache(methodCall); + } + } + + private MethodCall getMethodCallFromMap(Map elements, Object key) { + return (MethodCall) elements.get(key); + } + + private IProgressMonitor getProgressMonitor() { + // TODO: Figure out what to do with progress monitors + return new NullProgressMonitor(); + } + + private void initCacheForMethod() { + Map cachedCalls = new HashMap(); + getMethodCache().put(this.getMethodCall().getKey(), cachedCalls); + } +} Index: ui/org/eclipse/jdt/internal/ui/callhierarchy/AbstractGotoActionDelegate.java =================================================================== RCS file: ui/org/eclipse/jdt/internal/ui/callhierarchy/AbstractGotoActionDelegate.java diff -N ui/org/eclipse/jdt/internal/ui/callhierarchy/AbstractGotoActionDelegate.java --- ui/org/eclipse/jdt/internal/ui/callhierarchy/AbstractGotoActionDelegate.java 15 Apr 2003 09:19:18 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,154 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2003 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * Jesper Kamstrup Linnet (eclipse@kamstrup-linnet.dk) - initial API and implementation - * (report 36180: Callers/Callees view) - ******************************************************************************/ -package org.eclipse.jdt.internal.ui.callhierarchy; - -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.NullProgressMonitor; - -import org.eclipse.swt.widgets.Shell; - -import org.eclipse.jface.action.IAction; -import org.eclipse.jface.action.IStatusLineManager; -import org.eclipse.jface.viewers.ISelection; - -import org.eclipse.ui.IEditorActionDelegate; -import org.eclipse.ui.IEditorPart; -import org.eclipse.ui.PartInitException; - -import org.eclipse.jdt.core.IJavaElement; -import org.eclipse.jdt.core.JavaModelException; - -import org.eclipse.jdt.internal.ui.JavaPlugin; -import org.eclipse.jdt.internal.ui.actions.OpenActionUtil; -import org.eclipse.jdt.internal.ui.actions.SelectionConverter; -import org.eclipse.jdt.internal.ui.javaeditor.JavaEditor; - -/** - * @see IEditorActionDelegate - */ -public abstract class AbstractGotoActionDelegate implements IEditorActionDelegate { - private IEditorPart fEditor; - - public AbstractGotoActionDelegate() {} - - /** - * @see IEditorActionDelegate#setActiveEditor - */ - public void setActiveEditor(IAction action, IEditorPart targetEditor) { - this.fEditor = targetEditor; - } - - /** - * @see IEditorActionDelegate#run - */ - public void run(IAction action) { - clearErrorMessage(); - - if (fEditor instanceof JavaEditor) { - try { - IJavaElement element = SelectionConverter.codeResolve((JavaEditor) fEditor, - getShell(), "Title - TODO", "Message - TODO"); - - if (element != null) { - IJavaElement[] members = internalSearchForMembers(element, - getProgressMonitor()); - - if (members != null) { - if (members.length == 0) { - IJavaElement foundElement = OpenActionUtil.selectJavaElement(members, - getShell(), getSelectMethodTitle(), - getSelectMethodMessage()); - - if (foundElement != null) { - OpenActionUtil.open(foundElement, true); - } - } else { - showInfoMessage(getNoResultsMessage()); - } - } - } - } catch (JavaModelException e) { - Utility.logError("Error finding/jumping to method", e); - } catch (PartInitException e) { - Utility.logError("Error finding/jumping to method", e); - } - } - } - - private Shell getShell() { - return JavaPlugin.getActiveWorkbenchWindow().getShell(); - } - - /** - * @see IEditorActionDelegate#selectionChanged - */ - public void selectionChanged(IAction action, ISelection selection) {} - - protected abstract String getEmptySelectionMessage(); - - protected abstract String getNoResultsMessage(); - - protected abstract String getSelectMethodMessage(); - - protected abstract String getSelectMethodTitle(); - - protected abstract String getTaskName(); - - protected IJavaElement[] internalSearchForMembers(IJavaElement element, - IProgressMonitor progressMonitor) { - if (progressMonitor == null) { - progressMonitor = new NullProgressMonitor(); - } - - progressMonitor.beginTask(getTaskName(), IProgressMonitor.UNKNOWN); - - IJavaElement[] result = null; - - try { - result = searchForMembers(element, progressMonitor); - } finally { - progressMonitor.done(); - } - - return result; - } - - protected abstract IJavaElement[] searchForMembers(IJavaElement element, - IProgressMonitor progressMonitor); - - private IProgressMonitor getProgressMonitor() { - return new NullProgressMonitor(); - - // return getStatusLineManager().getProgressMonitor(); - } - - private IStatusLineManager getStatusLineManager() { - IStatusLineManager statusLineManager = fEditor.getEditorSite().getActionBars() - .getStatusLineManager(); - statusLineManager.setCancelEnabled(true); - - return statusLineManager; - } - - private void clearErrorMessage() { - showErrorMessage(null); - } - - private void showErrorMessage(String msg) { - getStatusLineManager().setErrorMessage(msg); - } - - private void showInfoMessage(String msg) { - getStatusLineManager().setMessage(msg); - clearErrorMessage(); - } -} Index: ui/org/eclipse/jdt/internal/ui/callhierarchy/CallHierarchy.java =================================================================== RCS file: ui/org/eclipse/jdt/internal/ui/callhierarchy/CallHierarchy.java diff -N ui/org/eclipse/jdt/internal/ui/callhierarchy/CallHierarchy.java --- ui/org/eclipse/jdt/internal/ui/callhierarchy/CallHierarchy.java 15 Apr 2003 09:19:18 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,346 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2003 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * Jesper Kamstrup Linnet (eclipse@kamstrup-linnet.dk) - initial API and implementation - * (report 36180: Callers/Callees view) - ******************************************************************************/ -package org.eclipse.jdt.internal.ui.callhierarchy; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.List; -import java.util.StringTokenizer; - -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.NullProgressMonitor; -import org.eclipse.core.runtime.Status; - -import org.eclipse.swt.widgets.Shell; - -import org.eclipse.jface.action.IStatusLineManager; -import org.eclipse.jface.dialogs.ErrorDialog; -import org.eclipse.jface.dialogs.MessageDialog; -import org.eclipse.jface.preference.IPreferenceStore; -import org.eclipse.jface.util.IPropertyChangeListener; -import org.eclipse.jface.util.OpenStrategy; -import org.eclipse.jface.util.PropertyChangeEvent; - -import org.eclipse.ui.IEditorPart; -import org.eclipse.ui.PartInitException; -import org.eclipse.ui.PlatformUI; -import org.eclipse.ui.texteditor.ITextEditor; - -import org.eclipse.jdt.core.IJavaElement; -import org.eclipse.jdt.core.IMethod; -import org.eclipse.jdt.core.JavaModelException; -import org.eclipse.jdt.core.search.IJavaSearchScope; -import org.eclipse.jdt.core.search.SearchEngine; - -import org.eclipse.jdt.ui.JavaUI; - -import org.eclipse.jdt.internal.ui.IJavaStatusConstants; -import org.eclipse.jdt.internal.ui.JavaPlugin; -import org.eclipse.jdt.internal.ui.javaeditor.EditorUtility; - -import org.eclipse.jdt.internal.corext.callhierarchy.Implementors; - -public class CallHierarchy implements IPropertyChangeListener { - private static CallHierarchy fInstance; - private IJavaSearchScope fSearchScope; - private int fMaxCallDepth = -1; - - private CallHierarchy() { - JavaPlugin.getDefault().getPreferenceStore().addPropertyChangeListener(this); - } - - public static CallHierarchy getDefault() { - if (fInstance == null) { - fInstance = new CallHierarchy(); - } - - return fInstance; - } - - /** - * Parses the comma separated string into an array of strings - * - * @return list - */ - public static String[] parseList(String listString) { - List list = new ArrayList(10); - StringTokenizer tokenizer = new StringTokenizer(listString, ","); //$NON-NLS-1$ - - while (tokenizer.hasMoreTokens()) { - String token = tokenizer.nextToken(); - list.add(token); - } - - return (String[]) list.toArray(new String[list.size()]); - } - - /** - * Returns filters for packages which should not be included in the search - * results. - * @return String[] - */ - public String[] getIgnoreFilters() { - IPreferenceStore settings = JavaPlugin.getDefault().getPreferenceStore(); - - if (settings.getBoolean(ICallHierarchyPreferencesConstants.PREF_USE_FILTERS)) { - String[] strings = CallHierarchy.parseList(settings.getString( - ICallHierarchyPreferencesConstants.PREF_ACTIVE_FILTERS_LIST)); - - return strings; - } else { - return null; - } - } - - /** - * Returns the maximum tree level allowed - * @return int - */ - public int getMaxCallDepth() { - if (fMaxCallDepth == -1) { - IPreferenceStore settings = JavaPlugin.getDefault().getPreferenceStore(); - - fMaxCallDepth = settings.getInt(ICallHierarchyPreferencesConstants.PREF_MAX_CALL_DEPTH); - } - - return fMaxCallDepth; - } - - /** - * @return - */ - public IProgressMonitor getProgressMonitor() { - // IProgressMonitor progressMonitor = getStatusLineManager().getProgressMonitor(); - return new NullProgressMonitor(); - } - - /** - * @return - */ - public boolean isSearchForCalleesUsingImplementorsEnabled() { - IPreferenceStore settings = JavaPlugin.getDefault().getPreferenceStore(); - - return settings.getBoolean(ICallHierarchyPreferencesConstants.PREF_USE_IMPLEMENTORS_FOR_CALLEE_SEARCH); - } - - /** - * @return - */ - public boolean isSearchForCallersUsingImplementorsEnabled() { - IPreferenceStore settings = JavaPlugin.getDefault().getPreferenceStore(); - - return settings.getBoolean(ICallHierarchyPreferencesConstants.PREF_USE_IMPLEMENTORS_FOR_CALLER_SEARCH); - } - - public void setSearchScope(IJavaSearchScope searchScope) { - this.fSearchScope = searchScope; - } - - public IJavaSearchScope getSearchScope() { - if (fSearchScope != null) { - return fSearchScope; - } - - Utility.logDebug("No search scope was set"); - - return SearchEngine.createWorkspaceScope(); - } - - public void initializeDefaultBasePreferences(IPreferenceStore store) { - store.setDefault(ICallHierarchyPreferencesConstants.PREF_MAX_CALL_DEPTH, 10); - store.setDefault(ICallHierarchyPreferencesConstants.PREF_USE_IMPLEMENTORS_FOR_CALLER_SEARCH, - false); - store.setDefault(ICallHierarchyPreferencesConstants.PREF_USE_IMPLEMENTORS_FOR_CALLEE_SEARCH, - false); - } - - public void initializeDefaultFilterPreferences(IPreferenceStore store) { - store.setDefault(ICallHierarchyPreferencesConstants.PREF_ACTIVE_FILTERS_LIST, - "javax.*,java.*"); - store.setDefault(ICallHierarchyPreferencesConstants.PREF_INACTIVE_FILTERS_LIST, - "com.ibm.*,com.sun.*,org.omg.*,sun.*,sunw.*"); //$NON-NLS-1$ - store.setDefault(ICallHierarchyPreferencesConstants.PREF_USE_FILTERS, true); - } - - public void initializeDefaultPreferences(IPreferenceStore store) { - initializeDefaultBasePreferences(store); - initializeDefaultFilterPreferences(store); - } - - /** - * @see org.eclipse.jface.util.IPropertyChangeListener#propertyChange(PropertyChangeEvent) - */ - public void propertyChange(PropertyChangeEvent event) { - if (event.getProperty().equals(ICallHierarchyPreferencesConstants.PREF_MAX_CALL_DEPTH)) { - fMaxCallDepth = ((Integer) event.getNewValue()).intValue(); - } - } - - /** - * This method removes this class as a property change listener on the plugin's preference - * store. - * - * TODO: Does this class ever receive shutdown messages? - */ - public void shutdown() { - JavaPlugin.getDefault().getPreferenceStore().removePropertyChangeListener(this); - } - - private IStatusLineManager getStatusLineManager() { - IStatusLineManager statusLineManager = PlatformUI.getWorkbench() - .getActiveWorkbenchWindow() - .getActivePage() - .findView(CallHierarchyViewPart.CALLERS_VIEW_ID) - .getViewSite().getActionBars() - .getStatusLineManager(); - statusLineManager.setCancelEnabled(true); - - return statusLineManager; - } - - /** - * @param method - * @return - */ - public Collection getInterfaceMethods(IMethod method) { - if (isSearchForCallersUsingImplementorsEnabled()) { - IJavaElement[] result = Implementors.getInstance().searchForInterfaces(new IJavaElement[] { - method - }, new NullProgressMonitor()); - - if ((result != null) && (result.length > 0)) { - return Arrays.asList(result); - } - } - - return new ArrayList(0); - } - - /** - * @param method - * @return - */ - public Collection getImplementingMethods(IMethod method) { - if (isSearchForCalleesUsingImplementorsEnabled()) { - IJavaElement[] result = Implementors.getInstance().searchForImplementors(new IJavaElement[] { - method - }, new NullProgressMonitor()); - - if ((result != null) && (result.length > 0)) { - return Arrays.asList(result); - } - } - - return new ArrayList(0); - } - - public MethodWrapper getCallerRoot(IMethod method) { - return new CallerMethodWrapper(null, new MethodCall(method)); - } - - public MethodWrapper getCalleeRoot(IMethod method) { - return new CalleeMethodWrapper(null, new MethodCall(method)); - } - - public static void jumpToMember(IJavaElement element) { - if (element != null) { - try { - IEditorPart methodEditor = EditorUtility.openInEditor(element, true); - JavaUI.revealInEditor(methodEditor, (IJavaElement) element); - } catch (JavaModelException e) { - Utility.logError("Error getting underlying resource", e); - } catch (PartInitException e) { - Utility.logError("Error opening editor", e); - } - } - } - - static CallLocation getCallLocation(Object element) { - CallLocation callLocation = null; - - if (element instanceof MethodWrapper) { - MethodWrapper methodWrapper = (MethodWrapper) element; - MethodCall methodCall = methodWrapper.getMethodCall(); - - if (methodCall != null) { - callLocation = methodCall.getFirstCallLocation(); - } - } else if (element instanceof CallLocation) { - callLocation = (CallLocation) element; - } - - return callLocation; - } - - public static void openInEditor(Object element, Shell shell, String title) { - CallLocation callLocation= null; - if (element instanceof CallLocation) { - callLocation= (CallLocation) element; - } else if (element instanceof CallLocation) { - callLocation= getCallLocation(element); - } - - if (callLocation == null) { - return; - } - - try { - boolean activateOnOpen = OpenStrategy.activateOnOpen(); - - IEditorPart methodEditor = EditorUtility.openInEditor(callLocation.getMember(), - activateOnOpen); - - if (methodEditor instanceof ITextEditor) { - ITextEditor editor = (ITextEditor) methodEditor; - editor.selectAndReveal(callLocation.getStart(), - (callLocation.getEnd() - callLocation.getStart())); - } - } catch (JavaModelException e) { - JavaPlugin.log(new Status(IStatus.ERROR, JavaPlugin.getPluginId(), - IJavaStatusConstants.INTERNAL_ERROR, - CallHierarchyMessages.getString( - "CallHierarchy.open_in_editor.error.message"), e)); //$NON-NLS-1$ - - ErrorDialog.openError(shell, title, - CallHierarchyMessages.getString( - "CallHierarchy.open_in_editor.error.messageProblems"), //$NON-NLS-1$ - e.getStatus()); - } catch (PartInitException x) { - String name = callLocation.getCalledMember().getElementName(); - MessageDialog.openError(shell, - CallHierarchyMessages.getString( - "CallHierarchy.open_in_editor.error.messageProblems"), //$NON-NLS-1$ - CallHierarchyMessages.getFormattedString( - "CallHierarchy.open_in_editor.error.messageArgs", //$NON-NLS-1$ - new String[] { name, x.getMessage() })); - } - } - - /** - * @param elem - * @return - */ - public static IEditorPart isOpenInEditor(Object elem) { - IJavaElement javaElement= null; - if (elem instanceof MethodWrapper) { - javaElement= ((MethodWrapper) elem).getMember(); - } else if (elem instanceof CallLocation) { - javaElement= ((CallLocation) elem).getCalledMember(); - } - if (javaElement != null) { - return EditorUtility.isOpenInEditor(javaElement); - } - return null; - } -} Index: ui/org/eclipse/jdt/internal/ui/callhierarchy/CallHierarchyContentProvider.java =================================================================== RCS file: /home/eclipse/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/callhierarchy/CallHierarchyContentProvider.java,v retrieving revision 1.1 diff -u -r1.1 CallHierarchyContentProvider.java --- ui/org/eclipse/jdt/internal/ui/callhierarchy/CallHierarchyContentProvider.java 15 Apr 2003 09:19:18 -0000 1.1 +++ ui/org/eclipse/jdt/internal/ui/callhierarchy/CallHierarchyContentProvider.java 16 Apr 2003 07:00:25 -0000 @@ -11,12 +11,12 @@ ******************************************************************************/ package org.eclipse.jdt.internal.ui.callhierarchy; +import org.eclipse.jdt.core.IJavaElement; +import org.eclipse.jdt.internal.corext.callhierarchy.MethodWrapper; import org.eclipse.jface.viewers.ITreeContentProvider; import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.jface.viewers.Viewer; -import org.eclipse.jdt.core.IJavaElement; - class CallHierarchyContentProvider implements ITreeContentProvider { private final static Object[] EMPTY_ARRAY = new Object[0]; private TreeViewer fViewer; @@ -59,7 +59,7 @@ } private boolean isMaxCallDepthExceeded(MethodWrapper methodWrapper) { - return methodWrapper.getLevel() > CallHierarchy.getDefault().getMaxCallDepth(); + return methodWrapper.getLevel() > CallHierarchyUI.getDefault().getMaxCallDepth(); } /** Index: ui/org/eclipse/jdt/internal/ui/callhierarchy/CallHierarchyFiltersActionGroup.java =================================================================== RCS file: ui/org/eclipse/jdt/internal/ui/callhierarchy/CallHierarchyFiltersActionGroup.java diff -N ui/org/eclipse/jdt/internal/ui/callhierarchy/CallHierarchyFiltersActionGroup.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ ui/org/eclipse/jdt/internal/ui/callhierarchy/CallHierarchyFiltersActionGroup.java 16 Apr 2003 07:00:25 -0000 @@ -0,0 +1,94 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * Jesper Kamstrup Linnet (eclipse@kamstrup-linnet.dk) - initial API and implementation + * (report 36180: Callers/Callees view) + ******************************************************************************/ +package org.eclipse.jdt.internal.ui.callhierarchy; + +import org.eclipse.jdt.internal.ui.JavaPluginImages; +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.action.IToolBarManager; +import org.eclipse.jface.action.Separator; +import org.eclipse.jface.util.Assert; +import org.eclipse.jface.viewers.StructuredViewer; +import org.eclipse.ui.IActionBars; +import org.eclipse.ui.IViewPart; +import org.eclipse.ui.actions.ActionGroup; + +/** + * Action group to add the filter action to a view part's toolbar + * menu. + *

+ * This class may be instantiated; it is not intended to be subclassed. + *

+ * + * @since 2.0 + */ +public class CallHierarchyFiltersActionGroup extends ActionGroup { + + class ShowFilterDialogAction extends Action { + ShowFilterDialogAction() { + setText(CallHierarchyMessages.getString("ShowFilterDialogAction.text")); //$NON-NLS-1$ + setImageDescriptor(JavaPluginImages.DESC_CLCL_FILTER); + } + + public void run() { + openDialog(); + } + } + + private IViewPart fPart; + private StructuredViewer fViewer; + + /** + * Creates a new CustomFiltersActionGroup. + * + * @param part the view part that owns this action group + * @param viewer the viewer to be filtered + */ + public CallHierarchyFiltersActionGroup(IViewPart part, StructuredViewer viewer) { + Assert.isNotNull(part); + Assert.isNotNull(viewer); + fPart= part; + fViewer= viewer; + } + + /* (non-Javadoc) + * Method declared on ActionGroup. + */ + public void fillActionBars(IActionBars actionBars) { + fillToolBar(actionBars.getToolBarManager()); + fillViewMenu(actionBars.getMenuManager()); + } + + private void fillToolBar(IToolBarManager toolBar) { + } + + private void fillViewMenu(IMenuManager viewMenu) { + viewMenu.add(new Separator("filters")); //$NON-NLS-1$ + viewMenu.add(new ShowFilterDialogAction()); + } + + /* (non-Javadoc) + * Method declared on ActionGroup. + */ + public void dispose() { + super.dispose(); + } + + // ---------- dialog related code ---------- + + private void openDialog() { + FiltersDialog dialog= new FiltersDialog( + fPart.getViewSite().getShell()); + + dialog.open(); + } +} Index: ui/org/eclipse/jdt/internal/ui/callhierarchy/CallHierarchyLabelProvider.java =================================================================== RCS file: /home/eclipse/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/callhierarchy/CallHierarchyLabelProvider.java,v retrieving revision 1.1 diff -u -r1.1 CallHierarchyLabelProvider.java --- ui/org/eclipse/jdt/internal/ui/callhierarchy/CallHierarchyLabelProvider.java 15 Apr 2003 09:19:18 -0000 1.1 +++ ui/org/eclipse/jdt/internal/ui/callhierarchy/CallHierarchyLabelProvider.java 16 Apr 2003 07:00:26 -0000 @@ -13,11 +13,10 @@ import java.util.Collection; -import org.eclipse.swt.graphics.Image; - -import org.eclipse.jface.viewers.LabelProvider; - +import org.eclipse.jdt.internal.corext.callhierarchy.MethodWrapper; import org.eclipse.jdt.ui.JavaElementLabelProvider; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.swt.graphics.Image; class CallHierarchyLabelProvider extends LabelProvider { private JavaElementLabelProvider fJavaElementLabelProvider = new JavaElementLabelProvider(JavaElementLabelProvider.SHOW_BASICS); Index: ui/org/eclipse/jdt/internal/ui/callhierarchy/CallHierarchyMessages.properties =================================================================== RCS file: /home/eclipse/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/callhierarchy/CallHierarchyMessages.properties,v retrieving revision 1.1 diff -u -r1.1 CallHierarchyMessages.properties --- ui/org/eclipse/jdt/internal/ui/callhierarchy/CallHierarchyMessages.properties 15 Apr 2003 09:19:18 -0000 1.1 +++ ui/org/eclipse/jdt/internal/ui/callhierarchy/CallHierarchyMessages.properties 16 Apr 2003 07:00:26 -0000 @@ -10,24 +10,6 @@ # (report 36180: Callers/Callees view) ############################################################################### -CallHierarchyPreferenceFilterPage.description=Filters -CallHierarchyPreferenceFilterPage.use.package.filters=Use package filters -CallHierarchyPreferenceFilterPage.defined.package.filters=Defined package filters -CallHierarchyPreferenceFilterPage.add.filter=Add filter -CallHierarchyPreferenceFilterPage.add.filter.tooltip=Add filter (tooltip) -CallHierarchyPreferenceFilterPage.add.package=Add package -CallHierarchyPreferenceFilterPage.add.package.tooltip=Add package (tooltip) -CallHierarchyPreferenceFilterPage.remove.filter=Remove filter -CallHierarchyPreferenceFilterPage.remove.filter.tooltip=Remove filter (tooltip) -CallHierarchyPreferenceFilterPage.enable.all=Enable all -CallHierarchyPreferenceFilterPage.enable.all.tooltip=Enable all (tooltip) -CallHierarchyPreferenceFilterPage.disable.all=Disable all -CallHierarchyPreferenceFilterPage.disable.all.tooltip=Disable all (tooltip) -CallHierarchyPreferenceFilterPage.invalid.input=Invalid input -CallHierarchyPreferenceFilterPage.addpackagedialog.title=addpackagedialog.title -CallHierarchyPreferenceFilterPage.addpackagedialog.error.message=addpackagedialog.error.message -CallHierarchyPreferenceFilterPage.addpackagedialog.message=addpackagedialog.message -CallHierarchyPreferenceFilterPage.label.defaultpackage=label.defaultpackage CallHierarchyViewPart.empty=No method has been selected. ToggleCallModeAction.callers.tooltip=Show the Caller Hierarchy ToggleCallModeAction.callers.label=Caller Hierarchy @@ -39,4 +21,10 @@ ToggleJavaLabelFormatAction.long.label=Long format ToggleOrientationAction.vertical.label=Vertical View Orientation ToggleOrientationAction.horizontal.label=Horizontal View Orientation -ToggleOrientationAction.single.label=Hierarchy View Only \ No newline at end of file +ToggleOrientationAction.single.label=Hierarchy View Only +ShowFilterDialogAction.text= &Filters... +FiltersDialog.filter= Filter Calls +FiltersDialog.filterOnNames= Filter on path names: +FiltersDialog.maxCallDepth= Max call depth: +FiltersDialog.titleMaxCallDepthInvalid= Error +FiltersDialog.messageMaxCallDepthInvalid= The max call depth must be in range [1..99] \ No newline at end of file Index: ui/org/eclipse/jdt/internal/ui/callhierarchy/CallHierarchyPreferenceBasePage.java =================================================================== RCS file: /home/eclipse/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/callhierarchy/CallHierarchyPreferenceBasePage.java,v retrieving revision 1.1 diff -u -r1.1 CallHierarchyPreferenceBasePage.java --- ui/org/eclipse/jdt/internal/ui/callhierarchy/CallHierarchyPreferenceBasePage.java 15 Apr 2003 09:19:18 -0000 1.1 +++ ui/org/eclipse/jdt/internal/ui/callhierarchy/CallHierarchyPreferenceBasePage.java 16 Apr 2003 07:00:26 -0000 @@ -11,16 +11,13 @@ ******************************************************************************/ package org.eclipse.jdt.internal.ui.callhierarchy; +import org.eclipse.jdt.internal.ui.JavaPlugin; import org.eclipse.jface.preference.BooleanFieldEditor; import org.eclipse.jface.preference.FieldEditorPreferencePage; import org.eclipse.jface.preference.IPreferenceStore; -import org.eclipse.jface.preference.IntegerFieldEditor; - import org.eclipse.ui.IWorkbench; import org.eclipse.ui.IWorkbenchPreferencePage; -import org.eclipse.jdt.internal.ui.JavaPlugin; - /** * @see PreferencePage */ @@ -43,18 +40,13 @@ * Set the default preferences for this page. */ public static void initDefaults(IPreferenceStore store) { - CallHierarchy.getDefault().initializeDefaultBasePreferences(store); + CallHierarchyUI.getDefault().initializeDefaultBasePreferences(store); } /* (non-Javadoc) * @see org.eclipse.jface.preference.FieldEditorPreferencePage#createFieldEditors() */ protected void createFieldEditors() { - IntegerFieldEditor maxCallDepth = new IntegerFieldEditor(ICallHierarchyPreferencesConstants.PREF_MAX_CALL_DEPTH, - "&Max call depth", getFieldEditorParent()); - maxCallDepth.setValidRange(1, 99); - addField(maxCallDepth); - BooleanFieldEditor useImplementorsForCallerSearch = new BooleanFieldEditor(ICallHierarchyPreferencesConstants.PREF_USE_IMPLEMENTORS_FOR_CALLER_SEARCH, "Search for &callers using the Implementors plugin", getFieldEditorParent()); @@ -64,10 +56,5 @@ "Sea&rch for callees using the Implementors plugin", getFieldEditorParent()); addField(useImplementorsForCalleeSearch); - - // This should be reenabled when the openInEditor(Object, boolean) method is made API. - // BooleanFieldEditor activateEditorOnSelect = new BooleanFieldEditor(ICallersConstants.PREF_ACTIVATE_EDITOR_ON_SELECT, - // "&Activate editor on select", getFieldEditorParent()); - // addField(activateEditorOnSelect); } } Index: ui/org/eclipse/jdt/internal/ui/callhierarchy/CallHierarchyUI.java =================================================================== RCS file: ui/org/eclipse/jdt/internal/ui/callhierarchy/CallHierarchyUI.java diff -N ui/org/eclipse/jdt/internal/ui/callhierarchy/CallHierarchyUI.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ ui/org/eclipse/jdt/internal/ui/callhierarchy/CallHierarchyUI.java 16 Apr 2003 07:00:26 -0000 @@ -0,0 +1,168 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * Jesper Kamstrup Linnet (eclipse@kamstrup-linnet.dk) - initial API and implementation + * (report 36180: Callers/Callees view) + ******************************************************************************/ +package org.eclipse.jdt.internal.ui.callhierarchy; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.jdt.core.IJavaElement; +import org.eclipse.jdt.core.JavaModelException; +import org.eclipse.jdt.internal.corext.callhierarchy.CallHierarchy; +import org.eclipse.jdt.internal.corext.callhierarchy.CallLocation; +import org.eclipse.jdt.internal.corext.callhierarchy.MethodWrapper; +import org.eclipse.jdt.internal.ui.IJavaStatusConstants; +import org.eclipse.jdt.internal.ui.JavaPlugin; +import org.eclipse.jdt.internal.ui.javaeditor.EditorUtility; +import org.eclipse.jdt.ui.JavaUI; +import org.eclipse.jface.action.IStatusLineManager; +import org.eclipse.jface.dialogs.ErrorDialog; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.jface.util.OpenStrategy; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.texteditor.ITextEditor; + +/** + * @author jl + */ +class CallHierarchyUI { + private static final int DEFAULT_MAX_CALL_DEPTH= 10; + private static final String PREF_MAX_CALL_DEPTH = "PREF_MAX_CALL_DEPTH"; + + private static CallHierarchyUI fgInstance; + + private CallHierarchyUI() { } + + public static CallHierarchyUI getDefault() { + if (fgInstance == null) { + fgInstance = new CallHierarchyUI(); + } + + return fgInstance; + } + + /** + * Returns the maximum tree level allowed + * @return int + */ + public int getMaxCallDepth() { + int maxCallDepth; + + IPreferenceStore settings = JavaPlugin.getDefault().getPreferenceStore(); + maxCallDepth = settings.getInt(PREF_MAX_CALL_DEPTH); + if (maxCallDepth < 1 || maxCallDepth > 99) { + maxCallDepth= DEFAULT_MAX_CALL_DEPTH; + } + + return maxCallDepth; + } + + public void setMaxCallDepth(int maxCallDepth) { + IPreferenceStore settings = JavaPlugin.getDefault().getPreferenceStore(); + settings.setValue(PREF_MAX_CALL_DEPTH, maxCallDepth); + } + + public void initializeDefaultBasePreferences(IPreferenceStore store) { + store.setDefault(ICallHierarchyPreferencesConstants.PREF_USE_IMPLEMENTORS_FOR_CALLER_SEARCH, + false); + store.setDefault(ICallHierarchyPreferencesConstants.PREF_USE_IMPLEMENTORS_FOR_CALLEE_SEARCH, + false); + } + + private IStatusLineManager getStatusLineManager() { + IStatusLineManager statusLineManager = PlatformUI.getWorkbench() + .getActiveWorkbenchWindow() + .getActivePage() + .findView(CallHierarchyViewPart.CALLERS_VIEW_ID) + .getViewSite().getActionBars() + .getStatusLineManager(); + statusLineManager.setCancelEnabled(true); + + return statusLineManager; + } + + public static void jumpToMember(IJavaElement element) { + if (element != null) { + try { + IEditorPart methodEditor = EditorUtility.openInEditor(element, true); + JavaUI.revealInEditor(methodEditor, (IJavaElement) element); + } catch (JavaModelException e) { + Utility.logError("Error getting underlying resource", e); + } catch (PartInitException e) { + Utility.logError("Error opening editor", e); + } + } + } + + public static void openInEditor(Object element, Shell shell, String title) { + CallLocation callLocation= null; + if (element instanceof CallLocation) { + callLocation= (CallLocation) element; + } else if (element instanceof CallLocation) { + callLocation= CallHierarchy.getCallLocation(element); + } + + if (callLocation == null) { + return; + } + + try { + boolean activateOnOpen = OpenStrategy.activateOnOpen(); + + IEditorPart methodEditor = EditorUtility.openInEditor(callLocation.getMember(), + activateOnOpen); + + if (methodEditor instanceof ITextEditor) { + ITextEditor editor = (ITextEditor) methodEditor; + editor.selectAndReveal(callLocation.getStart(), + (callLocation.getEnd() - callLocation.getStart())); + } + } catch (JavaModelException e) { + JavaPlugin.log(new Status(IStatus.ERROR, JavaPlugin.getPluginId(), + IJavaStatusConstants.INTERNAL_ERROR, + CallHierarchyMessages.getString( + "CallHierarchyUI.open_in_editor.error.message"), e)); //$NON-NLS-1$ + + ErrorDialog.openError(shell, title, + CallHierarchyMessages.getString( + "CallHierarchyUI.open_in_editor.error.messageProblems"), //$NON-NLS-1$ + e.getStatus()); + } catch (PartInitException x) { + String name = callLocation.getCalledMember().getElementName(); + MessageDialog.openError(shell, + CallHierarchyMessages.getString( + "CallHierarchyUI.open_in_editor.error.messageProblems"), //$NON-NLS-1$ + CallHierarchyMessages.getFormattedString( + "CallHierarchyUI.open_in_editor.error.messageArgs", //$NON-NLS-1$ + new String[] { name, x.getMessage() })); + } + } + + /** + * @param elem + * @return + */ + public static IEditorPart isOpenInEditor(Object elem) { + IJavaElement javaElement= null; + if (elem instanceof MethodWrapper) { + javaElement= ((MethodWrapper) elem).getMember(); + } else if (elem instanceof CallLocation) { + javaElement= ((CallLocation) elem).getCalledMember(); + } + if (javaElement != null) { + return EditorUtility.isOpenInEditor(javaElement); + } + return null; + } +} Index: ui/org/eclipse/jdt/internal/ui/callhierarchy/CallHierarchyViewPart.java =================================================================== RCS file: /home/eclipse/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/callhierarchy/CallHierarchyViewPart.java,v retrieving revision 1.1 diff -u -r1.1 CallHierarchyViewPart.java --- ui/org/eclipse/jdt/internal/ui/callhierarchy/CallHierarchyViewPart.java 15 Apr 2003 09:19:18 -0000 1.1 +++ ui/org/eclipse/jdt/internal/ui/callhierarchy/CallHierarchyViewPart.java 16 Apr 2003 07:00:29 -0000 @@ -1,28 +1,35 @@ /******************************************************************************* * Copyright (c) 2000, 2003 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials + * All rights reserved. This program and the accompanying materials * are made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/cpl-v10.html - * + * * Contributors: - * Jesper Kamstrup Linnet (eclipse@kamstrup-linnet.dk) - initial API and implementation - * (report 36180: Callers/Callees view) + * Jesper Kamstrup Linnet (eclipse@kamstrup-linnet.dk) - initial API and implementation + * (report 36180: Callers/Callees view) ******************************************************************************/ package org.eclipse.jdt.internal.ui.callhierarchy; import java.util.ArrayList; import java.util.List; -import org.eclipse.swt.SWT; -import org.eclipse.swt.custom.SashForm; -import org.eclipse.swt.events.KeyAdapter; -import org.eclipse.swt.events.KeyEvent; -import org.eclipse.swt.events.KeyListener; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Menu; - +import org.eclipse.jdt.core.IJavaElement; +import org.eclipse.jdt.core.IMember; +import org.eclipse.jdt.core.IMethod; +import org.eclipse.jdt.core.JavaModelException; +import org.eclipse.jdt.core.search.IJavaSearchScope; +import org.eclipse.jdt.internal.corext.callhierarchy.CallHierarchy; +import org.eclipse.jdt.internal.corext.callhierarchy.CallLocation; +import org.eclipse.jdt.internal.corext.callhierarchy.MethodWrapper; +import org.eclipse.jdt.internal.ui.JavaPlugin; +import org.eclipse.jdt.internal.ui.actions.CompositeActionGroup; +import org.eclipse.jdt.internal.ui.javaeditor.EditorUtility; +import org.eclipse.jdt.internal.ui.viewsupport.StatusBarUpdater; +import org.eclipse.jdt.ui.IContextMenuConstants; +import org.eclipse.jdt.ui.JavaElementLabelProvider; +import org.eclipse.jdt.ui.actions.OpenViewActionGroup; +import org.eclipse.jdt.ui.actions.RefactorActionGroup; import org.eclipse.jface.action.IMenuListener; import org.eclipse.jface.action.IMenuManager; import org.eclipse.jface.action.IStatusLineManager; @@ -41,7 +48,14 @@ import org.eclipse.jface.viewers.OpenEvent; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.viewers.Viewer; - +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.SashForm; +import org.eclipse.swt.events.KeyAdapter; +import org.eclipse.swt.events.KeyEvent; +import org.eclipse.swt.events.KeyListener; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Menu; import org.eclipse.ui.IActionBars; import org.eclipse.ui.IEditorPart; import org.eclipse.ui.IMemento; @@ -55,23 +69,6 @@ import org.eclipse.ui.part.ViewPart; import org.eclipse.ui.texteditor.ITextEditor; -import org.eclipse.jdt.core.IJavaElement; -import org.eclipse.jdt.core.IMember; -import org.eclipse.jdt.core.IMethod; -import org.eclipse.jdt.core.JavaModelException; -import org.eclipse.jdt.core.search.IJavaSearchScope; - -import org.eclipse.jdt.ui.IContextMenuConstants; -import org.eclipse.jdt.ui.JavaElementLabelProvider; -import org.eclipse.jdt.ui.actions.CustomFiltersActionGroup; -import org.eclipse.jdt.ui.actions.OpenViewActionGroup; -import org.eclipse.jdt.ui.actions.RefactorActionGroup; - -import org.eclipse.jdt.internal.ui.JavaPlugin; -import org.eclipse.jdt.internal.ui.actions.CompositeActionGroup; -import org.eclipse.jdt.internal.ui.javaeditor.EditorUtility; -import org.eclipse.jdt.internal.ui.viewsupport.StatusBarUpdater; - /** * This is the main view for the callers plugin. It builds a tree of callers/callees * and allows the user to double click an entry to go to the selected method. @@ -109,21 +106,21 @@ private int fCurrentOrientation; private int fCurrentCallMode; private int fCurrentJavaLabelFormat; - private CalleeMethodWrapper fCalleeRoot; - private CallerMethodWrapper fCallerRoot; + private MethodWrapper fCalleeRoot; + private MethodWrapper fCallerRoot; private IMemento fMemento; private IMethod fShownMethod; private SelectionProviderMediator fSelectionProviderMediator; private List fMethodHistory; private ListViewer fLocationViewer; - private Menu fListContextMenu; + private Menu fLocationContextMenu; private Menu fTreeContextMenu; private SashForm fHierarchyLocationSplitter; private SearchScopeActionGroup fSearchScopeActions; private ToggleOrientationAction[] fToggleOrientationActions; private ToggleCallModeAction[] fToggleCallModeActions; private ToggleJavaLabelFormatAction[] fToggleJavaLabelFormatActions; - private CustomFiltersActionGroup fCustomFiltersActionGroup; + private CallHierarchyFiltersActionGroup fFiltersActionGroup; private HistoryDropDownAction fHistoryDropDownAction; private RefreshAction fRefreshAction; private OpenDeclarationAction fOpenDeclarationAction; @@ -175,7 +172,7 @@ */ public void setMethod(IMethod method) { if (method == null) { - fPagebook.showPage(fNoHierarchyShownLabel); + showPage(PAGE_EMPTY); return; } @@ -285,10 +282,13 @@ showPage(PAGE_EMPTY); - fSelectionProviderMediator= new SelectionProviderMediator(new Viewer[] { fCallHierarchyViewer, fLocationViewer }); + fSelectionProviderMediator = new SelectionProviderMediator(new Viewer[] { + fCallHierarchyViewer, fLocationViewer + }); - IStatusLineManager slManager= getViewSite().getActionBars().getStatusLineManager(); - fSelectionProviderMediator.addSelectionChangedListener(new StatusBarUpdater(slManager)); + IStatusLineManager slManager = getViewSite().getActionBars().getStatusLineManager(); + fSelectionProviderMediator.addSelectionChangedListener(new StatusBarUpdater( + slManager)); getSite().setSelectionProvider(fSelectionProviderMediator); makeActions(); @@ -321,6 +321,8 @@ * @param b */ private void enableActions(boolean enabled) { + fLocationContextMenu.setEnabled(enabled); + // TODO: Is it possible to disable the actions on the toolbar and on the view menu? } @@ -442,7 +444,7 @@ */ public void dispose() { disposeMenu(fTreeContextMenu); - disposeMenu(fListContextMenu); + disposeMenu(fLocationContextMenu); super.dispose(); } @@ -483,13 +485,13 @@ Object structuredSelection = ((IStructuredSelection) selection).getFirstElement(); if (structuredSelection instanceof IMember) { - CallHierarchy.jumpToMember((IMember) structuredSelection); + CallHierarchyUI.jumpToMember((IMember) structuredSelection); } else if (structuredSelection instanceof MethodWrapper) { MethodWrapper methodWrapper = (MethodWrapper) structuredSelection; - CallHierarchy.jumpToMember(methodWrapper.getMember()); + CallHierarchyUI.jumpToMember(methodWrapper.getMember()); } else if (structuredSelection instanceof CallLocation) { - CallHierarchy.jumpToMember(((CallLocation) structuredSelection).getCalledMember()); + CallHierarchyUI.jumpToMember(((CallLocation) structuredSelection).getCalledMember()); } } } @@ -506,7 +508,7 @@ if (firstCall != null) { jumpToLocation(firstCall); } else { - CallHierarchy.jumpToMember(methodWrapper.getMember()); + CallHierarchyUI.jumpToMember(methodWrapper.getMember()); } } else if (structuredSelection instanceof CallLocation) { jumpToLocation((CallLocation) structuredSelection); @@ -557,8 +559,7 @@ /** * @param selection */ - private void locationSelectionChanged(ISelection selection) { - } + private void locationSelectionChanged(ISelection selection) {} /** * @param selection @@ -569,8 +570,8 @@ if (selectedElement instanceof MethodWrapper) { MethodWrapper methodWrapper = (MethodWrapper) selectedElement; - - revealElementInEditor(methodWrapper, fCallHierarchyViewer); + + revealElementInEditor(methodWrapper, fCallHierarchyViewer); updateLocationsView(methodWrapper); } else { updateLocationsView(null); @@ -581,21 +582,23 @@ private void revealElementInEditor(Object elem, Viewer originViewer) { // only allow revealing when the type hierarchy is the active pagae // no revealing after selection events due to model changes - if (getSite().getPage().getActivePart() != this) { return; } - + if (fSelectionProviderMediator.getViewerInFocus() != originViewer) { return; } - + if (elem instanceof MethodWrapper) { - CallLocation callLocation= CallHierarchy.getCallLocation(elem); + CallLocation callLocation = CallHierarchy.getCallLocation(elem); + if (callLocation != null) { - IEditorPart editorPart= CallHierarchy.isOpenInEditor(callLocation); + IEditorPart editorPart = CallHierarchyUI.isOpenInEditor(callLocation); + if (editorPart != null) { getSite().getPage().bringToTop(editorPart); + if (editorPart instanceof ITextEditor) { ITextEditor editor = (ITextEditor) editorPart; editor.selectAndReveal(callLocation.getStart(), @@ -603,17 +606,20 @@ } } } else { - IEditorPart editorPart= CallHierarchy.isOpenInEditor(elem); + IEditorPart editorPart = CallHierarchyUI.isOpenInEditor(elem); getSite().getPage().bringToTop(editorPart); - EditorUtility.revealInEditor(editorPart, ((MethodWrapper) elem).getMember()); + EditorUtility.revealInEditor(editorPart, + ((MethodWrapper) elem).getMember()); } } else if (elem instanceof IJavaElement) { - IEditorPart editorPart= EditorUtility.isOpenInEditor(elem); + IEditorPart editorPart = EditorUtility.isOpenInEditor(elem); + if (editorPart != null) { - // getSite().getPage().removePartListener(fPartListener); + // getSite().getPage().removePartListener(fPartListener); getSite().getPage().bringToTop(editorPart); EditorUtility.revealInEditor(editorPart, (IJavaElement) elem); - // getSite().getPage().addPartListener(fPartListener); + + // getSite().getPage().addPartListener(fPartListener); } } } @@ -637,21 +643,20 @@ protected void handleKeyEvent(KeyEvent event) { if (event.stateMask == 0) { -// if (event.keyCode == SWT.F3) { -// if ((fOpenDeclarationAction != null) && -// fOpenDeclarationAction.isEnabled()) { -// fOpenDeclarationAction.run(); - -// return; -// } -// } else - if (event.keyCode == SWT.F5) { - if ((fRefreshAction != null) && fRefreshAction.isEnabled()) { - fRefreshAction.run(); - - return; - } + // if (event.keyCode == SWT.F3) { + // if ((fOpenDeclarationAction != null) && + // fOpenDeclarationAction.isEnabled()) { + // fOpenDeclarationAction.run(); + // return; + // } + // } else + if (event.keyCode == SWT.F5) { + if ((fRefreshAction != null) && fRefreshAction.isEnabled()) { + fRefreshAction.run(); + + return; } + } } } @@ -659,25 +664,25 @@ return getViewSite().getActionBars(); } - private void setCalleeRoot(CalleeMethodWrapper calleeRoot) { + private void setCalleeRoot(MethodWrapper calleeRoot) { this.fCalleeRoot = calleeRoot; } private MethodWrapper getCalleeRoot() { if (fCalleeRoot == null) { - fCalleeRoot = (CalleeMethodWrapper) CallHierarchy.getDefault().getCalleeRoot(fShownMethod); + fCalleeRoot = (MethodWrapper) CallHierarchy.getDefault().getCalleeRoot(fShownMethod); } return fCalleeRoot; } - private void setCallerRoot(CallerMethodWrapper callerRoot) { + private void setCallerRoot(MethodWrapper callerRoot) { this.fCallerRoot = callerRoot; } private MethodWrapper getCallerRoot() { if (fCallerRoot == null) { - fCallerRoot = (CallerMethodWrapper) CallHierarchy.getDefault().getCallerRoot(fShownMethod); + fCallerRoot = (MethodWrapper) CallHierarchy.getDefault().getCallerRoot(fShownMethod); } return fCallerRoot; @@ -705,16 +710,15 @@ fLocationViewer.setLabelProvider(new LocationLabelProvider()); fLocationViewer.setInput(new ArrayList()); fLocationViewer.getControl().addKeyListener(createKeyListener()); - - fOpenLocationAction= new OpenLocationAction(getSite()); + + fOpenLocationAction = new OpenLocationAction(getSite()); fLocationViewer.addOpenListener(new IOpenListener() { - public void open(OpenEvent event) { - fOpenLocationAction.run(); - } - }); - -// fListViewer.addDoubleClickListener(this); + public void open(OpenEvent event) { + fOpenLocationAction.run(); + } + }); + // fListViewer.addDoubleClickListener(this); MenuManager menuMgr = new MenuManager(); //$NON-NLS-1$ menuMgr.setRemoveAllWhenShown(true); menuMgr.addMenuListener(new IMenuListener() { @@ -726,8 +730,8 @@ } }); - fListContextMenu = menuMgr.createContextMenu(fLocationViewer.getControl()); - fLocationViewer.getControl().setMenu(fListContextMenu); + fLocationContextMenu = menuMgr.createContextMenu(fLocationViewer.getControl()); + fLocationViewer.getControl().setMenu(fLocationContextMenu); // Register viewer with site. This must be done before making the actions. getSite().registerContextMenu(menuMgr, fLocationViewer); @@ -829,7 +833,7 @@ fOpenDeclarationAction = new OpenDeclarationAction(this.getSite()); fFocusOnSelectionAction = new FocusOnSelectionAction(this); fSearchScopeActions = new SearchScopeActionGroup(this); - fCustomFiltersActionGroup = new CustomFiltersActionGroup(this, + fFiltersActionGroup = new CallHierarchyFiltersActionGroup(this, fCallHierarchyViewer); fHistoryDropDownAction = new HistoryDropDownAction(this); fHistoryDropDownAction.setEnabled(false); @@ -850,7 +854,7 @@ fActionGroups = new CompositeActionGroup(new ActionGroup[] { new OpenViewActionGroup(this), new RefactorActionGroup(this), - fSearchScopeActions, fCustomFiltersActionGroup + fSearchScopeActions, fFiltersActionGroup }); } @@ -904,8 +908,8 @@ } static CallHierarchyViewPart findAndShowCallersView(IWorkbenchPartSite site) { - IWorkbenchPage workbenchPage= site.getPage(); - CallHierarchyViewPart callersView= null; + IWorkbenchPage workbenchPage = site.getPage(); + CallHierarchyViewPart callersView = null; try { callersView = (CallHierarchyViewPart) workbenchPage.showView(CallHierarchyViewPart.CALLERS_VIEW_ID); Index: ui/org/eclipse/jdt/internal/ui/callhierarchy/CallHierarchyViewer.java =================================================================== RCS file: /home/eclipse/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/callhierarchy/CallHierarchyViewer.java,v retrieving revision 1.1 diff -u -r1.1 CallHierarchyViewer.java --- ui/org/eclipse/jdt/internal/ui/callhierarchy/CallHierarchyViewer.java 15 Apr 2003 09:19:18 -0000 1.1 +++ ui/org/eclipse/jdt/internal/ui/callhierarchy/CallHierarchyViewer.java 16 Apr 2003 07:00:29 -0000 @@ -11,6 +11,12 @@ ******************************************************************************/ package org.eclipse.jdt.internal.ui.callhierarchy; +import org.eclipse.jdt.internal.corext.callhierarchy.MethodWrapper; +import org.eclipse.jface.action.IMenuListener; +import org.eclipse.jface.action.MenuManager; +import org.eclipse.jface.viewers.IOpenListener; +import org.eclipse.jface.viewers.OpenEvent; +import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.swt.SWT; import org.eclipse.swt.events.KeyListener; import org.eclipse.swt.layout.GridData; @@ -18,13 +24,6 @@ import org.eclipse.swt.widgets.Menu; import org.eclipse.swt.widgets.Tree; import org.eclipse.swt.widgets.TreeItem; - -import org.eclipse.jface.action.IMenuListener; -import org.eclipse.jface.action.MenuManager; -import org.eclipse.jface.viewers.IOpenListener; -import org.eclipse.jface.viewers.OpenEvent; -import org.eclipse.jface.viewers.TreeViewer; - import org.eclipse.ui.IWorkbenchPartSite; class CallHierarchyViewer extends TreeViewer { Index: ui/org/eclipse/jdt/internal/ui/callhierarchy/CallLocation.java =================================================================== RCS file: ui/org/eclipse/jdt/internal/ui/callhierarchy/CallLocation.java diff -N ui/org/eclipse/jdt/internal/ui/callhierarchy/CallLocation.java --- ui/org/eclipse/jdt/internal/ui/callhierarchy/CallLocation.java 15 Apr 2003 09:19:18 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,97 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2003 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * Jesper Kamstrup Linnet (eclipse@kamstrup-linnet.dk) - initial API and implementation - * (report 36180: Callers/Callees view) - ******************************************************************************/ -package org.eclipse.jdt.internal.ui.callhierarchy; - -import org.eclipse.core.runtime.IAdaptable; - -import org.eclipse.jdt.core.IBuffer; -import org.eclipse.jdt.core.ICompilationUnit; -import org.eclipse.jdt.core.IJavaElement; -import org.eclipse.jdt.core.IMember; -import org.eclipse.jdt.core.JavaModelException; - -class CallLocation implements IAdaptable { - private IMember fCalledMember; - private IMember fMember; - private String fCallText; - private int fEnd; - private int fStart; - - /** - * @param method - * @param cu - * @param start - * @param end - */ - public CallLocation(IMember member, IMember calledMember, int start, int end) { - this.fMember = member; - this.fCalledMember = calledMember; - this.fStart = start; - this.fEnd = end; - - fCallText = initializeCallText(); - } - - /** - * @return IMethod - */ - public IMember getCalledMember() { - return fCalledMember; - } - - /** - * - */ - public int getEnd() { - return fEnd; - } - - public IMember getMember() { - return fMember; - } - - /** - * - */ - public int getStart() { - return fStart; - } - - public String toString() { - return fCallText; - } - - private String initializeCallText() { - try { - ICompilationUnit compilationUnit = fMember.getCompilationUnit(); - - if ((fMember != null) && (compilationUnit != null)) { - IBuffer buffer = compilationUnit.getBuffer(); - - return buffer.getText(fStart, (fEnd - fStart)); - } else { - return fMember.getOpenable().getBuffer().getText(fStart, (fEnd - fStart)); - } - } catch (JavaModelException e) { - Utility.logError("CallLocation::toString: Error creating text", e); - - return "- error -"; - } - } - - public Object getAdapter(Class adapter) { - if (IJavaElement.class.isAssignableFrom(adapter)) { - return getMember(); - } - return null; - } -} Index: ui/org/eclipse/jdt/internal/ui/callhierarchy/CallSearchResultCollector.java =================================================================== RCS file: ui/org/eclipse/jdt/internal/ui/callhierarchy/CallSearchResultCollector.java diff -N ui/org/eclipse/jdt/internal/ui/callhierarchy/CallSearchResultCollector.java --- ui/org/eclipse/jdt/internal/ui/callhierarchy/CallSearchResultCollector.java 15 Apr 2003 09:19:18 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,107 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2003 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * Jesper Kamstrup Linnet (eclipse@kamstrup-linnet.dk) - initial API and implementation - * (report 36180: Callers/Callees view) - ******************************************************************************/ -package org.eclipse.jdt.internal.ui.callhierarchy; - -import java.util.HashMap; -import java.util.Map; - -import org.eclipse.jdt.core.IJavaElement; -import org.eclipse.jdt.core.IMember; -import org.eclipse.jdt.core.IType; - -class CallSearchResultCollector { - private Map fCalledMembers; - private String[] fPackageNames = null; - - public CallSearchResultCollector() { - this.fCalledMembers = createCalledMethodsData(); - - initializePackageFilters(); - } - - public Map getCallers() { - return fCalledMembers; - } - - protected void addMember(IMember member, IMember calledMember, int start, int end) { - if ((member != null) && (calledMember != null)) { - if (!isIgnored(calledMember)) { - MethodCall methodCall = (MethodCall) fCalledMembers.get(calledMember.getHandleIdentifier()); - - if (methodCall == null) { - methodCall = new MethodCall(calledMember); - fCalledMembers.put(calledMember.getHandleIdentifier(), methodCall); - } - - methodCall.addCallLocation(new CallLocation(member, calledMember, start, - end)); - } - } - } - - protected Map createCalledMethodsData() { - return new HashMap(); - } - - /** - * Method isIgnored. - * @param enclosingElement - * @return boolean - */ - private boolean isIgnored(IMember enclosingElement) { - if ((fPackageNames != null) && (fPackageNames.length > 0)) { - String fullyQualifiedName = getTypeOfElement(enclosingElement) - .getFullyQualifiedName(); - - for (int i = 0; i < fPackageNames.length; i++) { - if (matchPackage(fullyQualifiedName, fPackageNames[i])) { - return true; - } - } - } - - return false; - } - - private IType getTypeOfElement(IMember element) { - if (element.getElementType() == IJavaElement.TYPE) { - return (IType) element; - } - return element.getDeclaringType(); - } - - /** - * Method getPackageNames. - * @param strings - * @return String[] - */ - private String[] getPackageNames(String[] filters) { - if (filters != null) { - for (int i = 0; i < filters.length; i++) { - if (filters[i].endsWith(".*")) { - filters[i] = filters[i].substring(0, filters[i].length() - 2); - } - } - } - - return filters; - } - - private void initializePackageFilters() { - String[] filters = CallHierarchy.getDefault().getIgnoreFilters(); - fPackageNames = getPackageNames(filters); - } - - private boolean matchPackage(String fullyQualifiedName, String filter) { - return fullyQualifiedName.startsWith(filter); - } -} Index: ui/org/eclipse/jdt/internal/ui/callhierarchy/CalleeAnalyzerVisitor.java =================================================================== RCS file: ui/org/eclipse/jdt/internal/ui/callhierarchy/CalleeAnalyzerVisitor.java diff -N ui/org/eclipse/jdt/internal/ui/callhierarchy/CalleeAnalyzerVisitor.java --- ui/org/eclipse/jdt/internal/ui/callhierarchy/CalleeAnalyzerVisitor.java 15 Apr 2003 09:19:18 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,236 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2003 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * Jesper Kamstrup Linnet (eclipse@kamstrup-linnet.dk) - initial API and implementation - * (report 36180: Callers/Callees view) - ******************************************************************************/ -package org.eclipse.jdt.internal.ui.callhierarchy; - -import java.util.Collection; -import java.util.Map; - -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.SubProgressMonitor; - -import org.eclipse.jdt.core.IMethod; -import org.eclipse.jdt.core.ISourceRange; -import org.eclipse.jdt.core.IType; -import org.eclipse.jdt.core.JavaModelException; -import org.eclipse.jdt.core.dom.ASTNode; -import org.eclipse.jdt.core.dom.ASTVisitor; -import org.eclipse.jdt.core.dom.ClassInstanceCreation; -import org.eclipse.jdt.core.dom.ConstructorInvocation; -import org.eclipse.jdt.core.dom.IMethodBinding; -import org.eclipse.jdt.core.dom.ITypeBinding; -import org.eclipse.jdt.core.dom.MethodDeclaration; -import org.eclipse.jdt.core.dom.MethodInvocation; -import org.eclipse.jdt.core.dom.SuperConstructorInvocation; -import org.eclipse.jdt.core.dom.SuperMethodInvocation; - -import org.eclipse.jdt.internal.corext.dom.Binding2JavaModel; - -class CalleeAnalyzerVisitor extends ASTVisitor { - private CallSearchResultCollector fSearchResults; - private IMethod fMethod; - private IProgressMonitor fProgressMonitor; - private int fMethodEndPosition; - private int fMethodStartPosition; - - CalleeAnalyzerVisitor(IMethod method, IProgressMonitor progressMonitor) { - fSearchResults = new CallSearchResultCollector(); - this.fMethod = method; - this.fProgressMonitor = progressMonitor; - - try { - ISourceRange sourceRange = method.getSourceRange(); - this.fMethodStartPosition = sourceRange.getOffset(); - this.fMethodEndPosition = fMethodStartPosition + sourceRange.getLength(); - } catch (JavaModelException jme) { - Utility.logError("Error getting start and end of method: " + - fMethod.getElementName(), jme); - } - } - - /** - * Method getCallees. - * @return CallerElement - */ - public Map getCallees() { - return fSearchResults.getCallers(); - } - - /* (non-Javadoc) - * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.ClassInstanceCreation) - */ - public boolean visit(ClassInstanceCreation node) { - if (!isNodeWithinMethod(node)) { - return false; - } - - addMethodCall(node.resolveConstructorBinding(), node); - - return true; - } - - /** - * Find all constructor invocations (this(...)) from the called method. Since we only traverse into the - * AST on the wanted method declaration, this method should not hit on more constructor - * invocations than those in the wanted method. - * - * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.ConstructorInvocation) - */ - public boolean visit(ConstructorInvocation node) { - if (!isNodeWithinMethod(node)) { - return false; - } - - addMethodCall(node.resolveConstructorBinding(), node); - - return true; - } - - /** - * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.MethodDeclaration) - */ - public boolean visit(MethodDeclaration node) { - return isNodeWithinMethod(node); - } - - /** - * Find all method invocations from the called method. Since we only traverse into the - * AST on the wanted method declaration, this method should not hit on more method - * invocations than those in the wanted method. - * - * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.MethodInvocation) - */ - public boolean visit(MethodInvocation node) { - if (!isNodeWithinMethod(node)) { - return false; - } - - addMethodCall(node.resolveMethodBinding(), node); - - return true; - } - - /** - * Find invocations of the supertype's constructor from the called method (=constructor). - * Since we only traverse into the AST on the wanted method declaration, this method should - * not hit on more method invocations than those in the wanted method. - * - * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.SuperConstructorInvocation) - */ - public boolean visit(SuperConstructorInvocation node) { - if (!isNodeWithinMethod(node)) { - return false; - } - - addMethodCall(node.resolveConstructorBinding(), node); - - return true; - } - - /** - * Find all method invocations from the called method. Since we only traverse into the - * AST on the wanted method declaration, this method should not hit on more method - * invocations than those in the wanted method. - * - * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.MethodInvocation) - */ - public boolean visit(SuperMethodInvocation node) { - if (!isNodeWithinMethod(node)) { - return false; - } - - addMethodCall(node.resolveMethodBinding(), node); - - return true; - } - - /** - * Adds the specified method binding to the search results. - * @param calledMethodBinding - * @param node - */ - protected void addMethodCall(IMethodBinding calledMethodBinding, ASTNode node) { - try { - if (calledMethodBinding != null) { - fProgressMonitor.worked(1); - - ITypeBinding calledTypeBinding = calledMethodBinding.getDeclaringClass(); - IType calledType = null; - - if (!calledTypeBinding.isAnonymous()) { - calledType = Binding2JavaModel.find(calledTypeBinding, - fMethod.getJavaProject()); - } else { - calledType = Binding2JavaModel.find(calledTypeBinding.getInterfaces()[0], - fMethod.getJavaProject()); - } - - IMethod calledMethod = Binding2JavaModel.findIncludingSupertypes(calledMethodBinding, - calledType, - new SubProgressMonitor(fProgressMonitor, 100, - SubProgressMonitor.SUPPRESS_SUBTASK_LABEL)); - - if ((calledMethod != null) && calledType.isInterface()) { - calledMethod = findImplementingMethods(calledMethod); - } - - if (!isIgnoredBySearchScope(calledMethod)) { - fSearchResults.addMember(fMethod, calledMethod, - node.getStartPosition(), - node.getStartPosition() + node.getLength()); - } - } - } catch (JavaModelException jme) { - Utility.logError("Error adding callee search result", jme); - } - } - - /** - * @param enclosingElement - * @return - */ - private boolean isIgnoredBySearchScope(IMethod enclosingElement) { - if (enclosingElement != null) { - return !CallHierarchy.getDefault().getSearchScope().encloses(enclosingElement); - } else { - return false; - } - } - - private boolean isNodeWithinMethod(ASTNode node) { - int nodeStartPosition = node.getStartPosition(); - int nodeEndPosition = nodeStartPosition + node.getLength(); - - if (nodeStartPosition < fMethodStartPosition) { - return false; - } - - if (nodeEndPosition > fMethodEndPosition) { - return false; - } - - return true; - } - - /** - * @param calledMethod - */ - private IMethod findImplementingMethods(IMethod calledMethod) { - Collection implementingMethods = CallHierarchy.getDefault() - .getImplementingMethods(calledMethod); - - if ((implementingMethods.size() == 0) || (implementingMethods.size() > 1)) { - return calledMethod; - } else { - return (IMethod) implementingMethods.iterator().next(); - } - } -} Index: ui/org/eclipse/jdt/internal/ui/callhierarchy/CalleeMethodWrapper.java =================================================================== RCS file: ui/org/eclipse/jdt/internal/ui/callhierarchy/CalleeMethodWrapper.java diff -N ui/org/eclipse/jdt/internal/ui/callhierarchy/CalleeMethodWrapper.java --- ui/org/eclipse/jdt/internal/ui/callhierarchy/CalleeMethodWrapper.java 15 Apr 2003 09:19:18 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,106 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2003 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * Jesper Kamstrup Linnet (eclipse@kamstrup-linnet.dk) - initial API and implementation - * (report 36180: Callers/Callees view) - ******************************************************************************/ -package org.eclipse.jdt.internal.ui.callhierarchy; - -import java.util.Arrays; -import java.util.Comparator; -import java.util.HashMap; -import java.util.Map; - -import org.eclipse.core.runtime.IProgressMonitor; - -import org.eclipse.jdt.core.ICompilationUnit; -import org.eclipse.jdt.core.IJavaElement; -import org.eclipse.jdt.core.IMethod; -import org.eclipse.jdt.core.dom.AST; -import org.eclipse.jdt.core.dom.CompilationUnit; - -class CalleeMethodWrapper extends MethodWrapper { - private Comparator fMethodWrapperComparator = new MethodWrapperComparator(); - - private class MethodWrapperComparator implements Comparator { - /* (non-Javadoc) - * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object) - */ - public int compare(Object o1, Object o2) { - MethodWrapper m1 = (MethodWrapper) o1; - MethodWrapper m2 = (MethodWrapper) o2; - - CallLocation callLocation1 = m1.getMethodCall().getFirstCallLocation(); - CallLocation callLocation2 = m2.getMethodCall().getFirstCallLocation(); - - if ((callLocation1 != null) && (callLocation2 != null)) { - if (callLocation1.getStart() == callLocation2.getStart()) { - return callLocation1.getEnd() - callLocation2.getEnd(); - } - - return callLocation1.getStart() - callLocation2.getStart(); - } - - return 0; - } - } - - /** - * Constructor for CalleeMethodWrapper. - * @param parent - * @param method - */ - public CalleeMethodWrapper(MethodWrapper parent, MethodCall methodCall) { - super(parent, methodCall); - } - - /* Returns the calls sorted after the call location - * @see org.eclipse.jdt.internal.ui.callhierarchy.MethodWrapper#getCalls() - */ - public MethodWrapper[] getCalls() { - MethodWrapper[] result = super.getCalls(); - Arrays.sort(result, fMethodWrapperComparator); - - return result; - } - - /* (non-Javadoc) - * @see org.eclipse.jdt.internal.ui.callhierarchy.MethodWrapper#getTaskName() - */ - protected String getTaskName() { - return null; - } - - /** - * @see org.eclipse.jdt.internal.ui.callhierarchy.MethodWrapper#createMethodWrapper(org.eclipse.jdt.internal.ui.callhierarchy.MethodCall) - */ - protected MethodWrapper createMethodWrapper(MethodCall methodCall) { - return new CalleeMethodWrapper(this, methodCall); - } - - /** - * Find callees called from the current method. - * @see org.eclipse.jdt.internal.ui.callhierarchy.MethodWrapper#findChildren(org.eclipse.core.runtime.IProgressMonitor) - */ - protected Map findChildren(IProgressMonitor progressMonitor) { - if (getMember().getElementType() == IJavaElement.METHOD) { - CalleeAnalyzerVisitor visitor = new CalleeAnalyzerVisitor((IMethod) getMember(), - progressMonitor); - ICompilationUnit icu = getMember().getCompilationUnit(); - - if (icu != null) { - CompilationUnit cu = AST.parseCompilationUnit(icu, true); - cu.accept(visitor); - } - - return visitor.getCallees(); - } else { - return new HashMap(); - } - } -} Index: ui/org/eclipse/jdt/internal/ui/callhierarchy/CallerMethodWrapper.java =================================================================== RCS file: ui/org/eclipse/jdt/internal/ui/callhierarchy/CallerMethodWrapper.java diff -N ui/org/eclipse/jdt/internal/ui/callhierarchy/CallerMethodWrapper.java --- ui/org/eclipse/jdt/internal/ui/callhierarchy/CallerMethodWrapper.java 15 Apr 2003 09:19:18 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,91 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2003 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * Jesper Kamstrup Linnet (eclipse@kamstrup-linnet.dk) - initial API and implementation - * (report 36180: Callers/Callees view) - ******************************************************************************/ -package org.eclipse.jdt.internal.ui.callhierarchy; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; - -import org.eclipse.core.resources.ResourcesPlugin; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.SubProgressMonitor; - -import org.eclipse.jdt.core.IJavaElement; -import org.eclipse.jdt.core.IMember; -import org.eclipse.jdt.core.IMethod; -import org.eclipse.jdt.core.JavaModelException; -import org.eclipse.jdt.core.search.IJavaSearchConstants; -import org.eclipse.jdt.core.search.IJavaSearchScope; -import org.eclipse.jdt.core.search.SearchEngine; - -class CallerMethodWrapper extends MethodWrapper { - public CallerMethodWrapper(MethodWrapper parent, MethodCall methodCall) { - super(parent, methodCall); - } - - protected IJavaSearchScope getSearchScope() { - return CallHierarchy.getDefault().getSearchScope(); - } - - protected String getTaskName() { - return "Finding callers..."; - } - - /** - * @see org.eclipse.jdt.internal.ui.callhierarchy.MethodWrapper#createMethodWrapper(org.eclipse.jdt.internal.ui.callhierarchy.MethodCall) - */ - protected MethodWrapper createMethodWrapper(MethodCall methodCall) { - return new CallerMethodWrapper(this, methodCall); - } - - /** - * @see org.eclipse.jdt.internal.ui.callhierarchy.MethodWrapper#findChildren(org.eclipse.core.runtime.IProgressMonitor) - * @return The result of the search for children - */ - protected Map findChildren(IProgressMonitor progressMonitor) { - try { - MethodReferencesSearchCollector searchCollector = new MethodReferencesSearchCollector(); - SearchEngine searchEngine = new SearchEngine(); - - for (Iterator iter = getMembers().iterator(); - iter.hasNext() && !progressMonitor.isCanceled();) { - IMember member = (IMember) iter.next(); - searchCollector.setProgressMonitor(new SubProgressMonitor( - progressMonitor, 10, SubProgressMonitor.SUPPRESS_SUBTASK_LABEL)); - searchEngine.search(ResourcesPlugin.getWorkspace(), member, - IJavaSearchConstants.REFERENCES, getSearchScope(), searchCollector); - } - - return searchCollector.getCallers(); - } catch (JavaModelException e) { - Utility.logError("Error finding callers", e); - - return new HashMap(0); - } - } - - /** - * Returns a collection of IMember instances representing what to search for - */ - private Collection getMembers() { - Collection result = new ArrayList(); - - result.add(getMember()); - if (getMember().getElementType() == IJavaElement.METHOD) { - result.addAll(CallHierarchy.getDefault().getInterfaceMethods((IMethod) getMember())); - } - - return result; - } -} Index: ui/org/eclipse/jdt/internal/ui/callhierarchy/FiltersDialog.java =================================================================== RCS file: ui/org/eclipse/jdt/internal/ui/callhierarchy/FiltersDialog.java diff -N ui/org/eclipse/jdt/internal/ui/callhierarchy/FiltersDialog.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ ui/org/eclipse/jdt/internal/ui/callhierarchy/FiltersDialog.java 16 Apr 2003 07:00:30 -0000 @@ -0,0 +1,204 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * Jesper Kamstrup Linnet (eclipse@kamstrup-linnet.dk) - initial API and implementation + * (report 36180: Callers/Callees view) + ******************************************************************************/ +package org.eclipse.jdt.internal.ui.callhierarchy; + +import org.eclipse.jdt.internal.corext.callhierarchy.CallHierarchy; +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.MessageBox; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; + +/** + * @author jl + */ +public class FiltersDialog extends Dialog { + private Button fFilterOnNames; + private Text fNames; + private Text fMaxCallDepth; + + private SelectionListener selectionListener = new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + FiltersDialog.this.widgetSelected(e); + } + }; + + /** + * @param parentShell + */ + protected FiltersDialog(Shell parentShell) { + super(parentShell); + } + + /* (non-Javadoc) + * Method declared on Dialog. + */ + protected Control createDialogArea(Composite parent) { + Composite superComposite = (Composite) super.createDialogArea(parent); + + Font font = parent.getFont(); + Composite composite = new Composite(superComposite, SWT.NONE); + composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + composite.setFont(font); + + GridLayout layout = new GridLayout(); + layout.numColumns = 2; + composite.setLayout(layout); + + createNamesArea(composite); + createMaxCallDepthArea(composite); + + updateUIFromFilter(); + + return composite; + } + + /* (non-Javadoc) + * Method declared on Window. + */ + protected void configureShell(Shell newShell) { + super.configureShell(newShell); + newShell.setText(CallHierarchyMessages.getString("FiltersDialog.filter")); //$NON-NLS-1$ +// TODO: WorkbenchHelp.setHelp(newShell, ITaskListHelpContextIds.FILTERS_DIALOG); + } + + void createMaxCallDepthArea(Composite parent) { + new Label(parent, SWT.NONE).setText(CallHierarchyMessages.getString("FiltersDialog.maxCallDepth")); + + fMaxCallDepth = new Text(parent, SWT.SINGLE | SWT.BORDER); + fMaxCallDepth.setTextLimit(6); + + GridData gridData = new GridData(); + gridData.widthHint = convertWidthInCharsToPixels(10); + fMaxCallDepth.setLayoutData(gridData); + fMaxCallDepth.setFont(parent.getFont()); + } + + void createNamesArea(Composite parent) { + fFilterOnNames = createCheckbox(parent, + CallHierarchyMessages.getString("FiltersDialog.filterOnNames"), + false); //$NON-NLS-1$ + fFilterOnNames.setLayoutData(new GridData()); + fNames= new Text(parent, SWT.SINGLE | SWT.BORDER); + + GridData gridData = new GridData(); + gridData.widthHint = convertWidthInCharsToPixels(30); + fNames.setLayoutData(gridData); + fNames.setFont(parent.getFont()); + } + + /** + * Creates a check box button with the given parent and text. + * + * @param parent the parent composite + * @param text the text for the check box + * @param grabRow trueto grab the remaining horizontal space, + * false otherwise + * + * @return the check box button + */ + Button createCheckbox(Composite parent, String text, boolean grabRow) { + Button button = new Button(parent, SWT.CHECK); + + if (grabRow) { + GridData gridData = new GridData(GridData.FILL_HORIZONTAL); + button.setLayoutData(gridData); + } + + button.setText(text); + button.addSelectionListener(selectionListener); + button.setFont(parent.getFont()); + + return button; + } + + /** + * Updates the enabled state of the widgetry. + */ + void updateEnabledState() { + fNames.setEnabled(fFilterOnNames.getSelection()); + } + + /** + * Updates the given filter from the UI state. + * + * @param filter the filter to update + */ + void updateFilterFromUI() { + int maxCallDepth = Integer.parseInt(this.fMaxCallDepth.getText()); + + CallHierarchyUI.getDefault().setMaxCallDepth(maxCallDepth); + CallHierarchy.getDefault().setFilters(fNames.getText()); + CallHierarchy.getDefault().setFilterEnabled(fFilterOnNames.getSelection()); + } + + /** + * Updates the UI state from the given filter. + * + * @param filter the filter to use + */ + void updateUIFromFilter() { + fMaxCallDepth.setText(""+CallHierarchyUI.getDefault().getMaxCallDepth()); //$NON-NLS-1$ + fNames.setText(CallHierarchy.getDefault().getFilters()); + fFilterOnNames.setSelection(CallHierarchy.getDefault().isFilterEnabled()); + updateEnabledState(); + } + + /** + * Handles selection on a check box or combo box. + */ + void widgetSelected(SelectionEvent e) { + updateEnabledState(); + } + + /** + * Updates the filter from the UI state. + * Must be done here rather than by extending open() + * because after super.open() is called, the widgetry is disposed. + */ + protected void okPressed() { + try { + int maxCallDepth = Integer.parseInt(this.fMaxCallDepth.getText()); + + if (maxCallDepth < 1 || maxCallDepth > 99) { + throw new NumberFormatException(); + } + + updateFilterFromUI(); + super.okPressed(); + } + catch (NumberFormatException eNumberFormat) { + MessageBox messageBox = new MessageBox(getShell(), + SWT.OK | SWT.APPLICATION_MODAL | SWT.ICON_ERROR); + messageBox.setText(CallHierarchyMessages.getString( + "FiltersDialog.titleMaxCallDepthInvalid")); //$NON-NLS-1$ + messageBox.setMessage(CallHierarchyMessages.getString( + "FiltersDialog.messageMaxCallDepthInvalid")); //$NON-NLS-1$ + messageBox.open(); + + if (fMaxCallDepth.forceFocus()) { + fMaxCallDepth.setSelection(0, fMaxCallDepth.getCharCount()); + fMaxCallDepth.showSelection(); + } + } + } +} Index: ui/org/eclipse/jdt/internal/ui/callhierarchy/FocusOnSelectionAction.java =================================================================== RCS file: /home/eclipse/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/callhierarchy/FocusOnSelectionAction.java,v retrieving revision 1.1 diff -u -r1.1 FocusOnSelectionAction.java --- ui/org/eclipse/jdt/internal/ui/callhierarchy/FocusOnSelectionAction.java 15 Apr 2003 09:19:18 -0000 1.1 +++ ui/org/eclipse/jdt/internal/ui/callhierarchy/FocusOnSelectionAction.java 16 Apr 2003 07:00:30 -0000 @@ -12,14 +12,14 @@ package org.eclipse.jdt.internal.ui.callhierarchy; import org.eclipse.core.runtime.IAdaptable; - -import org.eclipse.jface.action.Action; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.ISelectionProvider; - import org.eclipse.jdt.core.IJavaElement; import org.eclipse.jdt.core.IMember; import org.eclipse.jdt.core.IMethod; +import org.eclipse.jdt.internal.corext.callhierarchy.MethodWrapper; +import org.eclipse.jdt.internal.ui.util.SelectionUtil; +import org.eclipse.jface.action.Action; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionProvider; class FocusOnSelectionAction extends Action { private CallHierarchyViewPart fPart; @@ -32,7 +32,7 @@ } public boolean canActionBeAdded() { - Object element = Utility.getSingleElement(getSelection()); + Object element = SelectionUtil.getSingleElement(getSelection()); IMethod method = null; @@ -55,7 +55,7 @@ * @see Action#run */ public void run() { - Object element = Utility.getSingleElement(getSelection()); + Object element = SelectionUtil.getSingleElement(getSelection()); if (element instanceof MethodWrapper) { IMember member= ((MethodWrapper) element).getMember(); Index: ui/org/eclipse/jdt/internal/ui/callhierarchy/ICallHierarchyPreferencesConstants.java =================================================================== RCS file: /home/eclipse/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/callhierarchy/ICallHierarchyPreferencesConstants.java,v retrieving revision 1.1 diff -u -r1.1 ICallHierarchyPreferencesConstants.java --- ui/org/eclipse/jdt/internal/ui/callhierarchy/ICallHierarchyPreferencesConstants.java 15 Apr 2003 09:19:18 -0000 1.1 +++ ui/org/eclipse/jdt/internal/ui/callhierarchy/ICallHierarchyPreferencesConstants.java 16 Apr 2003 07:00:30 -0000 @@ -12,10 +12,6 @@ package org.eclipse.jdt.internal.ui.callhierarchy; public interface ICallHierarchyPreferencesConstants { - public static final String PREF_USE_FILTERS = "PREF_USE_FILTERS"; - public static final String PREF_INACTIVE_FILTERS_LIST = "PREF_INACTIVE_FILTERS_LIST"; - public static final String PREF_ACTIVE_FILTERS_LIST = "PREF_ACTIVE_FILTERS_LIST"; - public static final String PREF_MAX_CALL_DEPTH = "PREF_MAX_CALL_DEPTH"; public static final String PREF_USE_IMPLEMENTORS_FOR_CALLER_SEARCH = "PREF_USE_IMPLEMENTORS_FOR_CALLER_SEARCH"; public static final String PREF_USE_IMPLEMENTORS_FOR_CALLEE_SEARCH = "PREF_USE_IMPLEMENTORS_FOR_CALLEE_SEARCH"; } Index: ui/org/eclipse/jdt/internal/ui/callhierarchy/LocationLabelProvider.java =================================================================== RCS file: /home/eclipse/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/callhierarchy/LocationLabelProvider.java,v retrieving revision 1.1 diff -u -r1.1 LocationLabelProvider.java --- ui/org/eclipse/jdt/internal/ui/callhierarchy/LocationLabelProvider.java 15 Apr 2003 09:19:18 -0000 1.1 +++ ui/org/eclipse/jdt/internal/ui/callhierarchy/LocationLabelProvider.java 16 Apr 2003 07:00:30 -0000 @@ -11,6 +11,7 @@ ******************************************************************************/ package org.eclipse.jdt.internal.ui.callhierarchy; +import org.eclipse.jdt.internal.corext.callhierarchy.CallLocation; import org.eclipse.jface.viewers.LabelProvider; class LocationLabelProvider extends LabelProvider { Index: ui/org/eclipse/jdt/internal/ui/callhierarchy/MethodCall.java =================================================================== RCS file: ui/org/eclipse/jdt/internal/ui/callhierarchy/MethodCall.java diff -N ui/org/eclipse/jdt/internal/ui/callhierarchy/MethodCall.java --- ui/org/eclipse/jdt/internal/ui/callhierarchy/MethodCall.java 15 Apr 2003 09:19:18 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,70 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2003 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * Jesper Kamstrup Linnet (eclipse@kamstrup-linnet.dk) - initial API and implementation - * (report 36180: Callers/Callees view) - ******************************************************************************/ -package org.eclipse.jdt.internal.ui.callhierarchy; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -import org.eclipse.jdt.core.IMember; - -class MethodCall { - private IMember fMember; - private List fCallLocations; - - /** - * @param enclosingElement - */ - public MethodCall(IMember enclosingElement) { - this.fMember = enclosingElement; - } - - /** - * - */ - public Collection getCallLocations() { - return fCallLocations; - } - - public CallLocation getFirstCallLocation() { - if ((fCallLocations != null) && !fCallLocations.isEmpty()) { - return (CallLocation) fCallLocations.get(0); - } else { - return null; - } - } - - /** - * @return Object - */ - public Object getKey() { - return getMember().getHandleIdentifier(); - } - - /** - * - */ - public IMember getMember() { - return fMember; - } - - /** - * @param location - */ - public void addCallLocation(CallLocation location) { - if (fCallLocations == null) { - fCallLocations = new ArrayList(); - } - - fCallLocations.add(location); - } -} Index: ui/org/eclipse/jdt/internal/ui/callhierarchy/MethodReferencesSearchCollector.java =================================================================== RCS file: ui/org/eclipse/jdt/internal/ui/callhierarchy/MethodReferencesSearchCollector.java diff -N ui/org/eclipse/jdt/internal/ui/callhierarchy/MethodReferencesSearchCollector.java --- ui/org/eclipse/jdt/internal/ui/callhierarchy/MethodReferencesSearchCollector.java 15 Apr 2003 09:19:18 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,82 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2003 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * Jesper Kamstrup Linnet (eclipse@kamstrup-linnet.dk) - initial API and implementation - * (report 36180: Callers/Callees view) - ******************************************************************************/ -package org.eclipse.jdt.internal.ui.callhierarchy; - -import java.util.Map; - -import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.SubProgressMonitor; - -import org.eclipse.jdt.core.IJavaElement; -import org.eclipse.jdt.core.IMember; -import org.eclipse.jdt.core.search.IJavaSearchResultCollector; - -class MethodReferencesSearchCollector implements IJavaSearchResultCollector { - private CallSearchResultCollector fSearchResults; - private IProgressMonitor fProgressMonitor; - private boolean fRequireExactMatch = true; - - MethodReferencesSearchCollector() { - fSearchResults = new CallSearchResultCollector(); - } - - public Map getCallers() { - return fSearchResults.getCallers(); - } - - /** - * @see org.eclipse.jdt.core.search.IJavaSearchResultCollector#getProgressMonitor() - */ - public IProgressMonitor getProgressMonitor() { - return fProgressMonitor; - } - - /** - * @see org.eclipse.jdt.core.search.IJavaSearchResultCollector#aboutToStart() - */ - public void aboutToStart() {} - - /** - * @see org.eclipse.jdt.core.search.IJavaSearchResultCollector#accept(org.eclipse.core.resources.IResource, int, int, org.eclipse.jdt.core.IJavaElement, int) - */ - public void accept(IResource resource, int start, int end, - IJavaElement enclosingElement, int accuracy) throws CoreException { - if (fRequireExactMatch && (accuracy != IJavaSearchResultCollector.EXACT_MATCH)) { - return; - } - - if (enclosingElement != null && enclosingElement instanceof IMember) { - IMember member= (IMember) enclosingElement; - switch (enclosingElement.getElementType()) { - case IJavaElement.METHOD: - case IJavaElement.TYPE: - case IJavaElement.FIELD: - fSearchResults.addMember(member, member, start, end); - break; - } - } - } - - /** - * @see org.eclipse.jdt.core.search.IJavaSearchResultCollector#done() - */ - public void done() {} - - /** - * @param monitor - */ - void setProgressMonitor(SubProgressMonitor monitor) { - this.fProgressMonitor = monitor; - } -} Index: ui/org/eclipse/jdt/internal/ui/callhierarchy/MethodWrapper.java =================================================================== RCS file: ui/org/eclipse/jdt/internal/ui/callhierarchy/MethodWrapper.java diff -N ui/org/eclipse/jdt/internal/ui/callhierarchy/MethodWrapper.java --- ui/org/eclipse/jdt/internal/ui/callhierarchy/MethodWrapper.java 15 Apr 2003 09:19:18 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,326 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2003 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * Jesper Kamstrup Linnet (eclipse@kamstrup-linnet.dk) - initial API and implementation - * (report 36180: Callers/Callees view) - ******************************************************************************/ -package org.eclipse.jdt.internal.ui.callhierarchy; - -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; - -import org.eclipse.core.runtime.IAdaptable; -import org.eclipse.core.runtime.IProgressMonitor; - -import org.eclipse.jdt.core.IJavaElement; -import org.eclipse.jdt.core.IMember; -import org.eclipse.jdt.core.IMethod; - -/** - * This class represents the general parts of a method call (either to or from a - * method). - * - */ -public abstract class MethodWrapper implements IAdaptable { - private Map fElements = null; - - /* - * A cache of previously found methods. This cache should be searched - * before adding a "new" method object reference to the list of elements. - * This way previously found methods won't be searched again. - */ - private Map fMethodCache; - private MethodCall fMethodCall; - private MethodWrapper fParent; - private int fLevel; - - /** - * Constructor CallerElement. - */ - public MethodWrapper(MethodWrapper parent, MethodCall methodCall) { - super(); - - if (methodCall == null) { - throw new IllegalArgumentException("Parameter method cannot be null"); - } - - if (parent == null) { - setMethodCache(new HashMap()); - fLevel = 1; - } else { - setMethodCache(parent.getMethodCache()); - fLevel = parent.getLevel() + 1; - } - - this.fMethodCall = methodCall; - this.fParent = parent; - } - - public Object getAdapter(Class adapter) { - if (adapter == IMethod.class) { - if (getMember().getElementType() == IJavaElement.METHOD) { - return getMember(); - } else { - return null; - } - } else { - if (IJavaElement.class.isAssignableFrom(adapter)) { - return getMember(); - } - } - - return null; - } - - /** - * Method getCallerElements. - * @return The child caller elements of this element - */ - public MethodWrapper[] getCalls() { - if (fElements == null) { - doFindChildren(); - } - - MethodWrapper[] result = new MethodWrapper[fElements.size()]; - int i = 0; - - for (Iterator iter = fElements.keySet().iterator(); iter.hasNext();) { - MethodCall methodCall = getMethodCallFromMap(fElements, iter.next()); - result[i++] = createMethodWrapper(methodCall); - } - - return result; - } - - /** - * @return int - */ - public int getLevel() { - return fLevel; - } - - /** - * Method getMethod. - * @return Object - */ - public IMember getMember() { - return getMethodCall().getMember(); - } - - /** - * @return MethodCall - */ - public MethodCall getMethodCall() { - return fMethodCall; - } - - /** - * Method getName. - */ - public String getName() { - if (getMethodCall() != null) { - return getMethodCall().getMember().getElementName(); - } else { - return ""; - } - } - - /** - * Method getParent. - * @return - */ - public MethodWrapper getParent() { - return fParent; - } - - public boolean equals(Object oth) { - if (this == oth) { - return true; - } - - if (oth == null) { - return false; - } - - if (oth.getClass() != getClass()) { - return false; - } - - MethodWrapper other = (MethodWrapper) oth; - - if (this.fParent == null) { - if (other.fParent != null) { - return false; - } - } else { - if (!this.fParent.equals(other.fParent)) { - return false; - } - } - - if (this.getMethodCall() == null) { - if (other.getMethodCall() != null) { - return false; - } - } else { - if (!this.getMethodCall().equals(other.getMethodCall())) { - return false; - } - } - - return true; - } - - public int hashCode() { - final int PRIME = 1000003; - int result = 0; - - if (fParent != null) { - result = (PRIME * result) + fParent.hashCode(); - } - - if (getMethodCall() != null) { - result = (PRIME * result) + getMethodCall().getMember().hashCode(); - } - - return result; - } - - /** - * @see java.lang.Object#toString() - */ - public String toString() { - String result; - - result = "CallerElement[name=" + getName() + ", children="; - - if (fElements == null) { - result += "unknown]"; - } else { - result += (fElements.size() + "]"); - } - - return result; - } - - private void setMethodCache(Map methodCache) { - fMethodCache = methodCache; - } - - protected abstract String getTaskName(); - - private void addCallToCache(MethodCall methodCall) { - Map cachedCalls = lookupMethod(this.getMethodCall()); - cachedCalls.put(methodCall.getKey(), methodCall); - } - - /** - * Method createMethodWrapper. - * @param method - * @return MethodWrapper - */ - protected abstract MethodWrapper createMethodWrapper(MethodCall methodCall); - - private void doFindChildren() { - Map existingResults = lookupMethod(getMethodCall()); - - if (existingResults != null) { - fElements = new HashMap(); - fElements.putAll(existingResults); - } else { - initCalls(); - - IProgressMonitor progressMonitor = getProgressMonitor(); - - if (progressMonitor != null) { - progressMonitor.beginTask(getTaskName(), IProgressMonitor.UNKNOWN); - } - - try { - performSearch(progressMonitor); - } finally { - if (progressMonitor != null) { - progressMonitor.done(); - } - } - - // ModalContext.run(getRunnableWithProgress(), true, getProgressMonitor(), - // Display.getCurrent()); - } - } - - /** - * Determines if the method represents a recursion call (i.e. whether the - * method call is already in the cache.) - * - * @return True if the call is part of a recursion - */ - public boolean isRecursive() { - MethodWrapper current = getParent(); - - while (current != null) { - if (getMember().getHandleIdentifier().equals(current.getMember() - .getHandleIdentifier())) { - return true; - } - - current = current.getParent(); - } - - return false; - } - - /** - * This method finds the children of the current IMethod (either callers or - * callees, depending on the concrete subclass. - * @return The result of the search for children - */ - protected abstract Map findChildren(IProgressMonitor progressMonitor); - - private Map getMethodCache() { - return fMethodCache; - } - - private void initCalls() { - this.fElements = new HashMap(); - - initCacheForMethod(); - } - - /** - * Looks up a previously created search result in the "global" cache. - * @param method - * @return List List of previously found search results - */ - private Map lookupMethod(MethodCall methodCall) { - return (Map) getMethodCache().get(methodCall.getKey()); - } - - private void performSearch(IProgressMonitor progressMonitor) { - fElements = findChildren(progressMonitor); - - for (Iterator iter = fElements.keySet().iterator(); iter.hasNext();) { - MethodCall methodCall = getMethodCallFromMap(fElements, iter.next()); - addCallToCache(methodCall); - } - } - - private MethodCall getMethodCallFromMap(Map elements, Object key) { - return (MethodCall) elements.get(key); - } - - private IProgressMonitor getProgressMonitor() { - return CallHierarchy.getDefault().getProgressMonitor(); - } - - private void initCacheForMethod() { - Map cachedCalls = new HashMap(); - getMethodCache().put(this.getMethodCall().getKey(), cachedCalls); - } -} Index: ui/org/eclipse/jdt/internal/ui/callhierarchy/OpenDeclarationAction.java =================================================================== RCS file: /home/eclipse/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/callhierarchy/OpenDeclarationAction.java,v retrieving revision 1.1 diff -u -r1.1 OpenDeclarationAction.java --- ui/org/eclipse/jdt/internal/ui/callhierarchy/OpenDeclarationAction.java 15 Apr 2003 09:19:18 -0000 1.1 +++ ui/org/eclipse/jdt/internal/ui/callhierarchy/OpenDeclarationAction.java 16 Apr 2003 07:00:31 -0000 @@ -16,25 +16,23 @@ import java.util.List; import org.eclipse.core.runtime.IAdaptable; - +import org.eclipse.jdt.core.IMethod; +import org.eclipse.jdt.core.JavaModelException; +import org.eclipse.jdt.internal.corext.callhierarchy.MethodWrapper; +import org.eclipse.jdt.internal.ui.util.SelectionUtil; +import org.eclipse.jdt.ui.actions.OpenAction; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.StructuredSelection; - import org.eclipse.ui.IWorkbenchSite; -import org.eclipse.jdt.core.IMethod; -import org.eclipse.jdt.core.JavaModelException; - -import org.eclipse.jdt.ui.actions.OpenAction; - class OpenDeclarationAction extends OpenAction { public OpenDeclarationAction(IWorkbenchSite site) { super(site); } public boolean canActionBeAdded() { - Object element = Utility.getSingleElement(getSelection()); + Object element = SelectionUtil.getSingleElement(getSelection()); IMethod method = null; Index: ui/org/eclipse/jdt/internal/ui/callhierarchy/OpenLocationAction.java =================================================================== RCS file: /home/eclipse/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/callhierarchy/OpenLocationAction.java,v retrieving revision 1.1 diff -u -r1.1 OpenLocationAction.java --- ui/org/eclipse/jdt/internal/ui/callhierarchy/OpenLocationAction.java 15 Apr 2003 09:19:18 -0000 1.1 +++ ui/org/eclipse/jdt/internal/ui/callhierarchy/OpenLocationAction.java 16 Apr 2003 07:00:31 -0000 @@ -13,12 +13,12 @@ import java.util.Iterator; +import org.eclipse.jdt.internal.corext.callhierarchy.CallLocation; +import org.eclipse.jdt.internal.corext.callhierarchy.MethodWrapper; +import org.eclipse.jdt.ui.actions.SelectionDispatchAction; import org.eclipse.jface.viewers.IStructuredSelection; - import org.eclipse.ui.IWorkbenchSite; -import org.eclipse.jdt.ui.actions.SelectionDispatchAction; - class OpenLocationAction extends SelectionDispatchAction { public OpenLocationAction(IWorkbenchSite site) { super(site); @@ -56,7 +56,7 @@ } private void run(Object element) { - CallHierarchy.openInEditor(element, getShell(), getDialogTitle()); + CallHierarchyUI.openInEditor(element, getShell(), getDialogTitle()); } private String getDialogTitle() { Index: ui/org/eclipse/jdt/internal/ui/callhierarchy/Utility.java =================================================================== RCS file: /home/eclipse/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/callhierarchy/Utility.java,v retrieving revision 1.1 diff -u -r1.1 Utility.java --- ui/org/eclipse/jdt/internal/ui/callhierarchy/Utility.java 15 Apr 2003 09:19:18 -0000 1.1 +++ ui/org/eclipse/jdt/internal/ui/callhierarchy/Utility.java 16 Apr 2003 07:00:31 -0000 @@ -20,28 +20,6 @@ import org.eclipse.jdt.internal.ui.JavaPlugin; class Utility { - /** - * Returns the selected element if the selection - * consists of a single element only. - * - * @param selection the selection - * @return the selected first element or null - * - */ - public static Object getSingleElement(ISelection s) { - if (!(s instanceof IStructuredSelection)) { - return null; - } - - IStructuredSelection selection = (IStructuredSelection) s; - - if (selection.size() != 1) { - return null; - } - - return selection.getFirstElement(); - } - static void logDebug(String message) { if (JavaPlugin.getDefault().isDebugging()) { JavaPlugin.getDefault().getLog().log(new Status(IStatus.INFO,