mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-165155 Java conditional breakpoint on expression or single-line lambda does not give access to lambda parameters
This commit is contained in:
@@ -25,6 +25,7 @@ import com.intellij.debugger.impl.DebuggerUtilsEx;
|
||||
import com.intellij.debugger.jdi.VirtualMachineProxyImpl;
|
||||
import com.intellij.debugger.requests.ClassPrepareRequestor;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.ReadAction;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.project.Project;
|
||||
@@ -203,18 +204,26 @@ public class PositionManagerImpl implements PositionManager, MultiRequestPositio
|
||||
return new JavaSourcePosition(sourcePosition, location.declaringType(), method, lambdaOrdinal);
|
||||
}
|
||||
|
||||
private static class JavaSourcePosition extends RemappedSourcePosition {
|
||||
public static class JavaSourcePosition extends RemappedSourcePosition {
|
||||
private final String myExpectedClassName;
|
||||
private final String myExpectedMethodName;
|
||||
private final int myLambdaOrdinal;
|
||||
|
||||
public JavaSourcePosition(SourcePosition delegate, ReferenceType declaringType, Method method, int lambdaOrdinal) {
|
||||
public JavaSourcePosition(@NotNull SourcePosition delegate, ReferenceType declaringType, Method method, int lambdaOrdinal) {
|
||||
super(delegate);
|
||||
myExpectedClassName = declaringType != null ? declaringType.name() : null;
|
||||
myExpectedMethodName = method != null ? method.name() : null;
|
||||
myLambdaOrdinal = lambdaOrdinal;
|
||||
}
|
||||
|
||||
public JavaSourcePosition(@NotNull SourcePosition delegate, int lambdaOrdinal) {
|
||||
super(delegate);
|
||||
assert lambdaOrdinal > -1;
|
||||
myExpectedClassName = null;
|
||||
myExpectedMethodName = "lambda$"; // fake lambda name
|
||||
myLambdaOrdinal = lambdaOrdinal;
|
||||
}
|
||||
|
||||
private PsiElement remapElement(PsiElement element) {
|
||||
String name = JVMNameUtil.getClassVMName(getEnclosingClass(element));
|
||||
if (name != null && !name.equals(myExpectedClassName)) {
|
||||
@@ -244,37 +253,34 @@ public class PositionManagerImpl implements PositionManager, MultiRequestPositio
|
||||
|
||||
@Override
|
||||
public SourcePosition mapDelegate(final SourcePosition original) {
|
||||
return ApplicationManager.getApplication().runReadAction(new Computable<SourcePosition>() {
|
||||
@Override
|
||||
public SourcePosition compute() {
|
||||
PsiFile file = original.getFile();
|
||||
int line = original.getLine();
|
||||
if (DebuggerUtilsEx.isLambdaName(myExpectedMethodName) && myLambdaOrdinal > -1) {
|
||||
List<PsiLambdaExpression> lambdas = DebuggerUtilsEx.collectLambdas(original, true);
|
||||
return ReadAction.compute(() -> {
|
||||
PsiFile file = original.getFile();
|
||||
int line = original.getLine();
|
||||
if (DebuggerUtilsEx.isLambdaName(myExpectedMethodName) && myLambdaOrdinal > -1) {
|
||||
List<PsiLambdaExpression> lambdas = DebuggerUtilsEx.collectLambdas(original, true);
|
||||
|
||||
Document document = PsiDocumentManager.getInstance(file.getProject()).getDocument(file);
|
||||
if (document == null || line >= document.getLineCount()) {
|
||||
return original;
|
||||
}
|
||||
if (myLambdaOrdinal < lambdas.size()) {
|
||||
PsiElement firstElem = DebuggerUtilsEx.getFirstElementOnTheLine(lambdas.get(myLambdaOrdinal), document, line);
|
||||
if (firstElem != null) {
|
||||
return SourcePosition.createFromElement(firstElem);
|
||||
}
|
||||
Document document = PsiDocumentManager.getInstance(file.getProject()).getDocument(file);
|
||||
if (document == null || line >= document.getLineCount()) {
|
||||
return original;
|
||||
}
|
||||
if (myLambdaOrdinal < lambdas.size()) {
|
||||
PsiElement firstElem = DebuggerUtilsEx.getFirstElementOnTheLine(lambdas.get(myLambdaOrdinal), document, line);
|
||||
if (firstElem != null) {
|
||||
return SourcePosition.createFromElement(firstElem);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// There may be more than one class/method code on the line, so we need to find out the correct place
|
||||
for (PsiElement elem : getLineElements(file, line)) {
|
||||
PsiElement remappedElement = remapElement(elem);
|
||||
if (remappedElement != null) {
|
||||
if (remappedElement.getTextOffset() <= original.getOffset()) break;
|
||||
return SourcePosition.createFromElement(remappedElement);
|
||||
}
|
||||
}
|
||||
}
|
||||
return original;
|
||||
}
|
||||
else {
|
||||
// There may be more than one class/method code on the line, so we need to find out the correct place
|
||||
for (PsiElement elem : getLineElements(file, line)) {
|
||||
PsiElement remappedElement = remapElement(elem);
|
||||
if (remappedElement != null) {
|
||||
if (remappedElement.getTextOffset() <= original.getOffset()) break;
|
||||
return SourcePosition.createFromElement(remappedElement);
|
||||
}
|
||||
}
|
||||
}
|
||||
return original;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
* Copyright 2000-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -28,7 +28,7 @@ abstract class RemappedSourcePosition extends SourcePosition {
|
||||
private SourcePosition myDelegate;
|
||||
private boolean myMapped = false;
|
||||
|
||||
public RemappedSourcePosition(SourcePosition delegate) {
|
||||
public RemappedSourcePosition(@NotNull SourcePosition delegate) {
|
||||
myDelegate = delegate;
|
||||
}
|
||||
|
||||
|
||||
@@ -761,6 +761,20 @@ public abstract class DebuggerUtilsEx extends DebuggerUtils {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static SourcePosition toSourcePosition(@Nullable XSourcePosition position, Project project) {
|
||||
if (position != null) {
|
||||
if (position instanceof JavaXSourcePosition) {
|
||||
return ((JavaXSourcePosition)position).mySourcePosition;
|
||||
}
|
||||
PsiFile psiFile = PsiManager.getInstance(project).findFile(position.getFile());
|
||||
if (psiFile != null) {
|
||||
return SourcePosition.createFromLine(psiFile, position.getLine());
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static class JavaXSourcePosition implements XSourcePosition, ExecutionPointHighlighter.HighlighterProvider {
|
||||
private final SourcePosition mySourcePosition;
|
||||
@NotNull private final VirtualFile myFile;
|
||||
|
||||
+5
-9
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2016 JetBrains s.r.o.
|
||||
* Copyright 2000-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -23,6 +23,7 @@ import com.intellij.debugger.engine.JVMNameUtil;
|
||||
import com.intellij.debugger.engine.events.DebuggerCommandImpl;
|
||||
import com.intellij.debugger.engine.requests.RequestManagerImpl;
|
||||
import com.intellij.debugger.impl.DebuggerContextImpl;
|
||||
import com.intellij.debugger.impl.DebuggerUtilsEx;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
@@ -235,14 +236,9 @@ public abstract class BreakpointWithHighlighter<P extends JavaBreakpointProperti
|
||||
@Override
|
||||
public void reload() {
|
||||
ApplicationManager.getApplication().assertReadAccessAllowed();
|
||||
XSourcePosition position = myXBreakpoint.getSourcePosition();
|
||||
PsiFile psiFile = getPsiFile();
|
||||
if (position != null && psiFile != null) {
|
||||
mySourcePosition = SourcePosition.createFromLine(psiFile, position.getLine());
|
||||
reload(psiFile);
|
||||
}
|
||||
else {
|
||||
mySourcePosition = null;
|
||||
mySourcePosition = DebuggerUtilsEx.toSourcePosition(myXBreakpoint.getSourcePosition(), myProject);
|
||||
if (mySourcePosition != null) {
|
||||
reload(mySourcePosition.getFile());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+43
-15
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2016 JetBrains s.r.o.
|
||||
* Copyright 2000-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -18,6 +18,7 @@ package com.intellij.debugger.ui.breakpoints;
|
||||
import com.intellij.debugger.DebuggerBundle;
|
||||
import com.intellij.debugger.HelpID;
|
||||
import com.intellij.debugger.SourcePosition;
|
||||
import com.intellij.debugger.engine.PositionManagerImpl;
|
||||
import com.intellij.debugger.impl.DebuggerUtilsEx;
|
||||
import com.intellij.icons.AllIcons;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
@@ -33,6 +34,7 @@ import com.intellij.xdebugger.breakpoints.XBreakpoint;
|
||||
import com.intellij.xdebugger.breakpoints.XLineBreakpoint;
|
||||
import com.intellij.xdebugger.breakpoints.ui.XBreakpointGroupingRule;
|
||||
import com.intellij.xdebugger.impl.XSourcePositionImpl;
|
||||
import com.intellij.xdebugger.impl.breakpoints.XLineBreakpointImpl;
|
||||
import org.jetbrains.annotations.Nls;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -99,12 +101,11 @@ public class JavaLineBreakpointType extends JavaLineBreakpointTypeBase<JavaLineB
|
||||
@NotNull
|
||||
@Override
|
||||
public List<JavaBreakpointVariant> computeVariants(@NotNull Project project, @NotNull XSourcePosition position) {
|
||||
PsiFile file = PsiManager.getInstance(project).findFile(position.getFile());
|
||||
if (file == null) {
|
||||
SourcePosition pos = DebuggerUtilsEx.toSourcePosition(position, project);
|
||||
if (pos == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
SourcePosition pos = SourcePosition.createFromLine(file, position.getLine());
|
||||
List<PsiLambdaExpression> lambdas = DebuggerUtilsEx.collectLambdas(pos, true);
|
||||
if (lambdas.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
@@ -116,7 +117,7 @@ public class JavaLineBreakpointType extends JavaLineBreakpointTypeBase<JavaLineB
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
Document document = PsiDocumentManager.getInstance(file.getProject()).getDocument(file);
|
||||
Document document = PsiDocumentManager.getInstance(project).getDocument(pos.getFile());
|
||||
if (document == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
@@ -246,22 +247,49 @@ public class JavaLineBreakpointType extends JavaLineBreakpointTypeBase<JavaLineB
|
||||
@Nullable
|
||||
@Override
|
||||
public TextRange getHighlightRange(XLineBreakpoint<JavaLineBreakpointProperties> breakpoint) {
|
||||
JavaLineBreakpointProperties properties = breakpoint.getProperties();
|
||||
if (properties != null) {
|
||||
Integer ordinal = properties.getLambdaOrdinal();
|
||||
if (ordinal != null) {
|
||||
Breakpoint javaBreakpoint = BreakpointManager.getJavaBreakpoint(breakpoint);
|
||||
if (javaBreakpoint instanceof LineBreakpoint) {
|
||||
PsiElement method = getContainingMethod((LineBreakpoint)javaBreakpoint);
|
||||
if (method != null) {
|
||||
return method.getTextRange();
|
||||
}
|
||||
Integer ordinal = getLambdaOrdinal(breakpoint);
|
||||
if (ordinal != null) {
|
||||
Breakpoint javaBreakpoint = BreakpointManager.getJavaBreakpoint(breakpoint);
|
||||
if (javaBreakpoint instanceof LineBreakpoint) {
|
||||
PsiElement method = getContainingMethod((LineBreakpoint)javaBreakpoint);
|
||||
if (method != null) {
|
||||
return method.getTextRange();
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public XSourcePosition getSourcePosition(@NotNull XBreakpoint<JavaLineBreakpointProperties> breakpoint) {
|
||||
Integer ordinal = getLambdaOrdinal(breakpoint);
|
||||
if (ordinal != null && ordinal > -1) {
|
||||
SourcePosition linePosition = createLineSourcePosition((XLineBreakpointImpl)breakpoint);
|
||||
if (linePosition != null) {
|
||||
return DebuggerUtilsEx.toXSourcePosition(new PositionManagerImpl.JavaSourcePosition(linePosition, ordinal));
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static Integer getLambdaOrdinal(XBreakpoint<JavaLineBreakpointProperties> breakpoint) {
|
||||
JavaLineBreakpointProperties properties = breakpoint.getProperties();
|
||||
return properties != null ? properties.getLambdaOrdinal() : null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static SourcePosition createLineSourcePosition(XLineBreakpointImpl breakpoint) {
|
||||
VirtualFile file = breakpoint.getFile();
|
||||
if (file != null) {
|
||||
PsiFile psiFile = PsiManager.getInstance(breakpoint.getProject()).findFile(file);
|
||||
if (psiFile != null) {
|
||||
return SourcePosition.createFromLine(psiFile, breakpoint.getLine());
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canBeHitInOtherPlaces() {
|
||||
return true; // line breakpoints could be hit in other versions of the same classes
|
||||
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2016 JetBrains s.r.o.
|
||||
* Copyright 2000-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -76,10 +76,10 @@ public abstract class XLineBreakpointType<P extends XBreakpointProperties> exten
|
||||
}
|
||||
|
||||
/**
|
||||
* Source position for line breakpoint is determined by its file and line
|
||||
* Source position for line breakpoint by default is determined by its file and line
|
||||
*/
|
||||
@Override
|
||||
public final XSourcePosition getSourcePosition(@NotNull XBreakpoint<P> breakpoint) {
|
||||
public XSourcePosition getSourcePosition(@NotNull XBreakpoint<P> breakpoint) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
+7
-10
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2016 JetBrains s.r.o.
|
||||
* Copyright 2000-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -17,8 +17,6 @@ package com.intellij.xdebugger.impl.breakpoints;
|
||||
|
||||
import com.intellij.openapi.actionSystem.AnAction;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.ReadAction;
|
||||
import com.intellij.openapi.application.Result;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.colors.EditorColorsManager;
|
||||
import com.intellij.openapi.editor.colors.EditorColorsScheme;
|
||||
@@ -148,7 +146,7 @@ public class XLineBreakpointImpl<P extends XBreakpointProperties> extends XBreak
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private VirtualFile getFile() {
|
||||
public VirtualFile getFile() {
|
||||
return VirtualFileManager.getInstance().findFileByUrl(getFileUrl());
|
||||
}
|
||||
|
||||
@@ -191,13 +189,12 @@ public class XLineBreakpointImpl<P extends XBreakpointProperties> extends XBreak
|
||||
|
||||
@Override
|
||||
public XSourcePosition getSourcePosition() {
|
||||
if (mySourcePosition != null) {
|
||||
return mySourcePosition;
|
||||
}
|
||||
mySourcePosition = super.getSourcePosition();
|
||||
if (mySourcePosition == null) {
|
||||
new ReadAction() {
|
||||
@Override
|
||||
protected void run(@NotNull Result result) {
|
||||
mySourcePosition = XDebuggerUtil.getInstance().createPosition(getFile(), getLine());
|
||||
}
|
||||
}.execute();
|
||||
mySourcePosition = XDebuggerUtil.getInstance().createPosition(getFile(), getLine());
|
||||
}
|
||||
return mySourcePosition;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user