diff options
Diffstat (limited to 'java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression')
2 files changed, 34 insertions, 10 deletions
diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/EvaluatorBuilderImpl.java b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/EvaluatorBuilderImpl.java index 45af0e10ac72..83ad91b4e27d 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/EvaluatorBuilderImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/EvaluatorBuilderImpl.java @@ -40,6 +40,7 @@ import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.tree.IElementType; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiTypesUtil; +import com.intellij.psi.util.PsiUtil; import com.intellij.psi.util.TypeConversionUtil; import com.intellij.util.IncorrectOperationException; import com.sun.jdi.Value; @@ -1036,7 +1037,8 @@ public class EvaluatorBuilderImpl implements EvaluatorBuilder { final PsiType castType = expression.getCastType().getType(); final PsiType operandType = operandExpr.getType(); - if (castType != null && operandType != null && !TypeConversionUtil.areTypesConvertible(operandType, castType)) { + // if operand type can not be resolved in current context - leave it for runtime checks + if (castType != null && operandType != null && !TypeConversionUtil.areTypesConvertible(operandType, castType) && PsiUtil.resolveClassInType(operandType) != null) { throw new EvaluateRuntimeException( new EvaluateException(JavaErrorMessages.message("inconvertible.type.cast", JavaHighlightUtil.formatType(operandType), JavaHighlightUtil .formatType(castType))) diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/MethodEvaluator.java b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/MethodEvaluator.java index 2569559d2d11..6ba88653749b 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/MethodEvaluator.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/MethodEvaluator.java @@ -21,21 +21,19 @@ package com.intellij.debugger.engine.evaluation.expression; import com.intellij.debugger.DebuggerBundle; +import com.intellij.debugger.engine.DebugProcess; import com.intellij.debugger.engine.DebugProcessImpl; import com.intellij.debugger.engine.DebuggerUtils; import com.intellij.debugger.engine.JVMName; -import com.intellij.debugger.engine.evaluation.EvaluateException; -import com.intellij.debugger.engine.evaluation.EvaluateExceptionUtil; -import com.intellij.debugger.engine.evaluation.EvaluateRuntimeException; -import com.intellij.debugger.engine.evaluation.EvaluationContextImpl; +import com.intellij.debugger.engine.evaluation.*; import com.intellij.debugger.impl.DebuggerUtilsEx; +import com.intellij.debugger.jdi.VirtualMachineProxyImpl; import com.intellij.openapi.diagnostic.Logger; -import com.sun.jdi.ClassType; -import com.sun.jdi.Method; -import com.sun.jdi.ObjectReference; -import com.sun.jdi.ReferenceType; +import com.intellij.rt.debugger.DefaultMethodInvoker; +import com.sun.jdi.*; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; public class MethodEvaluator implements Evaluator { @@ -149,7 +147,13 @@ public class MethodEvaluator implements Evaluator { if (requiresSuperObject) { return debugProcess.invokeInstanceMethod(context, objRef, jdiMethod, args, ObjectReference.INVOKE_NONVIRTUAL); } - return debugProcess.invokeMethod(context, objRef, jdiMethod, args); + // fix for default methods in interfaces, see IDEA-124066 + if (Boolean.valueOf(System.getProperty("debugger.invoke.default")) && jdiMethod.declaringType() instanceof InterfaceType) { + return invokeDefaultMethod(debugProcess, context, objRef, myMethodName); + } + else { + return debugProcess.invokeMethod(context, objRef, jdiMethod, args); + } } catch (Exception e) { if (LOG.isDebugEnabled()) { @@ -158,4 +162,22 @@ public class MethodEvaluator implements Evaluator { throw EvaluateExceptionUtil.createEvaluateException(e); } } + + // only methods without arguments for now + private static Value invokeDefaultMethod(DebugProcess debugProcess, EvaluationContext evaluationContext, + Value obj, String name) + throws EvaluateException, ClassNotLoadedException, InvalidTypeException { + ClassType invokerClass = (ClassType)debugProcess.findClass( + evaluationContext, DefaultMethodInvoker.class.getName(), + evaluationContext.getClassLoader()); + + if (invokerClass != null) { + List<Method> methods = invokerClass.methodsByName("invoke"); + if (!methods.isEmpty()) { + return debugProcess.invokeMethod(evaluationContext, invokerClass, methods.get(0), + Arrays.asList(obj, ((VirtualMachineProxyImpl)debugProcess.getVirtualMachineProxy()).mirrorOf(name))); + } + } + return null; + } } |