blob: 4b41970a6bf885e2648949fa75a3767f887749fb [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2004 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:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.jdt.internal.debug.ui.actions;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.IBreakpointManager;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.model.IBreakpoint;
import org.eclipse.debug.ui.actions.IToggleBreakpointsTarget;
import org.eclipse.jdt.core.Flags;
import org.eclipse.jdt.core.IClassFile;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IField;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IMember;
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.ISourceRange;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.Signature;
import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.dom.ASTParser;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.search.IJavaSearchConstants;
import org.eclipse.jdt.core.search.IJavaSearchScope;
import org.eclipse.jdt.core.search.ITypeNameRequestor;
import org.eclipse.jdt.core.search.SearchEngine;
import org.eclipse.jdt.debug.core.IJavaBreakpoint;
import org.eclipse.jdt.debug.core.IJavaFieldVariable;
import org.eclipse.jdt.debug.core.IJavaLineBreakpoint;
import org.eclipse.jdt.debug.core.IJavaMethodBreakpoint;
import org.eclipse.jdt.debug.core.IJavaWatchpoint;
import org.eclipse.jdt.debug.core.JDIDebugModel;
import org.eclipse.jdt.internal.corext.util.TypeInfo;
import org.eclipse.jdt.internal.corext.util.TypeInfoRequestor;
import org.eclipse.jdt.internal.debug.ui.BreakpointUtils;
import org.eclipse.jdt.internal.debug.ui.ExceptionHandler;
import org.eclipse.jdt.internal.debug.ui.JDIDebugUIPlugin;
import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants;
import org.eclipse.jdt.ui.IWorkingCopyManager;
import org.eclipse.jdt.ui.JavaUI;
import org.eclipse.jface.action.IStatusLineManager;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IFileEditorInput;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.texteditor.IEditorStatusLine;
import org.eclipse.ui.texteditor.ITextEditor;
/**
* Toggles a line breakpoint in a Java editor.
*
* @since 3.0
*/
public class ToggleBreakpointAdapter implements IToggleBreakpointsTarget {
protected void report(String message, IWorkbenchPart part) {
IEditorStatusLine statusLine= (IEditorStatusLine) part.getAdapter(IEditorStatusLine.class);
if (statusLine != null) {
if (message != null) {
statusLine.setMessage(true, message, null);
} else {
statusLine.setMessage(true, null, null);
}
}
if (message != null && JDIDebugUIPlugin.getActiveWorkbenchShell() != null) {
JDIDebugUIPlugin.getActiveWorkbenchShell().getDisplay().beep();
}
}
protected IType getType(ITextSelection selection) {
IMember member= ActionDelegateHelper.getDefault().getCurrentMember(selection);
IType type= null;
if (member instanceof IType) {
type = (IType)member;
} else if (member != null) {
type= member.getDeclaringType();
}
// bug 52385: we don't want local and anonymous types from compilation unit,
// we are getting 'not-always-correct' names for them.
try {
while (type != null && !type.isBinary() && type.isLocal()) {
type= type.getDeclaringType();
}
} catch (JavaModelException e) {
JDIDebugUIPlugin.log(e);
}
return type;
}
/* (non-Javadoc)
* @see org.eclipse.debug.ui.actions.IToggleBreakpointsTarget#toggleLineBreakpoints(IWorkbenchPart, ISelection)
*/
public void toggleLineBreakpoints(IWorkbenchPart part, ISelection selection) throws CoreException {
if (selection instanceof ITextSelection) {
report(null, part);
IEditorPart editorPart = (IEditorPart)part;
ITextSelection textSelection = (ITextSelection)selection;
IType type = getType(textSelection);
IEditorInput editorInput = editorPart.getEditorInput();
IDocument document= ((ITextEditor)editorPart).getDocumentProvider().getDocument(editorInput);
int lineNumber= textSelection.getStartLine() + 1;
int offset= textSelection.getOffset();
try {
if (type == null) {
IClassFile classFile= (IClassFile)editorInput.getAdapter(IClassFile.class);
if (classFile != null) {
type= classFile.getType();
// bug 34856 - if this is an inner type, ensure the breakpoint is not
// being added to the outer type
if (type.getDeclaringType() != null) {
ISourceRange sourceRange= type.getSourceRange();
int start= sourceRange.getOffset();
int end= start + sourceRange.getLength();
if (offset < start || offset > end) {
// not in the inner type
IStatusLineManager statusLine = editorPart.getEditorSite().getActionBars().getStatusLineManager();
statusLine .setErrorMessage(MessageFormat.format(ActionMessages.getString("ManageBreakpointRulerAction.Breakpoints_can_only_be_created_within_the_type_associated_with_the_editor__{0}._1"), new String[] { type.getTypeQualifiedName()})); //$NON-NLS-1$
Display.getCurrent().beep();
return;
}
}
}
}
String typeName= null;
IResource resource;
IJavaLineBreakpoint breakpoint= null;
if (type == null) {
if (editorInput instanceof IFileEditorInput) {
resource= ((IFileEditorInput)editorInput).getFile();
} else {
resource= ResourcesPlugin.getWorkspace().getRoot();
}
} else {
typeName= type.getFullyQualifiedName();
IJavaLineBreakpoint existingBreakpoint= JDIDebugModel.lineBreakpointExists(typeName, lineNumber);
if (existingBreakpoint != null) {
DebugPlugin.getDefault().getBreakpointManager().removeBreakpoint(existingBreakpoint, true);
return;
}
resource= BreakpointUtils.getBreakpointResource(type);
Map attributes = new HashMap(10);
try {
IRegion line= document.getLineInformation(lineNumber - 1);
int start= line.getOffset();
int end= start + line.getLength() - 1;
BreakpointUtils.addJavaBreakpointAttributesWithMemberDetails(attributes, type, start, end);
} catch (BadLocationException ble) {
JDIDebugUIPlugin.log(ble);
}
breakpoint= JDIDebugModel.createLineBreakpoint(resource, typeName, lineNumber, -1, -1, 0, true, attributes);
}
new BreakpointLocationVerifierJob(document, breakpoint, lineNumber, typeName, type, resource, (IEditorStatusLine) editorPart.getAdapter(IEditorStatusLine.class)).schedule();
} catch (CoreException ce) {
ExceptionHandler.handle(ce, ActionMessages.getString("ManageBreakpointActionDelegate.error.title1"), ActionMessages.getString("ManageBreakpointActionDelegate.error.message1")); //$NON-NLS-1$ //$NON-NLS-2$
return;
}
}
}
/*(non-Javadoc)
* @see org.eclipse.debug.ui.actions.IToggleBreakpointsTarget#canToggleLineBreakpoints(IWorkbenchPart, ISelection)
*/
public boolean canToggleLineBreakpoints(IWorkbenchPart part, ISelection selection) {
return selection instanceof ITextSelection;
}
/* (non-Javadoc)
* @see org.eclipse.debug.ui.actions.IToggleBreakpointsTarget#toggleMethodBreakpoints(org.eclipse.ui.IWorkbenchPart, org.eclipse.jface.viewers.ISelection)
*/
public void toggleMethodBreakpoints(IWorkbenchPart part, ISelection selection) throws CoreException {
report(null, part);
selection = translateToMembers(part, selection);
if (selection instanceof ITextSelection) {
ITextSelection textSelection = (ITextSelection) selection;
if (selection != null) {
CompilationUnit compilationUnit= parseCompilationUnit((ITextEditor)part);
if (compilationUnit != null) {
BreakpointMethodLocator locator= new BreakpointMethodLocator(textSelection.getOffset());
compilationUnit.accept(locator);
String methodName= locator.getMethodName();
if (methodName == null) {
report(ActionMessages.getString("ManageMethodBreakpointActionDelegate.CantAdd"), part); //$NON-NLS-1$
return;
}
String typeName= locator.getTypeName();
String methodSignature= locator.getMethodSignature();
if (methodSignature == null) {
report(ActionMessages.getString("ManageMethodBreakpointActionDelegate.methodNonAvailable"), part); //$NON-NLS-1$
return;
}
// check if this method breakpoint already exist. If yes, remove it.
IBreakpointManager breakpointManager= DebugPlugin.getDefault().getBreakpointManager();
IBreakpoint[] breakpoints= breakpointManager.getBreakpoints(JDIDebugModel.getPluginIdentifier());
for (int i= 0; i < breakpoints.length; i++) {
IBreakpoint breakpoint= breakpoints[i];
if (breakpoint instanceof IJavaMethodBreakpoint) {
IJavaMethodBreakpoint methodBreakpoint= (IJavaMethodBreakpoint)breakpoint;
if (typeName.equals(methodBreakpoint.getTypeName())
&& methodName.equals(methodBreakpoint.getMethodName())
&& methodSignature.equals(methodBreakpoint.getMethodSignature())) {
breakpointManager.removeBreakpoint(methodBreakpoint, true);
return;
}
}
}
// add the breakpoint
JDIDebugModel.createMethodBreakpoint(getResource((IEditorPart)part), typeName, methodName, methodSignature, true, false, false, -1, -1, -1, 0, true, new HashMap(10));
}
}
} else if (selection instanceof IStructuredSelection) {
IMethod[] members= getMethods((IStructuredSelection)selection);
if (members.length == 0) {
report(ActionMessages.getString("ToggleBreakpointAdapter.9"), part); //$NON-NLS-1$
return;
}
// add or remove the breakpoint
IBreakpointManager breakpointManager= DebugPlugin.getDefault().getBreakpointManager();
for (int i= 0, length= members.length; i < length; i++) {
IMethod method= members[i];
IJavaBreakpoint breakpoint= getBreakpoint(method);
if (breakpoint == null) {
// add breakpoint
int start = -1;
int end = -1;
ISourceRange range = method.getNameRange();
if (range != null) {
start = range.getOffset();
end = start + range.getLength();
}
Map attributes = new HashMap(10);
BreakpointUtils.addJavaBreakpointAttributes(attributes, method);
String methodName = method.getElementName();
if (method.isConstructor()) {
methodName = "<init>"; //$NON-NLS-1$
}
IType type= method.getDeclaringType();
String methodSignature= method.getSignature();
if (!type.isBinary()) {
//resolve the type names
methodSignature= resolveMethodSignature(type, methodSignature);
if (methodSignature == null) {
IStatus status = new Status(IStatus.ERROR, JDIDebugUIPlugin.getUniqueIdentifier(), IStatus.ERROR, "Source method signature could not be resolved", null); //$NON-NLS-1$
throw new CoreException(status);
}
}
JDIDebugModel.createMethodBreakpoint(BreakpointUtils.getBreakpointResource(method), type.getFullyQualifiedName(), methodName, methodSignature, true, false, false, -1, start, end, 0, true, attributes);
} else {
// remove breakpoint
breakpointManager.removeBreakpoint(breakpoint, true);
}
}
}
}
/* (non-Javadoc)
* @see org.eclipse.debug.ui.actions.IToggleBreakpointsTarget#canToggleMethodBreakpoints(org.eclipse.ui.IWorkbenchPart, org.eclipse.jface.viewers.ISelection)
*/
public boolean canToggleMethodBreakpoints(IWorkbenchPart part, ISelection selection) {
if (selection instanceof IStructuredSelection) {
IStructuredSelection ss = (IStructuredSelection) selection;
return getMethods(ss).length > 0;
} else {
return selection instanceof ITextSelection;
}
}
protected IMethod[] getMethods(IStructuredSelection selection) {
if (selection.isEmpty()) {
return new IMethod[0];
} else {
List methods = new ArrayList(selection.size());
Iterator iterator = selection.iterator();
while (iterator.hasNext()) {
Object thing = iterator.next();
try {
if (thing instanceof IMethod && !Flags.isAbstract(((IMethod)thing).getFlags())) {
methods.add(thing);
}
} catch (JavaModelException e) {
}
}
return (IMethod[]) methods.toArray(new IMethod[methods.size()]);
}
}
protected IField[] getFields(IStructuredSelection selection) {
if (selection.isEmpty()) {
return new IField[0];
} else {
List fields = new ArrayList(selection.size());
Iterator iterator = selection.iterator();
while (iterator.hasNext()) {
Object thing = iterator.next();
if (thing instanceof IField) {
fields.add(thing);
} else if (thing instanceof IJavaFieldVariable) {
IField field= getField((IJavaFieldVariable) thing);
if (field != null) {
fields.add(field);
}
}
}
return (IField[]) fields.toArray(new IField[fields.size()]);
}
}
/* (non-Javadoc)
* @see org.eclipse.debug.ui.actions.IToggleBreakpointsTarget#toggleWatchpoints(org.eclipse.ui.IWorkbenchPart, org.eclipse.jface.viewers.ISelection)
*/
public void toggleWatchpoints(IWorkbenchPart part, ISelection selection) throws CoreException {
report(null, part);
selection = translateToMembers(part, selection);
if (selection instanceof ITextSelection) {
ITextSelection textSelection= (ITextSelection) selection;
CompilationUnit compilationUnit= parseCompilationUnit((ITextEditor)part);
if (compilationUnit != null) {
BreakpointFieldLocator locator= new BreakpointFieldLocator(textSelection.getOffset());
compilationUnit.accept(locator);
String fieldName= locator.getFieldName();
if (fieldName == null) {
report(ActionMessages.getString("ManageWatchpointActionDelegate.CantAdd"), part); //$NON-NLS-1$
return;
}
String typeName= locator.getTypeName();
// check if the watchpoint already exists. If yes, remove it
IBreakpointManager breakpointManager= DebugPlugin.getDefault().getBreakpointManager();
IBreakpoint[] breakpoints= breakpointManager.getBreakpoints(JDIDebugModel.getPluginIdentifier());
for (int i= 0; i < breakpoints.length; i++) {
IBreakpoint breakpoint= breakpoints[i];
if (breakpoint instanceof IJavaWatchpoint) {
IJavaWatchpoint watchpoint= (IJavaWatchpoint)breakpoint;
if (typeName.equals(watchpoint.getTypeName()) && fieldName.equals(watchpoint.getFieldName())) {
breakpointManager.removeBreakpoint(watchpoint, true);
return;
}
}
}
// add the watchpoint
JDIDebugModel.createWatchpoint(getResource((IEditorPart)part), typeName, fieldName, -1, -1, -1, 0, true, new HashMap(10));
}
} else if (selection instanceof IStructuredSelection) {
IField[] members = getFields((IStructuredSelection)selection);
if (members.length == 0) {
report(ActionMessages.getString("ToggleBreakpointAdapter.10"), part); //$NON-NLS-1$
return;
}
// add or remove watchpoint
IBreakpointManager breakpointManager= DebugPlugin.getDefault().getBreakpointManager();
for (int i= 0, length= members.length; i < length; i++) {
IField element= members[i];
IJavaBreakpoint breakpoint= getBreakpoint(element);
if (breakpoint == null) {
IType type = element.getDeclaringType();
int start = -1;
int end = -1;
ISourceRange range = element.getNameRange();
if (range != null) {
start = range.getOffset();
end = start + range.getLength();
}
Map attributes = new HashMap(10);
BreakpointUtils.addJavaBreakpointAttributes(attributes, element);
JDIDebugModel.createWatchpoint(BreakpointUtils.getBreakpointResource(type), type.getFullyQualifiedName(), element.getElementName(), -1, start, end, 0, true, attributes);
} else {
// remove breakpoint
breakpointManager.removeBreakpoint(breakpoint, true);
}
}
}
}
public static String resolveMethodSignature(IType type, String methodSignature) throws JavaModelException {
String[] parameterTypes= Signature.getParameterTypes(methodSignature);
int length= length= parameterTypes.length;
String[] resolvedParameterTypes= new String[length];
for (int i = 0; i < length; i++) {
resolvedParameterTypes[i]= resolveType(type, parameterTypes[i]);
if (resolvedParameterTypes[i] == null) {
return null;
}
}
String resolvedReturnType= resolveType(type, Signature.getReturnType(methodSignature));
if (resolvedReturnType == null) {
return null;
}
return Signature.createMethodSignature(resolvedParameterTypes, resolvedReturnType);
}
private static String resolveType(IType type, String typeSignature) throws JavaModelException {
int count= Signature.getArrayCount(typeSignature);
String elementTypeSignature= Signature.getElementType(typeSignature);
if (elementTypeSignature.length() == 1) {
// no need to resolve primitive types
return typeSignature;
}
String elementTypeName= Signature.toString(elementTypeSignature);
String[][] resolvedElementTypeNames= type.resolveType(elementTypeName);
if (resolvedElementTypeNames == null || resolvedElementTypeNames.length != 1) {
// the type name cannot be resolved
return null;
}
String resolvedElementTypeName= Signature.toQualifiedName(resolvedElementTypeNames[0]);
String resolvedElementTypeSignature= Signature.createTypeSignature(resolvedElementTypeName, true).replace('.', '/');
return Signature.createArraySignature(resolvedElementTypeSignature, count);
}
protected static IResource getResource(IEditorPart editor) {
IResource resource;
IEditorInput editorInput = editor.getEditorInput();
if (editorInput instanceof IFileEditorInput) {
resource= ((IFileEditorInput)editorInput).getFile();
} else {
resource= ResourcesPlugin.getWorkspace().getRoot();
}
return resource;
}
/**
* Returns a handle to the specified method or <code>null</code> if none.
*
* @param editorPart the editor containing the method
* @param typeName
* @param methodName
* @param signature
* @return handle or <code>null</code>
*/
protected IMethod getMethodHandle(IEditorPart editorPart, String typeName, String methodName, String signature) throws CoreException {
IJavaElement element = (IJavaElement) editorPart.getEditorInput().getAdapter(IJavaElement.class);
IType type = null;
if (element instanceof ICompilationUnit) {
IType[] types = ((ICompilationUnit)element).getAllTypes();
for (int i = 0; i < types.length; i++) {
if (types[i].getFullyQualifiedName().equals(typeName)) {
type = types[i];
break;
}
}
} else if (element instanceof IClassFile) {
type = ((IClassFile)element).getType();
}
if (type != null) {
String[] sigs = Signature.getParameterTypes(signature);
return type.getMethod(methodName, sigs);
}
return null;
}
protected IJavaBreakpoint getBreakpoint(IMember element) {
IBreakpointManager breakpointManager= DebugPlugin.getDefault().getBreakpointManager();
IBreakpoint[] breakpoints= breakpointManager.getBreakpoints(JDIDebugModel.getPluginIdentifier());
if (element instanceof IMethod) {
IMethod method= (IMethod)element;
for (int i= 0; i < breakpoints.length; i++) {
IBreakpoint breakpoint= breakpoints[i];
if (breakpoint instanceof IJavaMethodBreakpoint) {
IJavaMethodBreakpoint methodBreakpoint= (IJavaMethodBreakpoint)breakpoint;
IMember container = null;
try {
container= BreakpointUtils.getMember(methodBreakpoint);
} catch (CoreException e) {
JDIDebugUIPlugin.log(e);
return null;
}
if (container == null) {
try {
if (method.getDeclaringType().getFullyQualifiedName().equals(methodBreakpoint.getTypeName())
&& method.getElementName().equals(methodBreakpoint.getMethodName())
&& method.getSignature().equals(methodBreakpoint.getMethodSignature())) {
return methodBreakpoint;
}
} catch (CoreException e) {
JDIDebugUIPlugin.log(e);
}
} else {
if (container instanceof IMethod) {
if (method.getDeclaringType().getFullyQualifiedName().equals(container.getDeclaringType().getFullyQualifiedName())) {
if (method.isSimilar((IMethod)container)) {
return methodBreakpoint;
}
}
}
}
}
}
} else if (element instanceof IField) {
for (int i= 0; i < breakpoints.length; i++) {
IBreakpoint breakpoint= breakpoints[i];
if (breakpoint instanceof IJavaWatchpoint) {
try {
if (equalFields(element, (IJavaWatchpoint)breakpoint))
return (IJavaBreakpoint)breakpoint;
} catch (CoreException e) {
JDIDebugUIPlugin.log(e);
}
}
}
}
return null;
}
/**
* Compare two fields. The default <code>equals()</code>
* method for <code>IField</code> doesn't give the comparison desired.
*/
private boolean equalFields(IMember breakpointField, IJavaWatchpoint watchpoint) throws CoreException {
return (breakpointField.getElementName().equals(watchpoint.getFieldName()) &&
breakpointField.getDeclaringType().getFullyQualifiedName().equals(watchpoint.getTypeName()));
}
protected CompilationUnit parseCompilationUnit(ITextEditor editor) {
IEditorInput editorInput = editor.getEditorInput();
IDocument document= editor.getDocumentProvider().getDocument(editorInput);
ASTParser parser = ASTParser.newParser(AST.LEVEL_2_0);
parser.setSource(document.get().toCharArray());
return (CompilationUnit) parser.createAST(null);
}
/* (non-Javadoc)
* @see org.eclipse.debug.ui.actions.IToggleBreakpointsTarget#canToggleWatchpoints(org.eclipse.ui.IWorkbenchPart, org.eclipse.jface.viewers.ISelection)
*/
public boolean canToggleWatchpoints(IWorkbenchPart part, ISelection selection) {
if (selection instanceof IStructuredSelection) {
IStructuredSelection ss = (IStructuredSelection) selection;
return getFields(ss).length > 0;
} else {
return selection instanceof ITextSelection;
}
}
/**
* Returns a selection of the member in the given text selection,
* or the original selection if none.
*
* @param part
* @param selection
* @return a structured selection of the member in the given text selection,
* or the original selection if none
* @exception CoreException if an exceptoin occurrs
*/
protected ISelection translateToMembers(IWorkbenchPart part, ISelection selection) throws CoreException {
if (selection instanceof ITextSelection && part instanceof IEditorPart) {
ITextSelection textSelection = (ITextSelection)selection;
IEditorPart editorPart = (IEditorPart) part;
IEditorInput editorInput = editorPart.getEditorInput();
IMember m= null;
IClassFile classFile= (IClassFile)editorInput.getAdapter(IClassFile.class);
if (classFile != null) {
IJavaElement e= classFile.getElementAt(textSelection.getOffset());
if (e instanceof IMember) {
m= (IMember)e;
}
} else {
IWorkingCopyManager manager= JavaUI.getWorkingCopyManager();
ICompilationUnit unit= manager.getWorkingCopy(editorInput);
if (unit != null) {
synchronized (unit) {
unit.reconcile(ICompilationUnit.NO_AST /*don't create ast*/, false/*don't force problem detection*/, null/*use primary owner*/, null/*no progress monitor*/);
}
IJavaElement e = unit.getElementAt(textSelection.getOffset());
if (e instanceof IMember) {
m= (IMember)e;
}
}
}
if (m != null) {
return new StructuredSelection(m);
}
}
return selection;
}
/**
* Returns a list of matching types (IType - Java model) that correspond to the
* declaring type (ReferenceType - JDI model) of the given variable.
*/
protected static List searchForDeclaringType(IJavaFieldVariable variable) {
List types= new ArrayList();
ILaunch launch = variable.getDebugTarget().getLaunch();
if (launch == null) {
return types;
}
ILaunchConfiguration configuration= launch.getLaunchConfiguration();
IJavaProject[] javaProjects = null;
IWorkspace workspace= ResourcesPlugin.getWorkspace();
if (configuration != null) {
// Launch configuration support
try {
String projectName= configuration.getAttribute(IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME, ""); //$NON-NLS-1$
if (projectName.length() != 0) {
javaProjects= new IJavaProject[] {JavaCore.create(workspace.getRoot().getProject(projectName))};
} else {
IProject[] projects= ResourcesPlugin.getWorkspace().getRoot().getProjects();
IProject project;
List projectList= new ArrayList();
for (int i= 0, numProjects= projects.length; i < numProjects; i++) {
project= projects[i];
if (project.isAccessible() && project.hasNature(JavaCore.NATURE_ID)) {
projectList.add(JavaCore.create(project));
}
}
javaProjects= new IJavaProject[projectList.size()];
projectList.toArray(javaProjects);
}
} catch (CoreException e) {
JDIDebugUIPlugin.log(e);
}
}
if (javaProjects == null) {
return types;
}
SearchEngine engine= new SearchEngine();
IJavaSearchScope scope= SearchEngine.createJavaSearchScope(javaProjects, true);
String declaringType= null;
try {
declaringType= variable.getDeclaringType().getName();
} catch (DebugException x) {
JDIDebugUIPlugin.log(x);
return types;
}
ArrayList typeRefsFound= new ArrayList(3);
ITypeNameRequestor requestor= new TypeInfoRequestor(typeRefsFound);
try {
engine.searchAllTypeNames(workspace,
getPackage(declaringType),
getTypeName(declaringType),
IJavaSearchConstants.EXACT_MATCH,
true,
IJavaSearchConstants.CLASS,
scope,
requestor,
IJavaSearchConstants.WAIT_UNTIL_READY_TO_SEARCH,
null);
} catch (JavaModelException x) {
JDIDebugUIPlugin.log(x);
return types;
}
Iterator iter= typeRefsFound.iterator();
TypeInfo typeInfo= null;
while (iter.hasNext()) {
typeInfo= (TypeInfo)iter.next();
try {
types.add(typeInfo.resolveType(scope));
} catch (JavaModelException jme) {
JDIDebugUIPlugin.log(jme);
}
}
return types;
}
/**
* Returns the package name of the given fully qualified type name.
* The package name is assumed to be the dot-separated prefix of the
* type name.
*/
protected static char[] getPackage(String fullyQualifiedName) {
int index= fullyQualifiedName.lastIndexOf('.');
if (index == -1) {
return new char[0];
}
return fullyQualifiedName.substring(0, index).toCharArray();
}
/**
* Returns a simple type name from the given fully qualified type name.
* The type name is assumed to be the last contiguous segment of the
* fullyQualifiedName not containing a '.' or '$'
*/
protected static char[] getTypeName(String fullyQualifiedName) {
int index= fullyQualifiedName.lastIndexOf('.');
String typeName= fullyQualifiedName.substring(index + 1);
int lastInnerClass= typeName.lastIndexOf('$');
if (lastInnerClass != -1) {
typeName= typeName.substring(lastInnerClass + 1);
}
return typeName.toCharArray();
}
/**
* Return the associated IField (Java model) for the given
* IJavaFieldVariable (JDI model)
*/
private IField getField(IJavaFieldVariable variable) {
String varName= null;
try {
varName= variable.getName();
} catch (DebugException x) {
JDIDebugUIPlugin.log(x);
return null;
}
IField field;
List types= searchForDeclaringType(variable);
Iterator iter= types.iterator();
while (iter.hasNext()) {
IType type= (IType)iter.next();
field= type.getField(varName);
if (field.exists()) {
return field;
}
}
return null;
}
}