2 * Copyright 2000-2015 JetBrains s.r.o.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package com.intellij.debugger.ui.breakpoints;
18 import com.intellij.debugger.DebuggerBundle;
19 import com.intellij.debugger.HelpID;
20 import com.intellij.debugger.SourcePosition;
21 import com.intellij.debugger.impl.DebuggerUtilsEx;
22 import com.intellij.openapi.editor.Document;
23 import com.intellij.openapi.project.Project;
24 import com.intellij.openapi.util.TextRange;
25 import com.intellij.openapi.util.text.StringUtil;
26 import com.intellij.openapi.vfs.VirtualFile;
27 import com.intellij.psi.*;
28 import com.intellij.util.SmartList;
29 import com.intellij.xdebugger.XDebuggerUtil;
30 import com.intellij.xdebugger.XSourcePosition;
31 import com.intellij.xdebugger.breakpoints.XBreakpoint;
32 import com.intellij.xdebugger.breakpoints.XLineBreakpoint;
33 import com.intellij.xdebugger.breakpoints.ui.XBreakpointGroupingRule;
34 import com.intellij.xdebugger.impl.XSourcePositionImpl;
35 import org.jetbrains.annotations.NotNull;
36 import org.jetbrains.annotations.Nullable;
37 import org.jetbrains.java.debugger.breakpoints.properties.JavaLineBreakpointProperties;
40 import java.util.Collections;
41 import java.util.List;
44 * Base class for java line-connected exceptions (line, method, field)
47 public class JavaLineBreakpointType extends JavaLineBreakpointTypeBase<JavaLineBreakpointProperties> implements JavaBreakpointType {
48 public JavaLineBreakpointType() {
49 super("java-line", DebuggerBundle.message("line.breakpoints.tab.title"));
53 protected String getHelpID() {
54 return HelpID.LINE_BREAKPOINTS;
58 public String getDisplayName() {
59 return DebuggerBundle.message("line.breakpoints.tab.title");
63 public List<XBreakpointGroupingRule<XLineBreakpoint<JavaLineBreakpointProperties>, ?>> getGroupingRules() {
64 return XDebuggerUtil.getInstance().getGroupingByFileRuleAsList();
69 public JavaLineBreakpointProperties createProperties() {
70 return new JavaLineBreakpointProperties();
75 public JavaLineBreakpointProperties createBreakpointProperties(@NotNull VirtualFile file, int line) {
76 return new JavaLineBreakpointProperties();
81 public Breakpoint createJavaBreakpoint(Project project, XBreakpoint breakpoint) {
82 return new LineBreakpoint(project, breakpoint);
86 public int getPriority() {
92 public List<JavaBreakpointVariant> computeVariants(@NotNull Project project, @NotNull XSourcePosition position) {
93 PsiFile file = PsiManager.getInstance(project).findFile(position.getFile());
95 return Collections.emptyList();
98 SourcePosition pos = SourcePosition.createFromLine(file, position.getLine());
99 List<PsiLambdaExpression> lambdas = DebuggerUtilsEx.collectLambdas(pos, true);
100 if (lambdas.isEmpty()) {
101 return Collections.emptyList();
104 PsiElement startMethod = DebuggerUtilsEx.getContainingMethod(pos);
105 //noinspection SuspiciousMethodCalls
106 if (lambdas.contains(startMethod) && lambdas.size() == 1) {
107 return Collections.emptyList();
110 Document document = PsiDocumentManager.getInstance(file.getProject()).getDocument(file);
111 if (document == null) {
112 return Collections.emptyList();
115 List<JavaBreakpointVariant> res = new SmartList<JavaBreakpointVariant>();
116 res.add(new JavaBreakpointVariant(position)); //all
118 if (startMethod instanceof PsiMethod) {
119 res.add(new ExactJavaBreakpointVariant(position, startMethod, -1)); // base method
123 for (PsiLambdaExpression lambda : lambdas) { //lambdas
124 PsiElement firstElem = DebuggerUtilsEx.getFirstElementOnTheLine(lambda, document, position.getLine());
125 res.add(new ExactJavaBreakpointVariant(XSourcePositionImpl.createByElement(firstElem), lambda, ordinal++));
131 class JavaBreakpointVariant extends XLineBreakpointVariant {
132 protected final XSourcePosition mySourcePosition;
134 private JavaBreakpointVariant(XSourcePosition position) {
135 mySourcePosition = position;
139 public String getText() {
144 public Icon getIcon() {
149 public TextRange getHighlightRange() {
154 public JavaLineBreakpointProperties createProperties() {
155 return createBreakpointProperties(mySourcePosition.getFile(),
156 mySourcePosition.getLine());
160 private class ExactJavaBreakpointVariant extends JavaBreakpointVariant {
161 private final PsiElement myElement;
162 private final Integer myLambdaOrdinal;
164 public ExactJavaBreakpointVariant(XSourcePosition position, PsiElement element, Integer lambdaOrdinal) {
167 myLambdaOrdinal = lambdaOrdinal;
171 public Icon getIcon() {
172 return myElement.getIcon(0);
176 public String getText() {
177 return StringUtil.shortenTextWithEllipsis(myElement.getText(), 100, 0);
181 public TextRange getHighlightRange() {
182 return myElement.getTextRange();
186 public JavaLineBreakpointProperties createProperties() {
187 JavaLineBreakpointProperties properties = super.createProperties();
188 properties.setLambdaOrdinal(myLambdaOrdinal);
195 public TextRange getHighlightRange(XLineBreakpoint<JavaLineBreakpointProperties> breakpoint) {
196 JavaLineBreakpointProperties properties = breakpoint.getProperties();
197 if (properties != null) {
198 Integer ordinal = properties.getLambdaOrdinal();
199 if (ordinal != null) {
200 Breakpoint javaBreakpoint = BreakpointManager.getJavaBreakpoint(breakpoint);
201 if (javaBreakpoint instanceof LineBreakpoint) {
202 PsiElement method = ((LineBreakpoint)javaBreakpoint).getContainingMethod();
203 if (method != null) {
204 return method.getTextRange();