IDEA-131134 Support multiple breakpoints within on single line dbe/142.2551
authorEgor.Ushakov <egor.ushakov@jetbrains.com>
Wed, 17 Jun 2015 14:44:38 +0000 (17:44 +0300)
committerEgor.Ushakov <egor.ushakov@jetbrains.com>
Wed, 17 Jun 2015 14:46:16 +0000 (17:46 +0300)
java/debugger/impl/src/com/intellij/debugger/impl/DebuggerUtilsEx.java
java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaLineBreakpointType.java
java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/LineBreakpoint.java
java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/properties/JavaLineBreakpointProperties.java
platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/XLineBreakpointType.java
platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XLineBreakpointImpl.java

index 608e43c9adb92b61a1b93d3de43f56c6415acf45..ac4db1dff4e8be0dc154cf898a7105f038804bf0 100644 (file)
@@ -788,7 +788,7 @@ public abstract class DebuggerUtilsEx extends DebuggerUtils {
     return null;
   }
 
-  public static List<PsiLambdaExpression> collectLambdas(SourcePosition position, final boolean onlyOnTheLine) {
+  public static List<PsiLambdaExpression> collectLambdas(@NotNull SourcePosition position, final boolean onlyOnTheLine) {
     ApplicationManager.getApplication().assertReadAccessAllowed();
     PsiFile file = position.getFile();
     int line = position.getLine();
@@ -849,6 +849,13 @@ public abstract class DebuggerUtilsEx extends DebuggerUtils {
     return body;
   }
 
+  public static boolean inTheMethod(@NotNull SourcePosition pos, @NotNull PsiElement method) {
+    PsiElement elem = pos.getElementAt();
+    if (elem == null) return false;
+    NavigatablePsiElement elemMethod = PsiTreeUtil.getParentOfType(elem, PsiMethod.class, PsiLambdaExpression.class);
+    return Comparing.equal(elemMethod, method);
+  }
+
   public static boolean inTheSameMethod(@NotNull SourcePosition pos1, @NotNull SourcePosition pos2) {
     ApplicationManager.getApplication().assertReadAccessAllowed();
     PsiElement elem1 = pos1.getElementAt();
index bd1faa161d38a8ab1fb6002ad1b834f95f65ee89..29d6ff4aac046dcb0bb8af187b2b618d9384b6ab 100644 (file)
@@ -117,12 +117,13 @@ public class JavaLineBreakpointType extends JavaLineBreakpointTypeBase<JavaLineB
     res.add(new JavaBreakpointVariant(position)); //all
 
     if (startMethod instanceof PsiMethod) {
-      res.add(new ExactJavaBreakpointVariant(position, startMethod)); // base method
+      res.add(new ExactJavaBreakpointVariant(position, startMethod, -1)); // base method
     }
 
+    int ordinal = 0;
     for (PsiLambdaExpression lambda : lambdas) { //lambdas
       PsiElement firstElem = DebuggerUtilsEx.getFirstElementOnTheLine(lambda, document, position.getLine());
-      res.add(new ExactJavaBreakpointVariant(XSourcePositionImpl.createByElement(firstElem), lambda));
+      res.add(new ExactJavaBreakpointVariant(XSourcePositionImpl.createByElement(firstElem), lambda, ordinal++));
     }
 
     return res;
@@ -159,10 +160,12 @@ public class JavaLineBreakpointType extends JavaLineBreakpointTypeBase<JavaLineB
 
   private class ExactJavaBreakpointVariant extends JavaBreakpointVariant {
     private final PsiElement myElement;
+    private final Integer myLambdaOrdinal;
 
-    public ExactJavaBreakpointVariant(XSourcePosition position, PsiElement element) {
+    public ExactJavaBreakpointVariant(XSourcePosition position, PsiElement element, Integer lambdaOrdinal) {
       super(position);
       myElement = element;
+      myLambdaOrdinal = lambdaOrdinal;
     }
 
     @Override
@@ -183,22 +186,24 @@ public class JavaLineBreakpointType extends JavaLineBreakpointTypeBase<JavaLineB
     @Override
     public JavaLineBreakpointProperties createProperties() {
       JavaLineBreakpointProperties properties = super.createProperties();
-      properties.setOffset(mySourcePosition.getOffset());
+      properties.setLambdaOrdinal(myLambdaOrdinal);
       return properties;
     }
   }
 
   @Nullable
   @Override
-  public TextRange getHighlightRange(JavaLineBreakpointProperties properties, Document document, Project project) {
-    Integer offset = properties.getOffset();
-    if (offset != null) {
-      PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(document);
-      if (file != null) {
-        PsiElement elem = file.findElementAt(offset);
-        NavigatablePsiElement method = PsiTreeUtil.getParentOfType(elem, PsiMethod.class, PsiLambdaExpression.class);
-        if (method != null) {
-          return method.getTextRange();
+  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 = ((LineBreakpoint)javaBreakpoint).getContainingMethod();
+          if (method != null) {
+            return method.getTextRange();
+          }
         }
       }
     }
index 8cf083f49710d99f66b3786f127709a69de1ba5b..03b277e676d7520eea5d40b29ea40984bebea43e 100644 (file)
@@ -210,21 +210,35 @@ public class LineBreakpoint extends BreakpointWithHighlighter {
       @Override
       public Boolean compute() {
         if (getProperties() instanceof JavaLineBreakpointProperties) {
-          Integer offset = ((JavaLineBreakpointProperties)getProperties()).getOffset();
-          if (offset == null) return true;
-          PsiFile file = getPsiFile();
-          if (file != null) {
-            SourcePosition exactPosition = SourcePosition.createFromOffset(file, offset);
-            SourcePosition position = debugProcess.getPositionManager().getSourcePosition(loc);
-            if (position == null) return false;
-            return DebuggerUtilsEx.inTheSameMethod(exactPosition, position);
-          }
+          Integer ordinal = ((JavaLineBreakpointProperties)getProperties()).getLambdaOrdinal();
+          if (ordinal == null) return true;
+          PsiElement containingMethod = getContainingMethod();
+          if (containingMethod == null) return false;
+          SourcePosition position = debugProcess.getPositionManager().getSourcePosition(loc);
+          if (position == null) return false;
+          return DebuggerUtilsEx.inTheMethod(position, containingMethod);
         }
         return true;
       }
     });
   }
 
+  @Nullable
+  public PsiElement getContainingMethod() {
+    SourcePosition position = getSourcePosition();
+    if (position == null) return null;
+    if (getProperties() instanceof JavaLineBreakpointProperties) {
+      Integer ordinal = ((JavaLineBreakpointProperties)getProperties()).getLambdaOrdinal();
+      if (ordinal > -1) {
+        List<PsiLambdaExpression> lambdas = DebuggerUtilsEx.collectLambdas(position, true);
+        if (ordinal < lambdas.size()) {
+          return lambdas.get(ordinal);
+        }
+      }
+    }
+    return PsiTreeUtil.getParentOfType(position.getElementAt(), PsiMethod.class, PsiLambdaExpression.class);
+  }
+
   private boolean isInScopeOf(DebugProcessImpl debugProcess, String className) {
     final SourcePosition position = getSourcePosition();
     if (position != null) {
index 1ddf268f589529096d130d0d001de569b879dfab..f33e37c9f289a88384c26169f54e5a79c6b8b04b 100644 (file)
@@ -21,14 +21,17 @@ import com.intellij.util.xmlb.annotations.OptionTag;
  * @author egor
  */
 public class JavaLineBreakpointProperties extends JavaBreakpointProperties<JavaLineBreakpointProperties> {
-  private Integer myOffset = null;
+  // null - stop at all positions on the line
+  // -1 - stop only at the base position (first on the line)
+  // 0 or more - index of the lambda on the line to stop at
+  private Integer myLambdaOrdinal = null;
 
-  @OptionTag("offset")
-  public Integer getOffset() {
-    return myOffset;
+  @OptionTag("lambda-ordinal")
+  public Integer getLambdaOrdinal() {
+    return myLambdaOrdinal;
   }
 
-  public void setOffset(Integer offset) {
-    myOffset = offset;
+  public void setLambdaOrdinal(Integer lambdaOrdinal) {
+    myLambdaOrdinal = lambdaOrdinal;
   }
 }
index 814fb0d7da12a36aa2888058eb5fadcb32bb0ea2..32e35eded48e3ca123ae210e362395d00fc1dae3 100644 (file)
@@ -18,7 +18,6 @@ package com.intellij.xdebugger.breakpoints;
 
 import com.intellij.icons.AllIcons;
 import com.intellij.openapi.actionSystem.AnAction;
-import com.intellij.openapi.editor.Document;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.util.TextRange;
 import com.intellij.openapi.vfs.VirtualFile;
@@ -123,7 +122,7 @@ public abstract class XLineBreakpointType<P extends XBreakpointProperties> exten
    * @return range to highlight on the line, null to highlight the whole line
    */
   @Nullable
-  public TextRange getHighlightRange(P properties, Document document, Project project) {
+  public TextRange getHighlightRange(XLineBreakpoint<P> breakpoint) {
     return null;
   }
 
index e86404b887faf2dd7ed3a9bc2797f86028a89cd0..2674a8c334f32156923e460ec03bbd1f8d9dce0a 100644 (file)
@@ -103,7 +103,7 @@ public class XLineBreakpointImpl<P extends XBreakpointProperties> extends XBreak
     MarkupModelEx markupModel;
     if (highlighter == null) {
       markupModel = (MarkupModelEx)DocumentMarkupModel.forDocument(document, getProject(), true);
-      TextRange range = myType.getHighlightRange(getProperties(), document, getProject());
+      TextRange range = myType.getHighlightRange(this);
       if (range != null && !range.isEmpty()) {
         range = range.intersection(DocumentUtil.getLineTextRange(document, getLine()));
         if (range != null && !range.isEmpty()) {