mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-139741 Support position highlighting of exact lambda/method
This commit is contained in:
@@ -26,11 +26,12 @@ import com.intellij.execution.filters.LineNumbersMapping;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.impl.DocumentMarkupModel;
|
||||
import com.intellij.openapi.editor.markup.HighlighterTargetArea;
|
||||
import com.intellij.openapi.editor.markup.RangeHighlighter;
|
||||
import com.intellij.openapi.editor.markup.TextAttributes;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.openapi.util.NullableComputable;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.openapi.util.*;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.*;
|
||||
@@ -38,6 +39,8 @@ import com.intellij.psi.search.FilenameIndex;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.util.containers.EmptyIterable;
|
||||
import com.intellij.xdebugger.impl.ui.ExecutionPointHighlighter;
|
||||
import com.intellij.xdebugger.ui.DebuggerColors;
|
||||
import com.sun.jdi.AbsentInformationException;
|
||||
import com.sun.jdi.Location;
|
||||
import com.sun.jdi.Method;
|
||||
@@ -179,7 +182,7 @@ public class PositionManagerImpl implements PositionManager, MultiRequestPositio
|
||||
return new JavaSourcePosition(SourcePosition.createFromLine(psiFile, lineNumber), location.declaringType(), location.method());
|
||||
}
|
||||
|
||||
private static class JavaSourcePosition extends RemappedSourcePosition {
|
||||
private static class JavaSourcePosition extends RemappedSourcePosition implements ExecutionPointHighlighter.HighlighterProvider {
|
||||
private final String myExpectedClassName;
|
||||
private final String myExpectedMethodName;
|
||||
|
||||
@@ -189,31 +192,63 @@ public class PositionManagerImpl implements PositionManager, MultiRequestPositio
|
||||
myExpectedMethodName = method != null ? method.name() : null;
|
||||
}
|
||||
|
||||
private PsiElement remapElement(PsiElement element) {
|
||||
PsiClass aClass = getEnclosingClass(element);
|
||||
if (!Comparing.equal(myExpectedClassName, JVMNameUtil.getClassVMName(aClass))) {
|
||||
return null;
|
||||
}
|
||||
NavigatablePsiElement method = PsiTreeUtil.getParentOfType(element, PsiMethod.class, PsiLambdaExpression.class);
|
||||
if (!StringUtil.isEmpty(myExpectedMethodName)) {
|
||||
if (method == null) {
|
||||
return null;
|
||||
}
|
||||
else if ((method instanceof PsiMethod && myExpectedMethodName.equals(((PsiMethod)method).getName()))) {
|
||||
return element;
|
||||
}
|
||||
else if (method instanceof PsiLambdaExpression && myExpectedMethodName.startsWith(LambdaMethodFilter.LAMBDA_METHOD_PREFIX)) {
|
||||
return ((PsiLambdaExpression)method).getBody();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SourcePosition mapDelegate(final SourcePosition original) {
|
||||
return ApplicationManager.getApplication().runReadAction(new Computable<SourcePosition>() {
|
||||
@Override
|
||||
public SourcePosition compute() {
|
||||
// There may be more than one class/method code on the line, so we need to find out the correct place
|
||||
int lineNumber = original.getLine();
|
||||
PsiElement element = original.getElementAt();
|
||||
PsiClass aClass = getEnclosingClass(element);
|
||||
if (aClass != null) {
|
||||
if (Comparing.equal(myExpectedClassName, JVMNameUtil.getClassVMName(aClass))) {
|
||||
return original;
|
||||
}
|
||||
//try to look for other elements in the line
|
||||
PsiFile file = original.getFile();
|
||||
for (PsiElement elem : getLineElements(file, lineNumber)) {
|
||||
if (Comparing.equal(myExpectedClassName, JVMNameUtil.getClassVMName(getEnclosingClass(elem)))) {
|
||||
return SourcePosition.createFromElement(elem);
|
||||
}
|
||||
for (PsiElement elem : getLineElements(original.getFile(), original.getLine())) {
|
||||
PsiElement remappedElement = remapElement(elem);
|
||||
if (remappedElement != null) {
|
||||
if (remappedElement.getTextOffset() <= original.getOffset()) break;
|
||||
return SourcePosition.createFromElement(remappedElement);
|
||||
}
|
||||
}
|
||||
return original;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public RangeHighlighter createHighlighter(Document document, Project project, TextAttributes attributes) {
|
||||
PsiElement element = getElementAt();
|
||||
NavigatablePsiElement method = PsiTreeUtil.getParentOfType(element, PsiMethod.class, PsiLambdaExpression.class);
|
||||
if (method instanceof PsiLambdaExpression) {
|
||||
TextRange range = method.getTextRange();
|
||||
int startOffset = document.getLineStartOffset(getLine());
|
||||
int endOffset = document.getLineEndOffset(getLine());
|
||||
int hlStart = Math.max(startOffset, range.getStartOffset());
|
||||
int hlEnd = Math.min(endOffset, range.getEndOffset());
|
||||
if (hlStart != startOffset || hlEnd != endOffset) {
|
||||
return DocumentMarkupModel.forDocument(document, project, true).
|
||||
addRangeHighlighter(hlStart, hlEnd, DebuggerColors.EXECUTION_LINE_HIGHLIGHTERLAYER, attributes,
|
||||
HighlighterTargetArea.EXACT_RANGE);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static Iterable<PsiElement> getLineElements(final PsiFile file, int lineNumber) {
|
||||
|
||||
@@ -43,7 +43,10 @@ import com.intellij.openapi.actionSystem.DataContext;
|
||||
import com.intellij.openapi.actionSystem.DefaultActionGroup;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.markup.RangeHighlighter;
|
||||
import com.intellij.openapi.editor.markup.TextAttributes;
|
||||
import com.intellij.openapi.fileTypes.FileType;
|
||||
import com.intellij.openapi.fileTypes.StdFileTypes;
|
||||
import com.intellij.openapi.project.Project;
|
||||
@@ -62,6 +65,7 @@ import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.xdebugger.XSourcePosition;
|
||||
import com.intellij.xdebugger.frame.XValueNode;
|
||||
import com.intellij.xdebugger.impl.XSourcePositionImpl;
|
||||
import com.intellij.xdebugger.impl.ui.ExecutionPointHighlighter;
|
||||
import com.sun.jdi.*;
|
||||
import com.sun.jdi.event.Event;
|
||||
import com.sun.jdi.event.EventSet;
|
||||
@@ -696,7 +700,7 @@ public abstract class DebuggerUtilsEx extends DebuggerUtils {
|
||||
return new JavaXSourcePosition(position, file);
|
||||
}
|
||||
|
||||
private static class JavaXSourcePosition implements XSourcePosition {
|
||||
private static class JavaXSourcePosition implements XSourcePosition, ExecutionPointHighlighter.HighlighterProvider {
|
||||
private final SourcePosition mySourcePosition;
|
||||
@NotNull private final VirtualFile myFile;
|
||||
|
||||
@@ -726,6 +730,15 @@ public abstract class DebuggerUtilsEx extends DebuggerUtils {
|
||||
public Navigatable createNavigatable(@NotNull Project project) {
|
||||
return XSourcePositionImpl.doCreateOpenFileDescriptor(project, this);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public RangeHighlighter createHighlighter(Document document, Project project, TextAttributes attributes) {
|
||||
if (mySourcePosition instanceof ExecutionPointHighlighter.HighlighterProvider) {
|
||||
return ((ExecutionPointHighlighter.HighlighterProvider)mySourcePosition).createHighlighter(document, project, attributes);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user