inline debugger: fixed slow variables tree update due to lots of sourcePosition requests in the debugger thread, also do not show fields values at the declaration for not "this" objects

This commit is contained in:
Egor.Ushakov
2014-11-14 21:04:25 +03:00
parent ac50ae9714
commit d45fb3f672
9 changed files with 84 additions and 75 deletions
@@ -34,19 +34,15 @@ import com.intellij.debugger.ui.tree.render.ClassRenderer;
import com.intellij.debugger.ui.tree.render.DescriptorLabelListener;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.pom.Navigatable;
import com.intellij.ui.ColoredTextContainer;
import com.intellij.xdebugger.XDebugSession;
import com.intellij.xdebugger.XSourcePosition;
import com.intellij.xdebugger.evaluation.XDebuggerEvaluator;
import com.intellij.xdebugger.frame.*;
import com.intellij.xdebugger.frame.presentation.XValuePresentation;
import com.intellij.xdebugger.impl.XSourcePositionImpl;
import com.intellij.xdebugger.impl.ui.XDebuggerUIConstants;
import com.intellij.xdebugger.settings.XDebuggerSettingsManager;
import com.sun.jdi.*;
@@ -89,7 +85,7 @@ public class JavaStackFrame extends XStackFrame {
myEqualityObject = update ? NodeManagerImpl.getContextKeyForFrame(myDescriptor.getFrameProxy()) : null;
myDebugProcess = ((DebugProcessImpl)descriptor.getDebugProcess());
myNodeManager = myDebugProcess.getXdebugProcess().getNodeManager();
myXSourcePosition = myDescriptor.getSourcePosition() != null ? new JavaXSourcePosition(myDescriptor.getSourcePosition()) : null;
myXSourcePosition = myDescriptor.getSourcePosition() != null ? DebuggerUtilsEx.toXSourcePosition(myDescriptor.getSourcePosition()) : null;
}
@NotNull
@@ -401,34 +397,4 @@ public class JavaStackFrame extends XStackFrame {
return "JavaFrame position unknown";
}
}
private static class JavaXSourcePosition implements XSourcePosition {
private final SourcePosition mySourcePosition;
public JavaXSourcePosition(@NotNull SourcePosition sourcePosition) {
mySourcePosition = sourcePosition;
}
@Override
public int getLine() {
return mySourcePosition.getLine();
}
@Override
public int getOffset() {
return mySourcePosition.getOffset();
}
@NotNull
@Override
public VirtualFile getFile() {
return mySourcePosition.getFile().getVirtualFile();
}
@NotNull
@Override
public Navigatable createNavigatable(@NotNull Project project) {
return XSourcePositionImpl.createOpenFileDescriptor(project, this);
}
}
}
@@ -377,9 +377,16 @@ public class JavaValue extends XNamedValue implements NodeDescriptorProvider, XV
@Override
public void computeSourcePosition(@NotNull final XNavigatable navigatable) {
if (navigatable instanceof XInlineSourcePosition && !(navigatable instanceof XNearestSourcePosition)
&& !(myValueDescriptor instanceof ThisDescriptorImpl || myValueDescriptor instanceof LocalVariableDescriptor)) {
return;
}
myEvaluationContext.getManagerThread().schedule(new SuspendContextCommandImpl(myEvaluationContext.getSuspendContext()) {
@Override
public Priority getPriority() {
if (navigatable instanceof XInlineSourcePosition) {
return Priority.LOW;
}
return Priority.NORMAL;
}
@@ -80,7 +80,7 @@ public class DebuggerContextUtil {
//final Editor editor = fileEditor instanceof TextEditorImpl ? ((TextEditorImpl)fileEditor).getEditor() : null;
if (editor != null && position != null && file.getVirtualFile().equals(position.getFile())) {
final Couple<Collection<TextRange>> usages = IdentifierHighlighterPass.getHighlightUsages(psi, file);
final Couple<Collection<TextRange>> usages = IdentifierHighlighterPass.getHighlightUsages(psi, file, false);
final List<TextRange> ranges = new ArrayList<TextRange>();
ranges.addAll(usages.first);
ranges.addAll(usages.second);
@@ -104,6 +104,6 @@ public class DebuggerContextUtil {
catch (Exception ignore) {
}
}
return SourcePosition.createFromOffset(file, psi.getTextOffset());
return null;
}
}
@@ -42,6 +42,8 @@ import com.intellij.openapi.fileTypes.StdFileTypes;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.*;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.pom.Navigatable;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
import com.intellij.ui.classFilter.ClassFilter;
@@ -631,6 +633,36 @@ public abstract class DebuggerUtilsEx extends DebuggerUtils {
@Nullable
public static XSourcePosition toXSourcePosition(@NotNull SourcePosition position) {
return XSourcePositionImpl.create(position.getFile().getVirtualFile(), position.getLine());
return new JavaXSourcePosition(position);
}
private static class JavaXSourcePosition implements XSourcePosition {
private final SourcePosition mySourcePosition;
public JavaXSourcePosition(@NotNull SourcePosition sourcePosition) {
mySourcePosition = sourcePosition;
}
@Override
public int getLine() {
return mySourcePosition.getLine();
}
@Override
public int getOffset() {
return mySourcePosition.getOffset();
}
@NotNull
@Override
public VirtualFile getFile() {
return mySourcePosition.getFile().getVirtualFile();
}
@NotNull
@Override
public Navigatable createNavigatable(@NotNull Project project) {
return XSourcePositionImpl.createOpenFileDescriptor(project, this);
}
}
}
@@ -123,7 +123,7 @@ public class IdentifierHighlighterPass extends TextEditorHighlightingPass {
* @param psiFile psi file for element
* @return a pair where first element is read usages and second is write usages
*/
public static Couple<Collection<TextRange>> getHighlightUsages(@NotNull PsiElement target, PsiFile psiFile) {
public static Couple<Collection<TextRange>> getHighlightUsages(@NotNull PsiElement target, PsiFile psiFile, boolean withDecls) {
Collection<TextRange> readRanges = new ArrayList<TextRange>();
Collection<TextRange> writeRanges = new ArrayList<TextRange>();
final ReadWriteAccessDetector detector = ReadWriteAccessDetector.findDetector(target);
@@ -143,13 +143,15 @@ public class IdentifierHighlighterPass extends TextEditorHighlightingPass {
}
}
final TextRange declRange = HighlightUsagesHandler.getNameIdentifierRange(psiFile, target);
if (declRange != null) {
if (detector != null && detector.isDeclarationWriteAccess(target)) {
writeRanges.add(declRange);
}
else {
readRanges.add(declRange);
if (withDecls) {
final TextRange declRange = HighlightUsagesHandler.getNameIdentifierRange(psiFile, target);
if (declRange != null) {
if (detector != null && detector.isDeclarationWriteAccess(target)) {
writeRanges.add(declRange);
}
else {
readRanges.add(declRange);
}
}
}
@@ -157,7 +159,7 @@ public class IdentifierHighlighterPass extends TextEditorHighlightingPass {
}
private void highlightTargetUsages(@NotNull PsiElement target) {
final Couple<Collection<TextRange>> usages = getHighlightUsages(target, myFile);
final Couple<Collection<TextRange>> usages = getHighlightUsages(target, myFile, true);
myReadAccessRanges.addAll(usages.first);
myWriteAccessRanges.addAll(usages.second);
}
@@ -0,0 +1,22 @@
/*
* Copyright 2000-2014 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.xdebugger.frame;
/**
* @author egor
*/
public interface XInlineSourcePosition extends XNavigatable {
}
@@ -18,5 +18,5 @@ package com.intellij.xdebugger.frame;
/**
* @author Konstantin Bulenkov
*/
public interface XNearestSourcePosition extends XNavigatable {
public interface XNearestSourcePosition extends XInlineSourcePosition {
}
@@ -37,7 +37,6 @@ import com.intellij.util.containers.Convertor;
import com.intellij.util.containers.TransferToEDTQueue;
import com.intellij.util.ui.TextTransferable;
import com.intellij.util.ui.UIUtil;
import com.intellij.util.ui.tree.TreeModelAdapter;
import com.intellij.xdebugger.XSourcePosition;
import com.intellij.xdebugger.evaluation.XDebuggerEditorsProvider;
import com.intellij.xdebugger.frame.XDebuggerTreeNodeHyperlink;
@@ -49,7 +48,6 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import javax.swing.event.TreeModelEvent;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;
@@ -155,27 +153,6 @@ public class XDebuggerTree extends DnDAwareTree implements DataProvider, Disposa
myEditorsProvider = editorsProvider;
mySourcePosition = sourcePosition;
myTreeModel = new DefaultTreeModel(null);
myTreeModel.addTreeModelListener(new TreeModelAdapter() {
@Override
public void treeNodesChanged(TreeModelEvent e) {
updateEditor();
}
@Override
public void treeNodesInserted(TreeModelEvent e) {
updateEditor();
}
@Override
public void treeNodesRemoved(TreeModelEvent e) {
updateEditor();
}
@Override
public void treeStructureChanged(TreeModelEvent e) {
updateEditor();
}
});
setModel(myTreeModel);
setCellRenderer(new XDebuggerTreeRenderer());
new TreeLinkMouseListener(new XDebuggerTreeRenderer()) {
@@ -226,7 +203,7 @@ public class XDebuggerTree extends DnDAwareTree implements DataProvider, Disposa
setTransferHandler(DEFAULT_TRANSFER_HANDLER);
}
private void updateEditor() {
public void updateEditor() {
myAlarm.cancelAndRequest();
}
@@ -18,6 +18,7 @@ package com.intellij.xdebugger.impl.ui.tree.nodes;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.util.text.StringUtil;
@@ -137,8 +138,8 @@ public class XValueNodeImpl extends XValueContainerNode<XValue> implements XValu
try {
final XDebugSession session = XDebugView.getSession(getTree());
if (session != null) {
final XSourcePosition position = session.getCurrentPosition();
if (position != null) {
final XSourcePosition debuggerPosition = session.getCurrentPosition();
if (debuggerPosition != null) {
final XInlineDebuggerDataCallback callback = new XInlineDebuggerDataCallback() {
@Override
public void computed(@NotNull VirtualFile file, @NotNull Document document, int line) {
@@ -156,11 +157,12 @@ public class XValueNodeImpl extends XValueContainerNode<XValue> implements XValu
if (old != null) {
presentations.addAll(old);
}
myTree.updateEditor();
}
};
if (getValueContainer().computeInlineDebuggerData(callback) == ThreeState.UNSURE) {
class ValueDeclaration implements XNavigatable {
class ValueDeclaration implements XInlineSourcePosition {
@Override
public void setSourcePosition(@Nullable XSourcePosition sourcePosition) {
final Map<Pair<VirtualFile, Integer>, Set<XValueNodeImpl>> map =
@@ -168,6 +170,7 @@ public class XValueNodeImpl extends XValueContainerNode<XValue> implements XValu
final Map<VirtualFile, Long> timestamps = myTree.getProject().getUserData(XVariablesView.DEBUG_VARIABLES_TIMESTAMPS);
if (map == null || timestamps == null || sourcePosition == null) return;
VirtualFile file = sourcePosition.getFile();
if (!Comparing.equal(debuggerPosition.getFile(), sourcePosition.getFile())) return;
final Document doc = FileDocumentManager.getInstance().getDocument(file);
if (doc == null) return;
int line = sourcePosition.getLine();