package jetbrains.mps.debugger.java.api.evaluation;
/*Generated by MPS */
import org.apache.log4j.Logger;
import org.apache.log4j.LogManager;
import com.sun.jdi.Value;
import com.sun.jdi.ArrayReference;
import org.jetbrains.annotations.NotNull;
import com.sun.jdi.Field;
import com.sun.jdi.ClassType;
import java.util.List;
import com.sun.jdi.Method;
import com.sun.jdi.ReferenceType;
import com.sun.jdi.VirtualMachine;
import org.jetbrains.annotations.Nullable;
import com.sun.jdi.Type;
import jetbrains.mps.debugger.java.api.evaluation.proxies.IValueProxy;
import com.sun.jdi.StackFrame;
import jetbrains.mps.debugger.java.api.evaluation.proxies.IObjectValueProxy;
import com.sun.jdi.ThreadReference;
import jetbrains.mps.debugger.java.api.evaluation.proxies.IArrayValueProxy;
import jetbrains.mps.debugger.java.api.evaluation.proxies.PrimitiveValueProxy;
import com.sun.jdi.InvocationException;
import com.sun.jdi.InvalidTypeException;
import com.sun.jdi.IncompatibleThreadStateException;
import org.apache.log4j.Level;
import com.sun.jdi.ClassNotLoadedException;
public abstract class EvaluationUtils {
private static final Logger LOG = LogManager.getLogger(EvaluationUtils.class);
protected static EvaluationUtils INSTANCE;
protected static final Object LOCK = new Object();
public static final String JAVA_LANG_OBJECT = "Ljava/lang/Object;";
public EvaluationUtils() {
}
public abstract void init();
public abstract void dispose();
public abstract Value getArrayElementAt(ArrayReference array, int index);
@NotNull
public abstract Field findField(ClassType referenceType, String fieldName) throws InvalidEvaluatedExpressionException;
public abstract List<Field> findFields(ClassType referenceType);
@NotNull
public abstract Method findConstructor(ClassType referenceType, String jniSignature) throws InvalidEvaluatedExpressionException;
@NotNull
public abstract Method findMethod(ClassType referenceType, String methodsName, String jniSignature) throws InvalidEvaluatedExpressionException;
@NotNull
public abstract ReferenceType findClassType(String className, VirtualMachine virtualMachine) throws InvalidEvaluatedExpressionException;
@Nullable
public abstract ReferenceType findClassTypeSilently(String className, VirtualMachine virtualMachine) throws InvalidEvaluatedExpressionException;
@Nullable
public abstract Type findTypeSilently(String className, VirtualMachine virtualMachine) throws InvalidEvaluatedExpressionException;
public abstract boolean instanceOf(final Type what, final String jniSignature, final VirtualMachine machine) throws EvaluationException;
@NotNull
public abstract IValueProxy getVariableValue(String varName, StackFrame stackFrame) throws EvaluationException;
@NotNull
public abstract <T extends IValueProxy> Iterable<T> toIterableProxy(IObjectValueProxy valueProxy, ThreadReference threadReference);
@NotNull
public abstract <T extends IValueProxy> Iterable<T> toIterableProxyFromArray(IArrayValueProxy valueProxy);
@NotNull
public abstract IValueProxy invokeStaticMethod(String className, String name, String jniSignature, ThreadReference threadReference, Object... args) throws EvaluationException;
@NotNull
public abstract IValueProxy getStaticField(String className, String fieldName, VirtualMachine machine) throws InvalidEvaluatedExpressionException;
@NotNull
public abstract IObjectValueProxy invokeConstructorProxy(String className, String jniSignature, ThreadReference threadReference, Object... args) throws EvaluationException;
public abstract IArrayValueProxy createArrayProxy(String className, VirtualMachine machine, int size) throws EvaluationException;
public abstract IArrayValueProxy createArrayProxyFromValues(String className, VirtualMachine machine, Object... args) throws EvaluationException;
@NotNull
public abstract IValueProxy getClass(String className, VirtualMachine machine) throws InvalidEvaluatedExpressionException;
@NotNull
public abstract IObjectValueProxy boxValue(PrimitiveValueProxy primitiveValueProxy, ThreadReference threadReference) throws EvaluationException;
public abstract PrimitiveValueProxy unboxValue(IObjectValueProxy valueProxy, ThreadReference threadReference) throws EvaluationException;
public abstract String getStringPresentation(@NotNull Value value, ThreadReference reference);
public static EvaluationUtils getInstance() {
synchronized (LOCK) {
return INSTANCE;
}
}
/**
* Do something and convert jdi exceptions to evaluation exception
*
* @param invocatable what to invoke
* @param <T> result
* @throws EvaluationException wrapper of the original exception
* @return result
*/
public static <T> T handleInvocationExceptions(EvaluationUtils.Invocatable<T> invocatable) throws EvaluationException {
try {
return invocatable.invoke();
} catch (InvocationException e) {
if (invocatable instanceof EvaluationUtils.ThreadInvocatable) {
throw new TargetVMEvaluationException(e, ((EvaluationUtils.ThreadInvocatable) invocatable).getCurrentThreadReference());
} else {
throw new TargetVMEvaluationException(e);
}
} catch (IllegalArgumentException e) {
throw new InvalidEvaluatedExpressionException(e);
} catch (InvalidTypeException e) {
throw new InvalidEvaluatedExpressionException(e);
} catch (RuntimeException e) {
if (e.getClass().getName().startsWith("com.sun.jdi")) {
throw new JdiRuntimeExceptionEvaluationException(e);
}
throw new EvaluationRuntimeException(e);
} catch (IncompatibleThreadStateException e) {
if (invocatable instanceof EvaluationUtils.ThreadInvocatable) {
throw new EvaluationException("Incompatible thread " + ((EvaluationUtils.ThreadInvocatable) invocatable).getCurrentThreadReference().name(), e);
} else {
throw new EvaluationException(e);
}
} catch (Throwable t) {
throw new EvaluationException(t);
}
}
/**
* When we need to call something from ui which throws evaluation exception.
* For example when we update the tree.
*
* @param invocatable the action to invoke
* @param failure value to return in case of failure
* @param <T> result
* @return result
*/
public static <T> T consumeEvaluationException(EvaluationUtils.EvaluationInvocatable<T> invocatable, T failure) {
try {
return invocatable.invoke();
} catch (InvalidEvaluatedExpressionException e) {
if (LOG.isEnabledFor(Level.WARN)) {
LOG.warn("", e);
}
} catch (InvocationTargetEvaluationException e) {
if (LOG.isEnabledFor(Level.WARN)) {
LOG.warn("", e);
}
} catch (TargetVMEvaluationException e) {
if (LOG.isEnabledFor(Level.WARN)) {
LOG.warn("", e);
}
} catch (JdiRuntimeExceptionEvaluationException e) {
if (LOG.isInfoEnabled()) {
LOG.info("", e);
}
} catch (EvaluationException e) {
if (LOG.isDebugEnabled()) {
LOG.debug("", e);
}
}
return failure;
}
/**
* Something that can throw one of jdi exceptions or EvaluationException
*
* @param <T> result
*/
public interface Invocatable<T> {
T invoke() throws InvocationException, InvalidTypeException, ClassNotLoadedException, IncompatibleThreadStateException, EvaluationException;
}
/**
* Something that can throw EvaluationException
*
* @param <T> result
*/
public interface EvaluationInvocatable<T> {
T invoke() throws EvaluationException;
}
/**
* Some action which also has information about thread reference where it happenes.
*
* @param <T> result
*/
public static abstract class ThreadInvocatable<T> implements EvaluationUtils.Invocatable<T> {
private final ThreadReference myThreadReference;
public ThreadInvocatable(ThreadReference threadReference) {
myThreadReference = threadReference;
}
public ThreadReference getCurrentThreadReference() {
return myThreadReference;
}
}
}