blob: 880653d05b83bb6dedfd05e139096bf70874052a [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2015 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
* Jesper Steen Møller <jesper@selskabet.org> - Bug 430839
*******************************************************************************/
package org.eclipse.jdt.internal.debug.core.model;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.debug.core.DebugException;
import org.eclipse.jdt.debug.core.IJavaClassType;
import org.eclipse.jdt.debug.core.IJavaInterfaceType;
import org.eclipse.jdt.debug.core.IJavaObject;
import org.eclipse.jdt.debug.core.IJavaThread;
import org.eclipse.jdt.debug.core.IJavaValue;
import com.ibm.icu.text.MessageFormat;
import com.sun.jdi.ClassType;
import com.sun.jdi.InterfaceType;
import com.sun.jdi.Method;
import com.sun.jdi.ObjectReference;
import com.sun.jdi.Value;
/**
* The class of an object in a debug target.
*/
public class JDIClassType extends JDIReferenceType implements IJavaClassType {
/**
* Constructs a new class type on the given target referencing the specified
* class type.
*/
public JDIClassType(JDIDebugTarget target, ClassType type) {
super(target, type);
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.jdt.debug.core.IJavaClassType#newInstance(java.lang.String,
* org.eclipse.jdt.debug.core.IJavaValue[],
* org.eclipse.jdt.debug.core.IJavaThread)
*/
@Override
public IJavaObject newInstance(String signature, IJavaValue[] args,
IJavaThread thread) throws DebugException {
if (getUnderlyingType() instanceof ClassType) {
ClassType clazz = (ClassType) getUnderlyingType();
JDIThread javaThread = (JDIThread) thread;
List<Value> arguments = convertArguments(args);
Method method = null;
try {
List<Method> methods = clazz.methodsByName("<init>", signature); //$NON-NLS-1$
if (methods.isEmpty()) {
requestFailed(
MessageFormat.format(
JDIDebugModelMessages.JDIClassType_Type_does_not_implement_cosntructor,
signature), null);
} else {
method = methods.get(0);
}
} catch (RuntimeException e) {
targetRequestFailed(
MessageFormat.format(
JDIDebugModelMessages.JDIClassType_exception_while_performing_method_lookup_for_constructor,
e.toString(), signature), e);
}
ObjectReference result = javaThread.newInstance(clazz, method,
arguments);
return (IJavaObject) JDIValue.createValue(getJavaDebugTarget(),
result);
}
requestFailed(
JDIDebugModelMessages.JDIClassType_Type_is_not_a_class_type,
null);
// execution will not fall through to here,
// as #requestFailed will throw an exception
return null;
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.jdt.debug.core.IJavaClassType#sendMessage(java.lang.String,
* java.lang.String, org.eclipse.jdt.debug.core.IJavaValue[],
* org.eclipse.jdt.debug.core.IJavaThread)
*/
@Override
public IJavaValue sendMessage(String selector, String signature,
IJavaValue[] args, IJavaThread thread) throws DebugException {
if (getUnderlyingType() instanceof ClassType) {
ClassType clazz = (ClassType) getUnderlyingType();
JDIThread javaThread = (JDIThread) thread;
List<Value> arguments = convertArguments(args);
Method method = null;
try {
List<Method> methods = clazz.methodsByName(selector, signature);
if (methods.isEmpty()) {
requestFailed(
MessageFormat.format(
JDIDebugModelMessages.JDIClassType_Type_does_not_implement_selector,
selector, signature), null);
} else {
method = methods.get(0);
}
} catch (RuntimeException e) {
targetRequestFailed(
MessageFormat.format(
JDIDebugModelMessages.JDIClassType_exception_while_performing_method_lookup_for_selector,
e.toString(), selector, signature), e);
}
Value result = javaThread.invokeMethod(clazz, null, method,
arguments, false);
return JDIValue.createValue(getJavaDebugTarget(), result);
}
requestFailed(
JDIDebugModelMessages.JDIClassType_Type_is_not_a_class_type,
null);
// execution will not fall through to here,
// as #requestFailed will throw an exception
return null;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.jdt.debug.core.IJavaClassType#getSuperclass()
*/
@Override
public IJavaClassType getSuperclass() throws DebugException {
try {
ClassType superclazz = ((ClassType) getUnderlyingType())
.superclass();
if (superclazz != null) {
return (IJavaClassType) JDIType.createType(
getJavaDebugTarget(), superclazz);
}
} catch (RuntimeException e) {
targetRequestFailed(
MessageFormat.format(
JDIDebugModelMessages.JDIClassType_exception_while_retrieving_superclass,
e.toString()), e);
}
// it is possible to return null
return null;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.jdt.debug.core.IJavaClassType#getAllInterfaces()
*/
@Override
public IJavaInterfaceType[] getAllInterfaces() throws DebugException {
try {
List<InterfaceType> interfaceList = ((ClassType) getUnderlyingType())
.allInterfaces();
List<JDIType> javaInterfaceTypeList = new ArrayList<>(interfaceList.size());
for(InterfaceType interfaceType : interfaceList) {
if (interfaceType != null) {
javaInterfaceTypeList.add(JDIType.createType(
getJavaDebugTarget(), interfaceType));
}
}
IJavaInterfaceType[] javaInterfaceTypeArray = new IJavaInterfaceType[javaInterfaceTypeList
.size()];
javaInterfaceTypeArray = javaInterfaceTypeList
.toArray(javaInterfaceTypeArray);
return javaInterfaceTypeArray;
} catch (RuntimeException re) {
targetRequestFailed(
MessageFormat.format(
JDIDebugModelMessages.JDIClassType_exception_while_retrieving_superclass,
re.toString()), re);
}
return new IJavaInterfaceType[0];
}
/*
* (non-Javadoc)
*
* @see org.eclipse.jdt.debug.core.IJavaClassType#getInterfaces()
*/
@Override
public IJavaInterfaceType[] getInterfaces() throws DebugException {
try {
List<InterfaceType> interfaceList = ((ClassType) getUnderlyingType()).interfaces();
List<JDIType> javaInterfaceTypeList = new ArrayList<>(interfaceList.size());
for(InterfaceType interfaceType : interfaceList) {
if (interfaceType != null) {
javaInterfaceTypeList.add(JDIType.createType(
getJavaDebugTarget(), interfaceType));
}
}
IJavaInterfaceType[] javaInterfaceTypeArray = new IJavaInterfaceType[javaInterfaceTypeList
.size()];
javaInterfaceTypeArray = javaInterfaceTypeList
.toArray(javaInterfaceTypeArray);
return javaInterfaceTypeArray;
} catch (RuntimeException re) {
targetRequestFailed(
MessageFormat.format(
JDIDebugModelMessages.JDIClassType_exception_while_retrieving_superclass,
re.toString()), re);
}
return new IJavaInterfaceType[0];
}
/*
* (non-Javadoc)
*
* @see org.eclipse.jdt.debug.core.IJavaClassType#isEnum()
*/
@Override
public boolean isEnum() {
return ((ClassType) getReferenceType()).isEnum();
}
}