summaryrefslogtreecommitdiff
path: root/java/debugger/impl/src/com/intellij/debugger/engine
diff options
context:
space:
mode:
Diffstat (limited to 'java/debugger/impl/src/com/intellij/debugger/engine')
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/engine/JavaDebuggerEvaluator.java10
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/engine/JavaExecutionStack.java39
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/engine/JavaStackFrame.java2
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/engine/JavaValue.java43
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/EvaluatorBuilderImpl.java4
-rw-r--r--java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/MethodEvaluator.java40
6 files changed, 92 insertions, 46 deletions
diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/JavaDebuggerEvaluator.java b/java/debugger/impl/src/com/intellij/debugger/engine/JavaDebuggerEvaluator.java
index e37576bae8f4..f2178c1d4fb5 100644
--- a/java/debugger/impl/src/com/intellij/debugger/engine/JavaDebuggerEvaluator.java
+++ b/java/debugger/impl/src/com/intellij/debugger/engine/JavaDebuggerEvaluator.java
@@ -15,6 +15,7 @@
*/
package com.intellij.debugger.engine;
+import com.intellij.debugger.engine.evaluation.EvaluateException;
import com.intellij.debugger.engine.evaluation.EvaluationContextImpl;
import com.intellij.debugger.engine.evaluation.TextWithImportsImpl;
import com.intellij.debugger.engine.events.DebuggerContextCommandImpl;
@@ -73,9 +74,16 @@ public class JavaDebuggerEvaluator extends XDebuggerEvaluator {
callback.errorOccurred("Context is not available");
return;
}
+ descriptor.setContext(evalContext);
+ @SuppressWarnings("ThrowableResultOfMethodCallIgnored")
+ EvaluateException exception = descriptor.getEvaluateException();
+ if (exception != null) {
+ callback.errorOccurred(exception.getMessage());
+ return;
+ }
JavaDebugProcess process = myDebugProcess.getXdebugProcess();
if (process != null) {
- callback.evaluated(JavaValue.create(descriptor, evalContext, process.getNodeManager()));
+ callback.evaluated(JavaValue.create(null, descriptor, evalContext, process.getNodeManager(), true));
}
}
});
diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/JavaExecutionStack.java b/java/debugger/impl/src/com/intellij/debugger/engine/JavaExecutionStack.java
index f2cb40008ad5..1bd95096055f 100644
--- a/java/debugger/impl/src/com/intellij/debugger/engine/JavaExecutionStack.java
+++ b/java/debugger/impl/src/com/intellij/debugger/engine/JavaExecutionStack.java
@@ -17,7 +17,6 @@ package com.intellij.debugger.engine;
import com.intellij.debugger.DebuggerBundle;
import com.intellij.debugger.engine.evaluation.EvaluateException;
-import com.intellij.debugger.engine.events.DebuggerCommandImpl;
import com.intellij.debugger.engine.events.DebuggerContextCommandImpl;
import com.intellij.debugger.engine.events.SuspendContextCommandImpl;
import com.intellij.debugger.impl.DebuggerUtilsEx;
@@ -46,7 +45,7 @@ public class JavaExecutionStack extends XExecutionStack {
private final DebugProcessImpl myDebugProcess;
private final NodeManagerImpl myNodeManager;
private volatile JavaStackFrame myTopFrame;
- private boolean myTopFrameReady = false;
+ private volatile boolean myTopFrameReady = false;
private final MethodsTracker myTracker = new MethodsTracker();
public JavaExecutionStack(@NotNull ThreadReferenceProxyImpl threadProxy, @NotNull DebugProcessImpl debugProcess, boolean current) {
@@ -99,25 +98,7 @@ public class JavaExecutionStack extends XExecutionStack {
@Nullable
@Override
public JavaStackFrame getTopFrame() {
- if (!myTopFrameReady) {
- //TODO: remove sync calculation
- if (DebuggerManagerThreadImpl.isManagerThread()) {
- myTopFrame = calcTopFrame();
- }
- else {
- myDebugProcess.getManagerThread().invokeAndWait(new DebuggerCommandImpl() {
- @Override
- public Priority getPriority() {
- return Priority.HIGH;
- }
-
- @Override
- protected void action() throws Exception {
- myTopFrame = calcTopFrame();
- }
- });
- }
- }
+ assert myTopFrameReady : "Top frame must be already calculated here";
return myTopFrame;
}
@@ -183,8 +164,20 @@ public class JavaExecutionStack extends XExecutionStack {
@Override
public void contextAction() throws Exception {
if (myStackFramesIterator.hasNext()) {
- JavaStackFrame frame = new JavaStackFrame(myStackFramesIterator.next(), myDebugProcess, myTracker, myNodeManager);
- if (DebuggerSettings.getInstance().SHOW_LIBRARY_STACKFRAMES || (!frame.getDescriptor().isSynthetic() && !frame.getDescriptor().isInLibraryContent())) {
+ JavaStackFrame frame;
+ boolean first = myAdded == 0;
+ if (first && myTopFrameReady) {
+ frame = myTopFrame;
+ myStackFramesIterator.next();
+ }
+ else {
+ frame = new JavaStackFrame(myStackFramesIterator.next(), myDebugProcess, myTracker, myNodeManager);
+ if (first && !myTopFrameReady) {
+ myTopFrame = frame;
+ myTopFrameReady = true;
+ }
+ }
+ if (first || DebuggerSettings.getInstance().SHOW_LIBRARY_STACKFRAMES || (!frame.getDescriptor().isSynthetic() && !frame.getDescriptor().isInLibraryContent())) {
if (++myAdded > mySkip) {
myContainer.addStackFrames(Arrays.asList(frame), false);
}
diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/JavaStackFrame.java b/java/debugger/impl/src/com/intellij/debugger/engine/JavaStackFrame.java
index 3f649e2b1dab..e7db635abe13 100644
--- a/java/debugger/impl/src/com/intellij/debugger/engine/JavaStackFrame.java
+++ b/java/debugger/impl/src/com/intellij/debugger/engine/JavaStackFrame.java
@@ -370,7 +370,7 @@ public class JavaStackFrame extends XStackFrame {
ArgumentValueDescriptorImpl descriptor = myNodeManager.getArgumentValueDescriptor(null, index, value, name);
// setContext is required to calculate correct name
descriptor.setContext(evaluationContext);
- return JavaValue.create(descriptor, evaluationContext, myNodeManager);
+ return JavaValue.create(null, descriptor, evaluationContext, myNodeManager, true);
}
protected void superBuildVariables(final EvaluationContextImpl evaluationContext, XValueChildrenList children) throws EvaluateException {
diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/JavaValue.java b/java/debugger/impl/src/com/intellij/debugger/engine/JavaValue.java
index 9cfb2bfde84e..7b0ffffe98d5 100644
--- a/java/debugger/impl/src/com/intellij/debugger/engine/JavaValue.java
+++ b/java/debugger/impl/src/com/intellij/debugger/engine/JavaValue.java
@@ -17,6 +17,7 @@ package com.intellij.debugger.engine;
import com.intellij.debugger.DebuggerInvocationUtil;
import com.intellij.debugger.SourcePosition;
+import com.intellij.debugger.actions.JavaReferringObjectsValue;
import com.intellij.debugger.actions.JumpToObjectAction;
import com.intellij.debugger.engine.evaluation.EvaluateException;
import com.intellij.debugger.engine.evaluation.EvaluationContextImpl;
@@ -66,27 +67,34 @@ public class JavaValue extends XNamedValue implements NodeDescriptorProvider, XV
private final ValueDescriptorImpl myValueDescriptor;
private final EvaluationContextImpl myEvaluationContext;
private final NodeManagerImpl myNodeManager;
+ private final boolean myContextSet;
- private JavaValue(JavaValue parent,
+ protected JavaValue(JavaValue parent,
@NotNull ValueDescriptorImpl valueDescriptor,
@NotNull EvaluationContextImpl evaluationContext,
- NodeManagerImpl nodeManager) {
+ NodeManagerImpl nodeManager,
+ boolean contextSet) {
super(valueDescriptor.getName());
myParent = parent;
myValueDescriptor = valueDescriptor;
myEvaluationContext = evaluationContext;
myNodeManager = nodeManager;
+ myContextSet = contextSet;
}
- private static JavaValue create(JavaValue parent, @NotNull ValueDescriptorImpl valueDescriptor, EvaluationContextImpl evaluationContext, NodeManagerImpl nodeManager, boolean init) {
+ static JavaValue create(JavaValue parent,
+ @NotNull ValueDescriptorImpl valueDescriptor,
+ EvaluationContextImpl evaluationContext,
+ NodeManagerImpl nodeManager,
+ boolean contextSet) {
DebuggerManagerThreadImpl.assertIsManagerThread();
- return new JavaValue(parent, valueDescriptor, evaluationContext, nodeManager);
+ return new JavaValue(parent, valueDescriptor, evaluationContext, nodeManager, contextSet);
}
- public static JavaValue create(@NotNull ValueDescriptorImpl valueDescriptor,
+ static JavaValue create(@NotNull ValueDescriptorImpl valueDescriptor,
EvaluationContextImpl evaluationContext,
NodeManagerImpl nodeManager) {
- return create(null, valueDescriptor, evaluationContext, nodeManager, true);
+ return create(null, valueDescriptor, evaluationContext, nodeManager, false);
}
public JavaValue getParent() {
@@ -113,7 +121,9 @@ public class JavaValue extends XNamedValue implements NodeDescriptorProvider, XV
@Override
public void threadAction() {
- myValueDescriptor.setContext(myEvaluationContext);
+ if (!myContextSet) {
+ myValueDescriptor.setContext(myEvaluationContext);
+ }
myValueDescriptor.updateRepresentation(myEvaluationContext, new DescriptorLabelListener() {
@Override
public void labelChanged() {
@@ -123,12 +133,12 @@ public class JavaValue extends XNamedValue implements NodeDescriptorProvider, XV
String type = strings[0];
XValuePresentation presentation;
if (myValueDescriptor.isString()) {
- presentation = new TypedStringValuePresentation(StringUtil.unquoteString(value), type);
+ presentation = new TypedStringValuePresentation(value, type);
}
else {
EvaluateException exception = myValueDescriptor.getEvaluateException();
if (myValueDescriptor.getLastRenderer() instanceof ToStringRenderer && exception == null) {
- presentation = new XRegularValuePresentation(StringUtil.wrapWithDoubleQuote(value), type);
+ presentation = new XRegularValuePresentation(StringUtil.wrapWithDoubleQuote(value.substring(0,Math.min(value.length(), XValueNode.MAX_VALUE_LENGTH))), type);
}
else {
presentation = new JavaValuePresentation(value, type, exception != null ? exception.getMessage() : null);
@@ -339,15 +349,16 @@ public class JavaValue extends XNamedValue implements NodeDescriptorProvider, XV
ApplicationManager.getApplication().runReadAction(new Runnable() {
@Override
public void run() {
+ final boolean nearest = navigatable instanceof XNearestSourcePosition;
if (myValueDescriptor instanceof FieldDescriptorImpl) {
- SourcePosition position = ((FieldDescriptorImpl)myValueDescriptor).getSourcePosition(getProject(), getDebuggerContext());
+ SourcePosition position = ((FieldDescriptorImpl)myValueDescriptor).getSourcePosition(getProject(), getDebuggerContext(), nearest);
if (position != null) {
navigatable.setSourcePosition(DebuggerUtilsEx.toXSourcePosition(position));
}
}
if (myValueDescriptor instanceof LocalVariableDescriptorImpl) {
SourcePosition position =
- ((LocalVariableDescriptorImpl)myValueDescriptor).getSourcePosition(getProject(), getDebuggerContext());
+ ((LocalVariableDescriptorImpl)myValueDescriptor).getSourcePosition(getProject(), getDebuggerContext(), nearest);
if (position != null) {
navigatable.setSourcePosition(DebuggerUtilsEx.toXSourcePosition(position));
}
@@ -442,4 +453,14 @@ public class JavaValue extends XNamedValue implements NodeDescriptorProvider, XV
public String getValueText() {
return myValueDescriptor.getValueText();
}
+ @Nullable
+ @Override
+ public XReferrersProvider getReferrersProvider() {
+ return new XReferrersProvider() {
+ @Override
+ public XValue getReferringObjectsValue() {
+ return new JavaReferringObjectsValue(JavaValue.this, false);
+ }
+ };
+ }
}
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;
+ }
}