Remove redundant files in Memory view, rename packages, add icons

This commit is contained in:
Vitaliy.Bibaev
2016-12-16 11:34:15 +03:00
parent d9d6420f12
commit 60f7a0cfde
74 changed files with 1565 additions and 909 deletions
@@ -1,4 +1,19 @@
package org.jetbrains.debugger.memory.action;
/*
* Copyright 2000-2016 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.debugger.memory.action;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
@@ -6,7 +21,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.xdebugger.XDebugSession;
import com.sun.jdi.ReferenceType;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.debugger.memory.view.ClassesTable;
import com.intellij.debugger.memory.ui.ClassesTable;
public abstract class ClassesActionBase extends AnAction {
@Override
@@ -1,4 +1,19 @@
package org.jetbrains.debugger.memory.action;
/*
* Copyright 2000-2016 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.debugger.memory.action;
import com.intellij.debugger.ui.impl.watch.NodeDescriptorProvider;
import com.intellij.debugger.ui.tree.NodeDescriptor;
@@ -1,9 +1,24 @@
package org.jetbrains.debugger.memory.action;
/*
* Copyright 2000-2016 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.debugger.memory.action;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.ToggleAction;
import com.intellij.openapi.project.Project;
import org.jetbrains.debugger.memory.component.InstancesTracker;
import com.intellij.debugger.memory.component.InstancesTracker;
public class EnableBackgroundTrackingAction extends ToggleAction{
@@ -1,4 +1,19 @@
package org.jetbrains.debugger.memory.action;
/*
* Copyright 2000-2016 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.debugger.memory.action;
import com.intellij.codeInsight.navigation.NavigationUtil;
import com.intellij.debugger.engine.DebuggerUtils;
@@ -49,7 +64,7 @@ public class JumpToTypeSourceAction extends ClassesActionBase {
}
@Nullable
private ReferenceType getObjectType(@NotNull ReferenceType ref) {
private static ReferenceType getObjectType(@NotNull ReferenceType ref) {
if (!(ref instanceof ArrayType)) {
return ref;
}
@@ -1,9 +1,24 @@
package org.jetbrains.debugger.memory.action;
/*
* Copyright 2000-2016 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.debugger.memory.action;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.ToggleAction;
import com.intellij.openapi.project.Project;
import org.jetbrains.debugger.memory.component.MemoryViewManager;
import com.intellij.debugger.memory.component.MemoryViewManager;
public class ShowClassesWithDiffAction extends ToggleAction {
@Override
@@ -1,9 +1,24 @@
package org.jetbrains.debugger.memory.action;
/*
* Copyright 2000-2016 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.debugger.memory.action;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.ToggleAction;
import com.intellij.openapi.project.Project;
import org.jetbrains.debugger.memory.component.MemoryViewManager;
import com.intellij.debugger.memory.component.MemoryViewManager;
public class ShowClassesWithInstanceAction extends ToggleAction {
@Override
@@ -1,4 +1,19 @@
package org.jetbrains.debugger.memory.action;
/*
* Copyright 2000-2016 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.debugger.memory.action;
import com.intellij.openapi.actionSystem.AnActionEvent;
@@ -1,4 +1,19 @@
package org.jetbrains.debugger.memory.action;
/*
* Copyright 2000-2016 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.debugger.memory.action;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.project.Project;
@@ -9,7 +24,7 @@ import com.intellij.xdebugger.impl.ui.tree.nodes.XValueNodeImpl;
import com.sun.jdi.ObjectReference;
import com.sun.jdi.ReferenceType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.debugger.memory.view.InstancesWindow;
import com.intellij.debugger.memory.ui.InstancesWindow;
public class ShowInstancesByClassAction extends DebuggerTreeAction {
@Override
@@ -1,10 +1,25 @@
package org.jetbrains.debugger.memory.action;
/*
* Copyright 2000-2016 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.debugger.memory.action;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.xdebugger.XDebugSession;
import com.sun.jdi.ReferenceType;
import org.jetbrains.debugger.memory.view.ClassesTable;
import org.jetbrains.debugger.memory.view.InstancesWindow;
import com.intellij.debugger.memory.ui.ClassesTable;
import com.intellij.debugger.memory.ui.InstancesWindow;
public class ShowInstancesFromClassesViewAction extends ShowInstancesAction {
private static final String POPUP_ELEMENT_LABEL = "Show Instances";
@@ -1,11 +1,26 @@
package org.jetbrains.debugger.memory.action;
/*
* Copyright 2000-2016 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.debugger.memory.action;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.xdebugger.XDebugSession;
import com.sun.jdi.ReferenceType;
import org.jetbrains.debugger.memory.utils.InstancesProvider;
import org.jetbrains.debugger.memory.view.ClassesTable;
import org.jetbrains.debugger.memory.view.InstancesWindow;
import com.intellij.debugger.memory.utils.InstancesProvider;
import com.intellij.debugger.memory.ui.ClassesTable;
import com.intellij.debugger.memory.ui.InstancesWindow;
public class ShowNewInstancesAction extends ShowInstancesAction {
private static final String POPUP_ELEMENT_LABEL = "Show New Instances";
@@ -1,8 +1,23 @@
package org.jetbrains.debugger.memory.action;
/*
* Copyright 2000-2016 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.debugger.memory.action;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.ToggleAction;
import org.jetbrains.debugger.memory.component.MemoryViewManager;
import com.intellij.debugger.memory.component.MemoryViewManager;
public class ShowTrackedAction extends ToggleAction {
@Override
@@ -1,6 +1,23 @@
package org.jetbrains.debugger.memory.action.tracking;
/*
* Copyright 2000-2016 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.debugger.memory.action.tracking;
import com.intellij.debugger.DebuggerManager;
import com.intellij.debugger.memory.action.DebuggerTreeAction;
import com.intellij.debugger.memory.ui.StackFramePopup;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.project.Project;
import com.intellij.psi.search.GlobalSearchScope;
@@ -10,11 +27,9 @@ import com.intellij.xdebugger.impl.ui.tree.nodes.XValueNodeImpl;
import com.sun.jdi.ObjectReference;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.debugger.memory.action.DebuggerTreeAction;
import org.jetbrains.debugger.memory.component.CreationPositionTracker;
import org.jetbrains.debugger.memory.utils.StackFrameDescriptor;
import org.jetbrains.debugger.memory.view.InstancesTree;
import org.jetbrains.debugger.memory.view.StackFramePopup;
import com.intellij.debugger.memory.component.CreationPositionTracker;
import com.intellij.debugger.memory.utils.StackFrameDescriptor;
import com.intellij.debugger.memory.ui.InstancesTree;
import java.util.List;
@@ -1,5 +1,23 @@
package org.jetbrains.debugger.memory.action.tracking;
/*
* Copyright 2000-2016 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.debugger.memory.action.tracking;
import com.intellij.debugger.memory.component.InstancesTracker;
import com.intellij.debugger.memory.tracking.TrackingType;
import com.intellij.debugger.memory.ui.ClassesTable;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.ToggleAction;
import com.intellij.xdebugger.XDebugSession;
@@ -7,9 +25,6 @@ import com.sun.jdi.ArrayType;
import com.sun.jdi.ReferenceType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.debugger.memory.component.InstancesTracker;
import org.jetbrains.debugger.memory.tracking.TrackingType;
import org.jetbrains.debugger.memory.view.ClassesTable;
public class TrackInstancesToggleAction extends ToggleAction {
@Override
@@ -53,12 +68,12 @@ public class TrackInstancesToggleAction extends ToggleAction {
}
@Nullable
private ReferenceType getSelectedClass(AnActionEvent e) {
private static ReferenceType getSelectedClass(AnActionEvent e) {
return e.getData(ClassesTable.SELECTED_CLASS_KEY);
}
@Nullable
private XDebugSession getDebugSession(AnActionEvent e) {
private static XDebugSession getDebugSession(AnActionEvent e) {
return e.getData(ClassesTable.DEBUG_SESSION_KEY);
}
}
@@ -1,5 +1,21 @@
package org.jetbrains.debugger.memory.component;
/*
* Copyright 2000-2016 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.debugger.memory.component;
import com.intellij.debugger.memory.utils.StackFrameDescriptor;
import com.intellij.openapi.components.AbstractProjectComponent;
import com.intellij.openapi.project.Project;
import com.intellij.xdebugger.XDebugSession;
@@ -8,7 +24,6 @@ import com.sun.jdi.ObjectReference;
import com.sun.jdi.ReferenceType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.debugger.memory.utils.StackFrameDescriptor;
import java.util.Iterator;
import java.util.List;
@@ -1,4 +1,19 @@
package org.jetbrains.debugger.memory.component;
/*
* Copyright 2000-2016 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.debugger.memory.component;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.components.*;
@@ -8,8 +23,8 @@ import com.intellij.util.containers.HashMap;
import com.intellij.util.xmlb.annotations.AbstractCollection;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.debugger.memory.event.InstancesTrackerListener;
import org.jetbrains.debugger.memory.tracking.TrackingType;
import com.intellij.debugger.memory.event.InstancesTrackerListener;
import com.intellij.debugger.memory.tracking.TrackingType;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@@ -56,14 +71,11 @@ public class InstancesTracker extends AbstractProjectComponent
myDispatcher.getMulticaster().classChanged(name, type);
}
public boolean remove(@NotNull String name) {
public void remove(@NotNull String name) {
TrackingType removed = myState.classes.remove(name);
if (removed != null) {
myDispatcher.getMulticaster().classRemoved(name);
return true;
}
return false;
}
public void addTrackerListener(@NotNull InstancesTrackerListener listener, @NotNull Disposable parentDisposable) {
@@ -1,5 +1,22 @@
package org.jetbrains.debugger.memory.component;
/*
* Copyright 2000-2016 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.debugger.memory.component;
import com.intellij.debugger.memory.event.MemoryViewManagerListener;
import com.intellij.debugger.memory.toolwindow.MemoryViewToolWindowFactory;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.components.*;
@@ -9,8 +26,6 @@ import com.intellij.openapi.wm.ToolWindowManager;
import com.intellij.util.EventDispatcher;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.debugger.memory.event.MemoryViewManagerListener;
import org.jetbrains.debugger.memory.toolwindow.MemoryViewToolWindowFactory;
@State(name = "MemoryViewSettings", storages = @Storage("memory.view.xml"))
public class MemoryViewManager extends ApplicationComponent.Adapter
@@ -1,4 +1,19 @@
package org.jetbrains.debugger.memory.component;
/*
* Copyright 2000-2016 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.debugger.memory.component;
public final class MemoryViewManagerState {
public boolean isShowWithInstancesOnly = true;
@@ -1,7 +1,22 @@
package org.jetbrains.debugger.memory.event;
/*
* Copyright 2000-2016 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.debugger.memory.event;
import com.intellij.debugger.memory.tracking.TrackingType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.debugger.memory.tracking.TrackingType;
import java.util.EventListener;
@@ -1,6 +1,21 @@
package org.jetbrains.debugger.memory.event;
/*
* Copyright 2000-2016 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.debugger.memory.event;
import org.jetbrains.debugger.memory.component.MemoryViewManagerState;
import com.intellij.debugger.memory.component.MemoryViewManagerState;
import org.jetbrains.annotations.NotNull;
import java.util.EventListener;
@@ -0,0 +1,33 @@
/*
* Copyright 2000-2016 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.debugger.memory.filtering;
import org.jetbrains.annotations.NotNull;
/**
* @author Vitaliy.Bibaev
*/
public interface CheckingResult {
@NotNull
Result getResult();
@NotNull
String getFailureDescription();
enum Result {
MATCH, NO_MATCH, ERROR
}
}
@@ -0,0 +1,50 @@
/*
* Copyright 2000-2016 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.debugger.memory.filtering;
import org.jetbrains.annotations.NotNull;
/**
* @author Vitaliy.Bibaev
*/
public class CheckingResultImpl implements CheckingResult {
public static final CheckingResult SUCCESS = new CheckingResultImpl(CheckingResultImpl.Result.MATCH, "");
public static final CheckingResult FAIL = new CheckingResultImpl(CheckingResultImpl.Result.NO_MATCH, "");
private final Result myResult;
private final String myDescription;
private CheckingResultImpl(@NotNull Result result, @NotNull String description) {
myResult = result;
myDescription = description;
}
public static CheckingResult error(@NotNull String description) {
return new CheckingResultImpl(Result.ERROR, description);
}
@Override
@NotNull
public Result getResult() {
return myResult;
}
@Override
@NotNull
public String getFailureDescription() {
return myDescription;
}
}
@@ -0,0 +1,33 @@
/*
* Copyright 2000-2016 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.debugger.memory.filtering;
import com.sun.jdi.ObjectReference;
import org.jetbrains.annotations.NotNull;
/**
* @author Vitaliy.Bibaev
*/
public interface ConditionChecker {
CheckingResult check(@NotNull ObjectReference ref);
ConditionChecker ALL_MATCHED_CHECKER = new ConditionChecker() {
@Override
public CheckingResult check(@NotNull ObjectReference ref) {
return CheckingResultImpl.SUCCESS;
}
};
}
@@ -0,0 +1,110 @@
/*
* Copyright 2000-2016 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.debugger.memory.filtering;
import com.intellij.debugger.engine.DebugProcessImpl;
import com.intellij.debugger.engine.SuspendContextImpl;
import com.intellij.debugger.engine.evaluation.EvaluateException;
import com.intellij.debugger.engine.evaluation.EvaluationContextImpl;
import com.intellij.debugger.engine.evaluation.TextWithImportsImpl;
import com.intellij.debugger.engine.evaluation.expression.ExpressionEvaluator;
import com.intellij.debugger.engine.events.DebuggerContextCommandImpl;
import com.intellij.debugger.ui.tree.render.CachedEvaluator;
import com.intellij.openapi.project.Project;
import com.intellij.xdebugger.XExpression;
import com.sun.jdi.BooleanValue;
import com.sun.jdi.ObjectReference;
import com.sun.jdi.Value;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.concurrent.atomic.AtomicReference;
/**
* @author Vitaliy.Bibaev
*/
public class ConditionCheckerImpl implements ConditionChecker {
private final DebugProcessImpl myDebugProcess;
private final MyCachedEvaluator myEvaluator;
private final AtomicReference<CheckingResult> myResultReference = new AtomicReference<>();
public ConditionCheckerImpl(@NotNull DebugProcessImpl debugProcess,
@Nullable XExpression expression,
@NotNull String className) {
myDebugProcess = debugProcess;
myEvaluator = new MyCachedEvaluator(myDebugProcess.getProject(), className);
myEvaluator.setReferenceExpression(TextWithImportsImpl.fromXExpression(expression));
}
@Override
public CheckingResult check(@NotNull ObjectReference ref) {
myDebugProcess.getManagerThread().invokeAndWait(new MyCheckerCommand(ref));
return myResultReference.get();
}
private class MyCheckerCommand extends DebuggerContextCommandImpl {
private final ObjectReference myReference;
protected MyCheckerCommand(@NotNull ObjectReference ref) {
super(myDebugProcess.getDebuggerContext());
myReference = ref;
}
@Override
public Priority getPriority() {
return Priority.LOWEST;
}
@Override
public void threadAction(@NotNull SuspendContextImpl suspendContext) {
ExpressionEvaluator evaluator;
try {
evaluator = myEvaluator.getEvaluator();
Value result =
evaluator.evaluate(new EvaluationContextImpl(suspendContext, suspendContext.getFrameProxy(), myReference));
if (result instanceof BooleanValue && ((BooleanValue)result).value()) {
myResultReference.set(CheckingResultImpl.SUCCESS);
}
else {
myResultReference.set(CheckingResultImpl.FAIL);
}
}
catch (EvaluateException e) {
myResultReference.set(CheckingResultImpl.error(e.getMessage()));
}
}
}
private static class MyCachedEvaluator extends CachedEvaluator {
private final Project myProject;
private final String myClassName;
public MyCachedEvaluator(@NotNull Project project, @NotNull String className) {
super();
myProject = project;
myClassName = className;
}
ExpressionEvaluator getEvaluator() throws EvaluateException {
return getEvaluator(myProject);
}
@Override
protected String getClassName() {
return myClassName;
}
}
}
@@ -0,0 +1,27 @@
/*
* Copyright 2000-2016 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.debugger.memory.filtering;
/**
* @author Vitaliy.Bibaev
*/
public enum FilteringResult {
ALL_CHECKED,
INTERRUPTED,
LIMIT_REACHED
}
@@ -0,0 +1,88 @@
/*
* Copyright 2000-2016 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.debugger.memory.filtering;
import com.intellij.debugger.engine.DebugProcessImpl;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.xdebugger.XExpression;
import com.sun.jdi.ObjectReference;
import com.sun.jdi.ReferenceType;
import org.jetbrains.annotations.NotNull;
import java.util.List;
/**
* @author Vitaliy.Bibaev
*/
public class FilteringTask implements Runnable {
private final List<ObjectReference> myReferences;
private final ConditionChecker myChecker;
private final FilteringTaskCallback myCallback;
private volatile boolean myIsCancelled = false;
public FilteringTask(@NotNull ReferenceType referenceType, @NotNull DebugProcessImpl debugProcess,
@NotNull XExpression expression, @NotNull List<ObjectReference> references,
@NotNull FilteringTaskCallback callback) {
myChecker = StringUtil.isEmptyOrSpaces(expression.getExpression())
? ConditionChecker.ALL_MATCHED_CHECKER
: new ConditionCheckerImpl(debugProcess, expression, referenceType.name());
myReferences = references;
myCallback = callback;
}
public void cancel() {
myIsCancelled = true;
}
public boolean isCancelled() {
return myIsCancelled;
}
@Override
public void run() {
myCallback.started(myReferences.size());
int proceedCount;
for (proceedCount = 0; proceedCount < myReferences.size(); proceedCount++) {
ObjectReference ref = myReferences.get(proceedCount);
CheckingResult result = myChecker.check(ref);
FilteringTaskCallback.Action action = FilteringTaskCallback.Action.CONTINUE;
switch (result.getResult()) {
case MATCH:
action = myCallback.matched(ref);
break;
case NO_MATCH:
action = myCallback.notMatched(ref);
break;
case ERROR:
action = myCallback.error(ref, result.getFailureDescription());
break;
}
if (action == FilteringTaskCallback.Action.STOP) {
break;
}
}
FilteringResult reason = myIsCancelled
? FilteringResult.INTERRUPTED
: proceedCount == myReferences.size()
? FilteringResult.ALL_CHECKED
: FilteringResult.LIMIT_REACHED;
myCallback.completed(reason);
}
}
@@ -0,0 +1,41 @@
/*
* Copyright 2000-2016 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.debugger.memory.filtering;
import com.sun.jdi.ObjectReference;
import org.jetbrains.annotations.NotNull;
/**
* @author Vitaliy.Bibaev
*/
public interface FilteringTaskCallback {
void started(int totalCount);
@NotNull
Action matched(@NotNull ObjectReference ref);
@NotNull
Action notMatched(@NotNull ObjectReference ref);
@NotNull
Action error(@NotNull ObjectReference ref, @NotNull String description);
void completed(@NotNull FilteringResult reason);
enum Action {
STOP, CONTINUE
}
}
@@ -1,109 +0,0 @@
package org.jetbrains.debugger.memory.sizeof;
import com.sun.jdi.*;
import java.util.Collection;
import java.util.concurrent.TimeUnit;
public class RetainedSizeFetcher extends SizeOfEvalStrategy {
private final static long REFERENCE_SIZE = 4;
private final static long CHAR_SIZE = 2;
private final static long INT_SIZE = 4;
private final static long FLOAT_SIZE = 4;
private final static long DOUBLE_SIZE = 8;
private final static long BYTE_SIZE = 1;
private final static long BOOLEAN_SIZE = 1; // ?
private final static long LONG_SIZE = 8;
private final static long SHORT_SIZE = 2;
private final boolean myCheckReferringObjects;
public RetainedSizeFetcher(boolean checkReferringObjects) {
myCheckReferringObjects = checkReferringObjects;
}
private static long getPrimitiveTypeSize(PrimitiveValue value) {
if (value instanceof IntegerValue) {
return INT_SIZE;
}
if (value instanceof LongValue) {
return LONG_SIZE;
}
if (value instanceof DoubleValue) {
return DOUBLE_SIZE;
}
if (value instanceof FloatValue) {
return FLOAT_SIZE;
}
if (value instanceof CharValue) {
return CHAR_SIZE;
}
if (value instanceof ByteValue) {
return BYTE_SIZE;
}
if (value instanceof BooleanValue) {
return BOOLEAN_SIZE;
}
return SHORT_SIZE;
}
private long getValueSize(Value value, Collection<ObjectReference> visited) {
if (value == null) {
return 0;
}
if (value instanceof PrimitiveValue) {
return getPrimitiveTypeSize((PrimitiveValue) value);
} else {
ObjectReference ref = (ObjectReference) value;
if (visited.contains(ref)) {
return 0;
}
if (myCheckReferringObjects) {
long startTime = System.nanoTime();
int needReferringObjectCount = visited.size() + 1;
Collection<ObjectReference> referringObjects = ref.referringObjects(needReferringObjectCount);
long duration = System.nanoTime() - startTime;
System.out.println("referringObjects(" + needReferringObjectCount + ") duration = " + duration + "ns "+
"(" + TimeUnit.NANOSECONDS.toMillis(duration) + " ms).");
if (referringObjects.stream().anyMatch(objectReference -> !visited.contains(objectReference))) {
return 0;
}
}
return sizeOfImpl(ref, visited, false);
}
}
@Override
protected long sizeOfImpl(ObjectReference ref, Collection<ObjectReference> visited, boolean isRoot) {
visited.add(ref);
long result = 0;
if (ref instanceof ArrayReference) {
ArrayReference arrRef = (ArrayReference) ref;
int length = arrRef.length();
for (int i = 0; i < length; i++) {
result += getValueSize(arrRef.getValue(i), visited);
}
}
for (Field field : ref.referenceType().allFields()) {
Value val = ref.getValue(field);
if (field.isStatic()) {
continue;
}
result += REFERENCE_SIZE;
if (val == null) {
continue;
}
result += getValueSize(val, visited);
}
return result;
}
}
@@ -1,21 +0,0 @@
package org.jetbrains.debugger.memory.sizeof;
import com.sun.jdi.ObjectReference;
import java.util.Collection;
import java.util.HashSet;
import java.util.concurrent.TimeUnit;
abstract class SizeOfEvalStrategy {
public long sizeOf(ObjectReference ref) {
long startTime = System.nanoTime();
long result = sizeOfImpl(ref, new HashSet<>(), true);
long duration = System.nanoTime() - startTime;
System.out.printf("org.jetbrains.plugin.sizeof [%d] == %d. time = %d ns (%d ms).%n",
ref.uniqueID(), result, duration, TimeUnit.NANOSECONDS.toMillis(duration));
return result;
}
protected abstract long sizeOfImpl(ObjectReference ref, Collection<ObjectReference> visited, boolean isRoot);
}
@@ -1,13 +1,30 @@
package org.jetbrains.debugger.memory.toolwindow;
/*
* Copyright 2000-2016 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.debugger.memory.toolwindow;
import com.intellij.debugger.memory.component.MemoryViewManager;
import com.intellij.debugger.memory.ui.ClassesFilteredView;
import com.intellij.execution.Executor;
import com.intellij.execution.ui.RunContentDescriptor;
import com.intellij.execution.ui.RunContentManager;
import com.intellij.execution.ui.RunContentWithExecutorListener;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.actionSystem.ActionGroup;
import com.intellij.openapi.actionSystem.ActionManager;
import com.intellij.openapi.actionSystem.DefaultActionGroup;
import com.intellij.openapi.actionSystem.Separator;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.Project;
@@ -23,11 +40,8 @@ import com.intellij.xdebugger.XDebugProcess;
import com.intellij.xdebugger.XDebugSession;
import com.intellij.xdebugger.XDebuggerManager;
import com.intellij.xdebugger.XDebuggerManagerListener;
import icons.MemoryViewIcons;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.debugger.memory.component.MemoryViewManager;
import org.jetbrains.debugger.memory.view.ClassesFilteredView;
import javax.swing.*;
import java.awt.*;
@@ -50,7 +64,7 @@ public class MemoryViewToolWindowFactory implements ToolWindowFactory, DumbAware
{
myEmptyContent = new JBLabel("Run debugging to see loaded classes", SwingConstants.CENTER);
myMemoryViewNotSupportedContent = new JBLabel("The Memory View not available for this session",
SwingConstants.CENTER);
SwingConstants.CENTER);
}
@Override
@@ -60,34 +74,29 @@ public class MemoryViewToolWindowFactory implements ToolWindowFactory, DumbAware
connection.subscribe(RunContentManager.TOPIC, new RunContentWithExecutorListener() {
@Override
public void contentSelected(@Nullable RunContentDescriptor descriptor, @NotNull Executor executor) {
SwingUtilities.invokeLater(() -> updateCurrentMemoryView(project, toolWindow));
ApplicationManager.getApplication().invokeLater(() -> updateCurrentMemoryView(project, toolWindow));
}
@Override
public void contentRemoved(@Nullable RunContentDescriptor descriptor, @NotNull Executor executor) {
SwingUtilities.invokeLater(() -> updateCurrentMemoryView(project, toolWindow));
ApplicationManager.getApplication().invokeLater(() -> updateCurrentMemoryView(project, toolWindow));
}
});
((ToolWindowImpl) toolWindow).getToolWindowManager()
.addToolWindowManagerListener(new ToolWindowManagerAdapter() {
@Override
public void stateChanged() {
if (!myMemoryViews.isEmpty() && !toolWindow.isDisposed()) {
myMemoryViews.values().forEach(classesFilteredView ->
classesFilteredView.setActive(toolWindow.isVisible()));
}
((ToolWindowImpl)toolWindow).getToolWindowManager()
.addToolWindowManagerListener(new ToolWindowManagerAdapter() {
@Override
public void stateChanged() {
if (!myMemoryViews.isEmpty() && !toolWindow.isDisposed()) {
myMemoryViews.values().forEach(classesFilteredView ->
classesFilteredView.setActive(toolWindow.isVisible()));
}
}, project);
}
}, project);
ActionGroup group = new DefaultActionGroup(
ActionManager.getInstance().getAction("MemoryView.ShowOnlyWithInstances"),
ActionManager.getInstance().getAction("MemoryView.ShowOnlyWithDiff"),
ActionManager.getInstance().getAction("MemoryView.ShowOnlyTracked"),
Separator.getInstance(),
ActionManager.getInstance().getAction("MemoryView.EnableTrackingWithClosedWindow")
);
((ToolWindowEx) toolWindow).setAdditionalGearActions(group);
final ActionGroup group = (ActionGroup)ActionManager.getInstance().getAction("MemoryView.SettingsPopupActionGroup");
((ToolWindowEx)toolWindow).setAdditionalGearActions(group);
toolWindow.getComponent().setLayout(new BorderLayout());
for (XDebugSession session : XDebuggerManager.getInstance(project).getDebugSessions()) {
@@ -105,7 +114,8 @@ public class MemoryViewToolWindowFactory implements ToolWindowFactory, DumbAware
ClassesFilteredView newView = new ClassesFilteredView(session);
newView.setActive(toolWindow != null && toolWindow.isVisible());
myMemoryViews.put(session, newView);
} catch (Throwable e) {
}
catch (Throwable e) {
LOG.warn("Cannot create new instance of the memory view. " + e.getMessage());
}
}
@@ -126,7 +136,8 @@ public class MemoryViewToolWindowFactory implements ToolWindowFactory, DumbAware
if (myMemoryViews.containsKey(session)) {
view = myMemoryViews.get(session);
replaceToolWindowContent(toolWindow, view);
} else {
}
else {
view = null;
replaceToolWindowContent(toolWindow, myMemoryViewNotSupportedContent);
}
@@ -143,7 +154,7 @@ public class MemoryViewToolWindowFactory implements ToolWindowFactory, DumbAware
replaceToolWindowContent(toolWindow, myEmptyContent);
}
private void replaceToolWindowContent(@NotNull ToolWindow toolWindow, JComponent comp) {
private static void replaceToolWindowContent(@NotNull ToolWindow toolWindow, JComponent comp) {
LOG.assertTrue(SwingUtilities.isEventDispatchThread());
JComponent toolWindowComp = toolWindow.getComponent();
toolWindowComp.removeAll();
@@ -152,7 +163,7 @@ public class MemoryViewToolWindowFactory implements ToolWindowFactory, DumbAware
}
@Nullable
private ToolWindow getToolWindow(@NotNull Project project) {
private static ToolWindow getToolWindow(@NotNull Project project) {
return MemoryViewManager.getInstance().getToolWindow(project);
}
@@ -170,15 +181,15 @@ public class MemoryViewToolWindowFactory implements ToolWindowFactory, DumbAware
public void processStopped(@NotNull XDebugProcess debugProcess) {
Project project = debugProcess.getSession().getProject();
boolean enabled = Arrays.stream(XDebuggerManager.getInstance(project)
.getDebugSessions()).anyMatch(session -> !session.getDebugProcess().equals(debugProcess));
.getDebugSessions()).anyMatch(session -> !session.getDebugProcess().equals(debugProcess));
updateIcon(project, enabled);
}
private void updateIcon(@NotNull Project project, boolean enabled) {
ToolWindow toolWindow = MemoryViewManager.getInstance().getToolWindow(project);
if (toolWindow != null) {
SwingUtilities.invokeLater(() ->
toolWindow.setIcon(enabled ? MemoryViewIcons.MAIN_ENABLED : MemoryViewIcons.MAIN_DISABLED));
Icon icon = enabled ? AllIcons.Debugger.MemoryView.ToolWindowEnabled : AllIcons.Debugger.MemoryView.ToolWindowDisabled;
ApplicationManager.getApplication().invokeLater(() -> toolWindow.setIcon(icon));
}
}
});
@@ -189,7 +200,7 @@ public class MemoryViewToolWindowFactory implements ToolWindowFactory, DumbAware
private final class MyDebuggerStatusChangedListener implements XDebuggerManagerListener {
@Override
public void processStarted(@NotNull XDebugProcess xDebugProcess) {
SwingUtilities.invokeLater(() -> {
ApplicationManager.getApplication().invokeLater(() -> {
XDebugSession session = xDebugProcess.getSession();
addNewSession(session);
updateView(session);
@@ -200,7 +211,7 @@ public class MemoryViewToolWindowFactory implements ToolWindowFactory, DumbAware
public void processStopped(@NotNull XDebugProcess xDebugProcess) {
XDebugSession session = xDebugProcess.getSession();
removeSession(session);
SwingUtilities.invokeLater(() -> updateView(session));
ApplicationManager.getApplication().invokeLater(() -> updateView(session));
}
private void updateView(@NotNull XDebugSession debugSession) {
@@ -1,4 +1,19 @@
package org.jetbrains.debugger.memory.tracking;
/*
* Copyright 2000-2016 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.debugger.memory.tracking;
interface BackgroundTracker {
void setBackgroundMode(boolean isBackgroundMode);
@@ -1,4 +1,19 @@
package org.jetbrains.debugger.memory.tracking;
/*
* Copyright 2000-2016 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.debugger.memory.tracking;
import com.intellij.debugger.DebuggerManager;
import com.intellij.debugger.engine.DebugProcess;
@@ -1,4 +1,19 @@
package org.jetbrains.debugger.memory.tracking;
/*
* Copyright 2000-2016 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.debugger.memory.tracking;
import com.intellij.debugger.DebuggerManager;
import com.intellij.debugger.engine.DebugProcessImpl;
@@ -8,11 +23,15 @@ import com.intellij.debugger.engine.events.DebuggerCommandImpl;
import com.intellij.debugger.engine.events.SuspendContextCommandImpl;
import com.intellij.debugger.jdi.StackFrameProxyImpl;
import com.intellij.debugger.jdi.ThreadReferenceProxyImpl;
import com.intellij.debugger.memory.component.CreationPositionTracker;
import com.intellij.debugger.memory.utils.StackFrameDescriptor;
import com.intellij.debugger.ui.breakpoints.JavaLineBreakpointType;
import com.intellij.debugger.ui.breakpoints.LineBreakpoint;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Disposer;
import com.intellij.xdebugger.XDebugSession;
import com.intellij.xdebugger.XDebuggerManager;
import com.intellij.xdebugger.breakpoints.XBreakpoint;
import com.intellij.xdebugger.impl.XDebuggerManagerImpl;
import com.intellij.xdebugger.impl.breakpoints.LineBreakpointState;
@@ -26,10 +45,8 @@ import com.sun.jdi.request.BreakpointRequest;
import com.sun.jdi.request.EventRequest;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.debugger.memory.component.CreationPositionTracker;
import org.jetbrains.debugger.memory.component.InstancesTracker;
import org.jetbrains.debugger.memory.event.InstancesTrackerListener;
import org.jetbrains.debugger.memory.utils.StackFrameDescriptor;
import com.intellij.debugger.memory.component.InstancesTracker;
import com.intellij.debugger.memory.event.InstancesTrackerListener;
import org.jetbrains.java.debugger.breakpoints.properties.JavaLineBreakpointProperties;
import java.util.*;
@@ -59,7 +76,7 @@ public class ConstructorInstancesTracker implements TrackerForNewInstances, Disp
myPositionTracker = CreationPositionTracker.getInstance(debugSession.getProject());
Project project = debugSession.getProject();
myIsBackgroundTrackingEnabled = InstancesTracker.getInstance(myDebugSession.getProject())
.isBackgroundTrackingEnabled();
.isBackgroundTrackingEnabled();
InstancesTracker.getInstance(myDebugSession.getProject()).addTrackerListener(new InstancesTrackerListener() {
@Override
@@ -71,7 +88,8 @@ public class ConstructorInstancesTracker implements TrackerForNewInstances, Disp
protected void action() throws Exception {
if (newState) {
myBreakpoint.enable();
} else {
}
else {
myBreakpoint.disable();
}
}
@@ -80,14 +98,14 @@ public class ConstructorInstancesTracker implements TrackerForNewInstances, Disp
}
}, this);
myDebugProcess = (DebugProcessImpl) DebuggerManager.getInstance(project)
.getDebugProcess(debugSession.getDebugProcess().getProcessHandler());
myDebugProcess = (DebugProcessImpl)DebuggerManager.getInstance(project)
.getDebugProcess(debugSession.getDebugProcess().getProcessHandler());
JavaLineBreakpointType breakPointType = new JavaLineBreakpointType();
XBreakpoint bpn = new XLineBreakpointImpl<>(breakPointType,
((XDebuggerManagerImpl) XDebuggerManagerImpl.getInstance(project)).getBreakpointManager(),
new JavaLineBreakpointProperties(),
new LineBreakpointState<>());
((XDebuggerManagerImpl)XDebuggerManager.getInstance(project)).getBreakpointManager(),
new JavaLineBreakpointProperties(),
new LineBreakpointState<>());
myBreakpoint = new MyConstructorBreakpoints(project, bpn);
myBreakpoint.createRequestForPreparedClass(myDebugProcess, myReference);
@@ -136,7 +154,7 @@ public class ConstructorInstancesTracker implements TrackerForNewInstances, Disp
@Override
public void dispose() {
myBreakpoint.dispose();
Disposer.dispose(myBreakpoint);
}
@Override
@@ -148,7 +166,8 @@ public class ConstructorInstancesTracker implements TrackerForNewInstances, Disp
myIsBackgroundMode = isBackgroundMode;
if (isBackgroundMode) {
doEnableBackgroundMode();
} else {
}
else {
doDisableBackgroundMode();
}
}
@@ -164,7 +183,7 @@ public class ConstructorInstancesTracker implements TrackerForNewInstances, Disp
}
private final class MyConstructorBreakpoints extends LineBreakpoint<JavaLineBreakpointProperties>
implements Disposable {
implements Disposable {
private boolean myIsEnabled = false;
private final List<BreakpointRequest> myRequests = new ArrayList<>();
@@ -205,7 +224,7 @@ public class ConstructorInstancesTracker implements TrackerForNewInstances, Disp
@Override
public boolean processLocatableEvent(SuspendContextCommandImpl action, LocatableEvent event)
throws EventProcessingException {
throws EventProcessingException {
try {
SuspendContextImpl suspendContext = action.getSuspendContext();
if (suspendContext != null) {
@@ -223,7 +242,8 @@ public class ConstructorInstancesTracker implements TrackerForNewInstances, Disp
String typeName = loc.declaringType().name();
String methodName = loc.method().name();
return new StackFrameDescriptor(typeName, methodName, loc.lineNumber());
} catch (EvaluateException e) {
}
catch (EvaluateException e) {
return null;
}
}).filter(Objects::nonNull).collect(Collectors.toList());
@@ -231,7 +251,8 @@ public class ConstructorInstancesTracker implements TrackerForNewInstances, Disp
}
}
}
} catch (EvaluateException e) {
}
catch (EvaluateException e) {
return false;
}
@@ -1,169 +0,0 @@
package org.jetbrains.debugger.memory.tracking;
import com.intellij.debugger.engine.SuspendContextImpl;
import com.intellij.debugger.engine.jdi.ThreadReferenceProxy;
import com.intellij.openapi.diagnostic.Logger;
import com.sun.jdi.*;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
class HashBasedTracking extends InstanceTrackingStrategy {
private static final Logger LOG = Logger.getInstance(HashBasedTracking.class);
private final ReferenceType myClassType;
private MyHashCodeMethodWrapper myHashCodeWrapper;
private Set<Integer> myHashesSet;
private MyState myState = MyState.WAIT_HASHES;
private int myCount = 0;
HashBasedTracking(@Nullable SuspendContextImpl suspendContext,
@NotNull ReferenceType classType,
@NotNull List<ObjectReference> initialInstances) {
myClassType = classType;
if (suspendContext != null) {
myHashesSet = toSetOfHashes(evalHashCodes(suspendContext, initialInstances));
myState = myState.next();
}
}
@NotNull
@Override
protected List<ObjectReference> updateImpl(@NotNull SuspendContextImpl suspendContext,
@NotNull List<ObjectReference> references) {
Map<ObjectReference, Optional<Integer>> ref2hash = evalHashCodes(suspendContext, references);
List<ObjectReference> newInstances = new ArrayList<>();
for (ObjectReference ref : references) {
Optional<Integer> hash = ref2hash.get(ref);
if (hash.isPresent() && !myState.equals(MyState.WAIT_HASHES) && !myHashesSet.contains(hash.get())) {
newInstances.add(ref);
}
}
myHashesSet = toSetOfHashes(ref2hash);
myState = myState.next();
myCount = newInstances.size();
return newInstances;
}
@Override
public int getCount() {
return myCount;
}
@Override
public boolean isReady() {
return myState == MyState.READY;
}
@NotNull
private Map<ObjectReference, Optional<Integer>> evalHashCodes(@NotNull SuspendContextImpl suspendContext,
@NotNull List<ObjectReference> references) {
MyHashCodeMethodWrapper hashCodeCaller = getHashCodeMethod(myClassType);
Map<ObjectReference, Optional<Integer>> result = new HashMap<>();
ThreadReferenceProxy threadProxy = suspendContext.getThread();
ThreadReference thread = threadProxy != null ? threadProxy.getThreadReference() : null;
if (thread == null || hashCodeCaller == null) {
LOG.warn(thread == null ? "Thread is null" : "hashCode not found");
return result;
}
long start = System.nanoTime();
for (ObjectReference ref : references) {
Optional<Integer> hash = Optional.empty();
try {
if (!ref.isCollected()) {
ref.disableCollection();
if (!ref.isCollected()) {
hash = hashCodeCaller.eval(ref, suspendContext, thread);
}
ref.enableCollection();
}
} catch (InvalidTypeException | ClassNotLoadedException |
IncompatibleThreadStateException | InvocationException e) {
LOG.warn("Hash code evaluation failed", e);
}
result.put(ref, hash);
}
long duration = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - start);
LOG.info(String.format("Hash code evaluation: %d ms. Count = %d", duration, references.size()));
return result;
}
private Set<Integer> toSetOfHashes(@NotNull Map<ObjectReference, Optional<Integer>> ref2hashCode) {
return ref2hashCode.values().stream()
.filter(Optional::isPresent)
.map(Optional::get)
.collect(Collectors.toCollection(HashSet::new));
}
@Nullable
private MyHashCodeMethodWrapper getHashCodeMethod(@NotNull ReferenceType referenceType) {
if (myHashCodeWrapper != null) {
return myHashCodeWrapper;
}
final List<ReferenceType> referenceTypes = referenceType.virtualMachine().classesByName("java.util.Objects");
if (!referenceTypes.isEmpty()) {
ClassType objectsClass = (ClassType) referenceTypes.get(0);
Method hashCodeFromObjects = objectsClass.methodsByName("hashCode").stream()
.filter(method -> method.argumentTypeNames().size() == 1
&& "java.lang.Object".equals(method.argumentTypeNames().get(0)))
.findFirst()
.orElse(null);
myHashCodeWrapper = (ref, suspendContext, thread) -> {
final Value value = objectsClass.invokeMethod(thread, hashCodeFromObjects,
Collections.singletonList(ref), ClassType.INVOKE_SINGLE_THREADED);
return Optional.of(((IntegerValue) value).value());
};
} else {
final Method hashCode = referenceType.methodsByName("hashCode").stream()
.filter(method -> method.argumentTypeNames().isEmpty())
.findFirst()
.orElse(null);
myHashCodeWrapper = hashCode == null ? null : (ref, suspendContext, thread) -> {
final Value value = ref.invokeMethod(thread, hashCode, Collections.emptyList(), ClassType.INVOKE_SINGLE_THREADED);
return Optional.of(((IntegerValue) value).value());
};
}
return myHashCodeWrapper;
}
// WAIT_HASHES -> WAIT_UPDATE -> READY
enum MyState {
WAIT_HASHES {
@Override
public MyState next() {
return WAIT_UPDATE;
}
}, WAIT_UPDATE {
@Override
public MyState next() {
return READY;
}
}, READY {
@Override
public MyState next() {
return this;
}
};
public abstract MyState next();
}
private interface MyHashCodeMethodWrapper {
Optional<Integer> eval(@NotNull ObjectReference ref, @NotNull SuspendContextImpl suspendContext,
@NotNull ThreadReference thread) throws InvocationException, InvalidTypeException,
ClassNotLoadedException, IncompatibleThreadStateException;
}
}
@@ -1,37 +0,0 @@
package org.jetbrains.debugger.memory.tracking;
import com.intellij.debugger.engine.SuspendContextImpl;
import com.sun.jdi.ObjectReference;
import org.jetbrains.annotations.NotNull;
import java.util.List;
import java.util.stream.Collectors;
class IdentityBasedTracking extends InstanceTrackingStrategy {
private long myLastId = -1;
private int myCount = 0;
IdentityBasedTracking(@NotNull List<ObjectReference> initialInstances) {
myLastId = getMaxId(initialInstances);
}
@NotNull
@Override
protected List<ObjectReference> updateImpl(@NotNull SuspendContextImpl suspendContext,
@NotNull List<ObjectReference> references) {
List<ObjectReference> result = references.stream()
.filter(reference -> reference.uniqueID() > myLastId)
.collect(Collectors.toList());
myLastId = Math.max(myLastId, getMaxId(result));
myCount = result.size();
return result;
}
private long getMaxId(@NotNull List<ObjectReference> references) {
return references.stream().map(ObjectReference::uniqueID).max(Long::compare).orElse(-1L);
}
@Override
public int getCount() {
return myCount;
}
}
@@ -1,52 +0,0 @@
package org.jetbrains.debugger.memory.tracking;
import com.intellij.debugger.engine.SuspendContextImpl;
import com.sun.jdi.ObjectReference;
import com.sun.jdi.ReferenceType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public abstract class InstanceTrackingStrategy implements TrackerForNewInstances {
@NotNull
private List<ObjectReference> myNewInstances = new ArrayList<>();
private boolean myIsReady = false;
public static InstanceTrackingStrategy create(@NotNull ReferenceType referenceType,
@Nullable SuspendContextImpl suspendContext,
@NotNull TrackingType type,
@NotNull List<ObjectReference> init) {
switch (type) {
case IDENTITY:
return new IdentityBasedTracking(init);
case HASH:
return new HashBasedTracking(suspendContext, referenceType, init);
case RETAIN:
return new RetainReferencesTracking(init);
}
throw new UnsupportedOperationException("Such TrackingType not found");
}
@NotNull
public final List<ObjectReference> getNewInstances() {
return Collections.unmodifiableList(myNewInstances);
}
public final void update(@NotNull SuspendContextImpl suspendContext, @NotNull List<ObjectReference> references) {
myNewInstances = updateImpl(suspendContext, references);
myIsReady = true;
}
@Override
public boolean isReady() {
return myIsReady;
}
@NotNull
protected abstract List<ObjectReference> updateImpl(@NotNull SuspendContextImpl suspendContext,
@NotNull List<ObjectReference> references);
}
@@ -1,30 +0,0 @@
package org.jetbrains.debugger.memory.tracking;
import com.intellij.debugger.engine.SuspendContextImpl;
import com.sun.jdi.ObjectReference;
import org.jetbrains.annotations.NotNull;
import java.util.List;
class RetainReferencesTracking extends InstanceTrackingStrategy {
private final IdentityBasedTracking myIdTracker;
private List<ObjectReference> myHardRefs;
RetainReferencesTracking(@NotNull List<ObjectReference> initialInstances) {
myHardRefs = initialInstances;
myIdTracker = new IdentityBasedTracking(initialInstances);
}
@NotNull
@Override
protected List<ObjectReference> updateImpl(@NotNull SuspendContextImpl suspendContext,
@NotNull List<ObjectReference> references) {
myIdTracker.update(suspendContext, references);
myHardRefs = references;
return myIdTracker.getNewInstances();
}
@Override
public int getCount() {
return myHardRefs.size();
}
}
@@ -1,4 +1,19 @@
package org.jetbrains.debugger.memory.tracking;
/*
* Copyright 2000-2016 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.debugger.memory.tracking;
import com.sun.jdi.ObjectReference;
import org.jetbrains.annotations.NotNull;
@@ -1,32 +1,33 @@
package org.jetbrains.debugger.memory.tracking;
/*
* Copyright 2000-2016 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.debugger.memory.tracking;
import com.intellij.ui.JBColor;
import org.jetbrains.annotations.NotNull;
public enum TrackingType {
IDENTITY("Id Based Tracking",JBColor.yellow),
HASH("Hash Based Tracking", JBColor.yellow),
RETAIN("Retaining Reference Object Tracking", JBColor.yellow),
CREATION("Track Constructors", JBColor.orange);
CREATION("Track Constructors");
private final String myDescription;
private final JBColor myHighlighting;
TrackingType(@NotNull String description, @NotNull JBColor highlighting) {
TrackingType(@SuppressWarnings("SameParameterValue") @NotNull String description) {
myDescription = description;
myHighlighting = highlighting;
}
@NotNull
public JBColor color() {
return myHighlighting;
}
@NotNull
public String description() {
return myDescription;
}
public static JBColor inactiveColor() { return JBColor.GRAY; }
}
@@ -1,14 +1,34 @@
package org.jetbrains.debugger.memory.view;
/*
* Copyright 2000-2016 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.debugger.memory.ui;
import com.intellij.debugger.DebuggerManager;
import com.intellij.debugger.DebuggerManagerEx;
import com.intellij.debugger.engine.DebugProcessImpl;
import com.intellij.debugger.engine.SuspendContextImpl;
import com.intellij.debugger.engine.events.DebuggerCommandImpl;
import com.intellij.debugger.impl.DebuggerManagerImpl;
import com.intellij.debugger.memory.event.MemoryViewManagerListener;
import com.intellij.debugger.memory.utils.KeyboardUtils;
import com.intellij.debugger.memory.utils.LowestPriorityCommand;
import com.intellij.debugger.memory.utils.SingleAlarmWithMutableDelay;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.ActionGroup;
import com.intellij.openapi.actionSystem.ActionManager;
import com.intellij.openapi.actionSystem.ActionPopupMenu;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Disposer;
@@ -22,20 +42,16 @@ import com.sun.jdi.ReferenceType;
import com.sun.jdi.VirtualMachine;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.debugger.memory.component.CreationPositionTracker;
import org.jetbrains.debugger.memory.component.InstancesTracker;
import org.jetbrains.debugger.memory.component.MemoryViewManager;
import org.jetbrains.debugger.memory.component.MemoryViewManagerState;
import org.jetbrains.debugger.memory.event.InstancesTrackerListener;
import org.jetbrains.debugger.memory.event.MemoryViewManagerListener;
import org.jetbrains.debugger.memory.tracking.ClassPreparedListener;
import org.jetbrains.debugger.memory.tracking.ConstructorInstancesTracker;
import org.jetbrains.debugger.memory.tracking.TrackerForNewInstances;
import org.jetbrains.debugger.memory.tracking.TrackingType;
import org.jetbrains.debugger.memory.utils.AndroidUtil;
import org.jetbrains.debugger.memory.utils.KeyboardUtils;
import org.jetbrains.debugger.memory.utils.LowestPriorityCommand;
import org.jetbrains.debugger.memory.utils.SingleAlarmWithMutableDelay;
import com.intellij.debugger.memory.component.CreationPositionTracker;
import com.intellij.debugger.memory.component.InstancesTracker;
import com.intellij.debugger.memory.component.MemoryViewManager;
import com.intellij.debugger.memory.component.MemoryViewManagerState;
import com.intellij.debugger.memory.event.InstancesTrackerListener;
import com.intellij.debugger.memory.tracking.ClassPreparedListener;
import com.intellij.debugger.memory.tracking.ConstructorInstancesTracker;
import com.intellij.debugger.memory.tracking.TrackerForNewInstances;
import com.intellij.debugger.memory.tracking.TrackingType;
import com.intellij.debugger.memory.utils.AndroidUtil;
import javax.swing.FocusManager;
import javax.swing.*;
@@ -49,8 +65,8 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import java.util.stream.IntStream;
import static org.jetbrains.debugger.memory.view.ClassesTable.DiffViewTableModel.CLASSNAME_COLUMN_INDEX;
import static org.jetbrains.debugger.memory.view.ClassesTable.DiffViewTableModel.DIFF_COLUMN_INDEX;
import static com.intellij.debugger.memory.ui.ClassesTable.DiffViewTableModel.CLASSNAME_COLUMN_INDEX;
import static com.intellij.debugger.memory.ui.ClassesTable.DiffViewTableModel.DIFF_COLUMN_INDEX;
public class ClassesFilteredView extends BorderLayoutPanel implements Disposable {
private static final Logger LOG = Logger.getInstance(ClassesFilteredView.class);
@@ -221,7 +237,7 @@ public class ClassesFilteredView extends BorderLayoutPanel implements Disposable
@Override
public void sessionResumed() {
myConstructorTrackedClasses.values().forEach(ConstructorInstancesTracker::obsolete);
SwingUtilities.invokeLater(() -> {
ApplicationManager.getApplication().invokeLater(() -> {
myTable.getEmptyText().setText(EMPTY_TABLE_CONTENT_WHEN_RUNNING);
myTable.hideContent();
});
@@ -235,7 +251,7 @@ public class ClassesFilteredView extends BorderLayoutPanel implements Disposable
@Override
public void sessionPaused() {
SwingUtilities.invokeLater(() -> myTable.getEmptyText().setText(EMPTY_TABLE_CONTENT_WHEN_SUSPENDED));
ApplicationManager.getApplication().invokeLater(() -> myTable.getEmptyText().setText(EMPTY_TABLE_CONTENT_WHEN_SUSPENDED));
updateClassesAndCounts();
}
};
@@ -243,7 +259,7 @@ public class ClassesFilteredView extends BorderLayoutPanel implements Disposable
mySingleAlarm = new SingleAlarmWithMutableDelay(() -> {
myLastSuspendContext = getSuspendContext();
if (myLastSuspendContext != null) {
SwingUtilities.invokeLater(() -> myTable.setBusy(true));
ApplicationManager.getApplication().invokeLater(() -> myTable.setBusy(true));
myDebugProcess.getManagerThread()
.schedule(new MyUpdateClassesCommand(myLastSuspendContext));
}
@@ -287,7 +303,7 @@ public class ClassesFilteredView extends BorderLayoutPanel implements Disposable
tracker.disable();
}
Disposer.register(ClassesFilteredView.this, tracker);
Disposer.register(this, tracker);
myConstructorTrackedClasses.put(ref, tracker);
}
}
@@ -303,7 +319,7 @@ public class ClassesFilteredView extends BorderLayoutPanel implements Disposable
}
private SuspendContextImpl getSuspendContext() {
return DebuggerManagerImpl.getInstanceEx(myProject).getContext().getSuspendContext();
return DebuggerManagerEx.getInstanceEx(myProject).getContext().getSuspendContext();
}
private void updateClassesAndCounts() {
@@ -312,9 +328,9 @@ public class ClassesFilteredView extends BorderLayoutPanel implements Disposable
}
}
private ActionPopupMenu createContextMenu() {
ActionGroup group = (ActionGroup) ActionManager.getInstance().getAction("ClassesView.PopupActionGroup");
return ActionManager.getInstance().createActionPopupMenu("ClassesView.PopupActionGroup", group);
private static ActionPopupMenu createContextMenu() {
ActionGroup group = (ActionGroup) ActionManager.getInstance().getAction("MemoryView.ClassesPopupActionGroup");
return ActionManager.getInstance().createActionPopupMenu("MemoryView.ClassesPopupActionGroup", group);
}
@Override
@@ -340,7 +356,7 @@ public class ClassesFilteredView extends BorderLayoutPanel implements Disposable
}
private void doActivate() {
myDebugSession.addSessionListener(myDebugSessionListener, ClassesFilteredView.this);
myDebugSession.addSessionListener(myDebugSessionListener, this);
myConstructorTrackedClasses.values().forEach(x -> x.setBackgroundMode(false));
final SuspendContextImpl lastContext = myLastSuspendContext;
if (lastContext == null || !lastContext.equals(getSuspendContext())) {
@@ -400,10 +416,10 @@ public class ClassesFilteredView extends BorderLayoutPanel implements Disposable
final long[] counts = chunks.size() == 1 ? chunks.get(0) : IntStream.range(0, chunks.size()).boxed()
.flatMapToLong(integer -> Arrays.stream(chunks.get(integer)))
.toArray();
SwingUtilities.invokeLater(() -> myTable.setClassesAndUpdateCounts(classes, counts));
ApplicationManager.getApplication().invokeLater(() -> myTable.setClassesAndUpdateCounts(classes, counts));
}
SwingUtilities.invokeLater(() -> myTable.setBusy(false));
ApplicationManager.getApplication().invokeLater(() -> myTable.setBusy(false));
}
private boolean isContextValid() {
@@ -411,7 +427,7 @@ public class ClassesFilteredView extends BorderLayoutPanel implements Disposable
}
}
private class FilterTextField extends SearchTextField {
private static class FilterTextField extends SearchTextField {
FilterTextField() {
super(false);
}
@@ -1,5 +1,24 @@
package org.jetbrains.debugger.memory.view;
/*
* Copyright 2000-2016 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.debugger.memory.ui;
import com.intellij.debugger.memory.component.InstancesTracker;
import com.intellij.debugger.memory.utils.AbstractTableColumnDescriptor;
import com.intellij.debugger.memory.utils.AbstractTableModelWithColumns;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.DataKey;
import com.intellij.openapi.actionSystem.DataProvider;
@@ -17,16 +36,12 @@ import com.intellij.util.ui.JBUI;
import com.intellij.xdebugger.XDebugSession;
import com.sun.jdi.ObjectReference;
import com.sun.jdi.ReferenceType;
import icons.MemoryViewIcons;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.debugger.memory.component.InstancesTracker;
import org.jetbrains.debugger.memory.tracking.TrackerForNewInstances;
import org.jetbrains.debugger.memory.tracking.TrackingType;
import org.jetbrains.debugger.memory.utils.AbstractTableColumnDescriptor;
import org.jetbrains.debugger.memory.utils.AbstractTableModelWithColumns;
import org.jetbrains.debugger.memory.utils.InstancesProvider;
import com.intellij.debugger.memory.tracking.TrackerForNewInstances;
import com.intellij.debugger.memory.tracking.TrackingType;
import com.intellij.debugger.memory.utils.InstancesProvider;
import javax.swing.*;
import javax.swing.border.Border;
@@ -39,9 +54,9 @@ public class ClassesTable extends JBTable implements DataProvider, Disposable {
public static final DataKey<ReferenceType> SELECTED_CLASS_KEY = DataKey.create("ClassesTable.SelectedClass");
public static final DataKey<XDebugSession> DEBUG_SESSION_KEY = DataKey.create("ClassesTable.DebugSession");
public static final DataKey<InstancesProvider> NEW_INSTANCES_PROVIDER_KEY =
DataKey.create("ClassesTable.NewInstances");
DataKey.create("ClassesTable.NewInstances");
public static final DataKey<ReferenceCountProvider> REF_COUNT_PROVIDER_KEY =
DataKey.create("ClassesTable.ReferenceCountProvider");
DataKey.create("ClassesTable.ReferenceCountProvider");
private static final Border EMPTY_BORDER = BorderFactory.createEmptyBorder();
@@ -63,7 +78,7 @@ public class ClassesTable extends JBTable implements DataProvider, Disposable {
private MinusculeMatcher myMatcher = NameUtil.buildMatcher("*").build();
private String myFilteringPattern = "";
private volatile List<ReferenceType> myElems = Collections.unmodifiableList(new ArrayList<>());
private volatile List<ReferenceType> myItems = Collections.unmodifiableList(new ArrayList<>());
ClassesTable(@NotNull XDebugSession session, boolean onlyWithDiff, boolean onlyWithInstances,
boolean onlyTracked, @NotNull ClassesFilteredView parent) {
@@ -99,20 +114,20 @@ public class ClassesTable extends JBTable implements DataProvider, Disposable {
@Override
public boolean include(Entry<? extends DiffViewTableModel, ? extends Integer> entry) {
int ix = entry.getIdentifier();
ReferenceType ref = myElems.get(ix);
ReferenceType ref = myItems.get(ix);
DiffValue diff = myCounts.getOrDefault(ref, myUnknownValue);
boolean isFilteringOptionsRefused = myOnlyWithDiff && diff.diff() == 0
|| myOnlyWithInstances && !diff.hasInstance()
|| myOnlyTracked && myParent.getStrategy(ref) == null;
|| myOnlyWithInstances && !diff.hasInstance()
|| myOnlyTracked && myParent.getStrategy(ref) == null;
return !(isFilteringOptionsRefused) && myMatcher.matches(ref.name());
}
});
List<RowSorter.SortKey> myDefaultSortingKeys = Arrays.asList(
new RowSorter.SortKey(DiffViewTableModel.DIFF_COLUMN_INDEX, SortOrder.DESCENDING),
new RowSorter.SortKey(DiffViewTableModel.COUNT_COLUMN_INDEX, SortOrder.DESCENDING),
new RowSorter.SortKey(DiffViewTableModel.CLASSNAME_COLUMN_INDEX, SortOrder.ASCENDING)
new RowSorter.SortKey(DiffViewTableModel.DIFF_COLUMN_INDEX, SortOrder.DESCENDING),
new RowSorter.SortKey(DiffViewTableModel.COUNT_COLUMN_INDEX, SortOrder.DESCENDING),
new RowSorter.SortKey(DiffViewTableModel.CLASSNAME_COLUMN_INDEX, SortOrder.ASCENDING)
);
sorter.setSortKeys(myDefaultSortingKeys);
setRowSorter(sorter);
@@ -121,12 +136,12 @@ public class ClassesTable extends JBTable implements DataProvider, Disposable {
myCountProvider = new ReferenceCountProvider() {
@Override
public int getTotalCount(@NotNull ReferenceType ref) {
return (int) myCounts.get(ref).myCurrentCount;
return (int)myCounts.get(ref).myCurrentCount;
}
@Override
public int getDiffCount(@NotNull ReferenceType ref) {
return (int) myCounts.get(ref).diff();
return (int)myCounts.get(ref).diff();
}
@Override
@@ -150,7 +165,7 @@ public class ClassesTable extends JBTable implements DataProvider, Disposable {
int selectedRow = getSelectedRow();
if (selectedRow != -1) {
int ix = convertRowIndexToModel(selectedRow);
return myElems.get(ix);
return myItems.get(ix);
}
return null;
@@ -158,7 +173,7 @@ public class ClassesTable extends JBTable implements DataProvider, Disposable {
@Nullable
ReferenceType getClassByName(@NotNull String name) {
for (ReferenceType ref : myElems) {
for (ReferenceType ref : myItems) {
if (name.equals(ref.name())) {
return ref;
}
@@ -207,14 +222,14 @@ public class ClassesTable extends JBTable implements DataProvider, Disposable {
assert classes.size() == counts.length;
ReferenceType selectedClass = myModel.getSelectedClassBeforeHided();
int newSelectedIndex = classes.indexOf(selectedClass);
boolean isInitialized = !myElems.isEmpty();
myElems = Collections.unmodifiableList(new ArrayList<>(classes));
boolean isInitialized = !myItems.isEmpty();
myItems = Collections.unmodifiableList(new ArrayList<>(classes));
for (int i = 0, size = classes.size(); i < size; i++) {
ReferenceType ref = classes.get(i);
DiffValue oldValue = isInitialized && !myCounts.containsKey(ref)
? new DiffValue(0, 0)
: myCounts.getOrDefault(ref, myUnknownValue);
? new DiffValue(0, 0)
: myCounts.getOrDefault(ref, myUnknownValue);
myCounts.put(ref, oldValue.update(counts[i]));
}
@@ -223,7 +238,7 @@ public class ClassesTable extends JBTable implements DataProvider, Disposable {
if (newSelectedIndex != -1 && !myModel.isHided()) {
int ix = convertRowIndexToView(newSelectedIndex);
changeSelection(ix,
DiffViewTableModel.CLASSNAME_COLUMN_INDEX, false, false);
DiffViewTableModel.CLASSNAME_COLUMN_INDEX, false, false);
}
getRowSorter().allRowsChanged();
@@ -253,7 +268,7 @@ public class ClassesTable extends JBTable implements DataProvider, Disposable {
TrackerForNewInstances strategy = myParent.getStrategy(selectedClass);
if (strategy != null && strategy.isReady()) {
List<ObjectReference> newInstances = strategy.getNewInstances();
return (InstancesProvider) limit -> newInstances;
return (InstancesProvider)limit -> newInstances;
}
}
}
@@ -271,7 +286,7 @@ public class ClassesTable extends JBTable implements DataProvider, Disposable {
@Nullable
private TrackingType getTrackingType(int row) {
ReferenceType ref = (ReferenceType) getValueAt(row, convertColumnIndexToView(DiffViewTableModel.CLASSNAME_COLUMN_INDEX));
ReferenceType ref = (ReferenceType)getValueAt(row, convertColumnIndexToView(DiffViewTableModel.CLASSNAME_COLUMN_INDEX));
return myInstancesTracker.getTrackingType(ref.name());
}
@@ -286,24 +301,24 @@ public class ClassesTable extends JBTable implements DataProvider, Disposable {
DiffViewTableModel() {
super(new AbstractTableColumnDescriptor[]{
new AbstractTableColumnDescriptor("Class", ReferenceType.class) {
@Override
public Object getValue(int ix) {
return myElems.get(ix);
}
},
new AbstractTableColumnDescriptor("Count", Long.class) {
@Override
public Object getValue(int ix) {
return myCounts.getOrDefault(myElems.get(ix), myUnknownValue).myCurrentCount;
}
},
new AbstractTableColumnDescriptor("Diff", DiffValue.class) {
@Override
public Object getValue(int ix) {
return myCounts.getOrDefault(myElems.get(ix), myUnknownValue);
}
new AbstractTableColumnDescriptor("Class", ReferenceType.class) {
@Override
public Object getValue(int ix) {
return myItems.get(ix);
}
},
new AbstractTableColumnDescriptor("Count", Long.class) {
@Override
public Object getValue(int ix) {
return myCounts.getOrDefault(myItems.get(ix), myUnknownValue).myCurrentCount;
}
},
new AbstractTableColumnDescriptor("Diff", DiffValue.class) {
@Override
public Object getValue(int ix) {
return myCounts.getOrDefault(myItems.get(ix), myUnknownValue);
}
}
});
}
@@ -333,7 +348,7 @@ public class ClassesTable extends JBTable implements DataProvider, Disposable {
@Override
public int getRowCount() {
return myIsWithContent ? myElems.size() : 0;
return myIsWithContent ? myItems.size() : 0;
}
}
@@ -408,34 +423,34 @@ public class ClassesTable extends JBTable implements DataProvider, Disposable {
}
if (trackingType != null && column == DiffViewTableModel.DIFF_COLUMN_INDEX) {
setIcon(MemoryViewIcons.CLASS_TRACKED);
setIcon(AllIcons.Debugger.MemoryView.ClassTracked);
setTransparentIconBackground(true);
}
if (value != null) {
addText(table, value, isSelected, hasFocus, row, column);
addText(value, isSelected, row);
}
}
protected abstract void addText(JTable table, @NotNull Object value, boolean isSelected,
boolean hasFocus, int row, int column);
protected abstract void addText(@NotNull Object value, boolean isSelected, int row);
}
private class MyClassColumnRenderer extends MyTableCellRenderer {
@Override
protected void addText(JTable table, @NotNull Object value, boolean isSelected,
boolean hasFocus, int row, int column) {
String presentation = ((ReferenceType) value).name();
protected void addText(@NotNull Object value, boolean isSelected,
int row) {
String presentation = ((ReferenceType)value).name();
append(" ");
if (isSelected) {
FList<TextRange> textRanges = myMatcher.matchingFragments(presentation);
if (textRanges != null) {
SimpleTextAttributes attributes = new SimpleTextAttributes(getBackground(), getForeground(), null,
SimpleTextAttributes.STYLE_SEARCH_MATCH);
SimpleTextAttributes.STYLE_SEARCH_MATCH);
SpeedSearchUtil.appendColoredFragments(this, presentation, textRanges,
SimpleTextAttributes.REGULAR_ATTRIBUTES, attributes);
SimpleTextAttributes.REGULAR_ATTRIBUTES, attributes);
}
} else {
}
else {
append(String.format("%s", presentation), SimpleTextAttributes.REGULAR_ATTRIBUTES);
}
}
@@ -443,8 +458,8 @@ public class ClassesTable extends JBTable implements DataProvider, Disposable {
private class MyCountColumnRenderer extends MyTableCellRenderer {
@Override
protected void addText(JTable table, @NotNull Object value, boolean isSelected,
boolean hasFocus, int row, int column) {
protected void addText(@NotNull Object value, boolean isSelected,
int row) {
setTextAlign(SwingConstants.RIGHT);
append(value.toString());
}
@@ -452,14 +467,14 @@ public class ClassesTable extends JBTable implements DataProvider, Disposable {
private class MyDiffColumnRenderer extends MyTableCellRenderer {
private final SimpleTextAttributes myClickableCellAttributes =
new SimpleTextAttributes(SimpleTextAttributes.STYLE_UNDERLINE, JBColor.BLUE);
new SimpleTextAttributes(SimpleTextAttributes.STYLE_UNDERLINE, JBColor.BLUE);
@Override
protected void addText(JTable table, @NotNull Object value, boolean isSelected,
boolean hasFocus, int row, int column) {
protected void addText(@NotNull Object value, boolean isSelected,
int row) {
setTextAlign(SwingConstants.RIGHT);
ReferenceType ref = myElems.get(convertRowIndexToModel(row));
ReferenceType ref = myItems.get(convertRowIndexToModel(row));
long diff = myCountProvider.getDiffCount(ref);
String text = String.format("%s%d", diff > 0 ? "+" : "", diff);
@@ -468,13 +483,15 @@ public class ClassesTable extends JBTable implements DataProvider, Disposable {
if (newInstancesCount >= 0) {
if (newInstancesCount == diff) {
append(text, diff == 0 ? SimpleTextAttributes.REGULAR_ATTRIBUTES : myClickableCellAttributes);
} else {
}
else {
append(text, SimpleTextAttributes.REGULAR_ATTRIBUTES);
if (newInstancesCount != 0) {
append(String.format(" (%d)", newInstancesCount), myClickableCellAttributes);
}
}
} else {
}
else {
append(text, SimpleTextAttributes.REGULAR_ATTRIBUTES);
}
}
@@ -1,4 +1,19 @@
package org.jetbrains.debugger.memory.view;
/*
* Copyright 2000-2016 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.debugger.memory.ui;
import com.intellij.codeInsight.lookup.LookupManager;
import com.intellij.debugger.engine.DebuggerUtils;
@@ -14,10 +29,10 @@ import com.intellij.openapi.ui.popup.util.BaseListPopupStep;
import com.intellij.psi.PsiClass;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.ui.ColoredListCellRenderer;
import com.intellij.ui.SimpleTextAttributes;
import com.intellij.ui.popup.list.ListPopupImpl;
import com.intellij.xdebugger.XExpression;
import com.intellij.xdebugger.evaluation.XDebuggerEditorsProvider;
import com.intellij.xdebugger.impl.XSourcePositionImpl;
import com.intellij.xdebugger.impl.breakpoints.XExpressionImpl;
import com.intellij.xdebugger.impl.ui.XDebuggerExpressionEditor;
import org.jetbrains.annotations.NotNull;
@@ -34,7 +49,7 @@ class ExpressionEditorWithHistory extends XDebuggerExpressionEditor {
final @NotNull XDebuggerEditorsProvider debuggerEditorsProvider,
final @Nullable Disposable parentDisposable) {
super(project, debuggerEditorsProvider, HISTORY_ID_PREFIX + className, null,
XExpressionImpl.EMPTY_EXPRESSION, false, true, true);
XExpressionImpl.EMPTY_EXPRESSION, false, true, true);
new AnAction("InstancesWindow.ShowHistory") {
@Override
@@ -53,9 +68,8 @@ class ExpressionEditorWithHistory extends XDebuggerExpressionEditor {
protected Void doInBackground() throws Exception {
ApplicationManager.getApplication().runReadAction(() -> {
final PsiClass psiClass = DebuggerUtils.findClass(className,
project, GlobalSearchScope.allScope(project));
XSourcePositionImpl position = XSourcePositionImpl.createByElement(psiClass);
SwingUtilities.invokeLater(() -> setSourcePosition(position));
project, GlobalSearchScope.allScope(project));
ApplicationManager.getApplication().invokeLater(() -> setContext(psiClass));
});
return null;
}
@@ -79,7 +93,7 @@ class ExpressionEditorWithHistory extends XDebuggerExpressionEditor {
@Override
protected void customizeCellRenderer(@NotNull JList list, XExpression value, int index,
boolean selected, boolean hasFocus) {
append(value.getExpression());
append(value.getExpression(), SimpleTextAttributes.REGULAR_ATTRIBUTES);
}
};
}
@@ -1,5 +1,21 @@
package org.jetbrains.debugger.memory.view;
/*
* Copyright 2000-2016 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.debugger.memory.ui;
import com.intellij.debugger.memory.filtering.FilteringResult;
import com.intellij.icons.AllIcons;
import com.intellij.ui.JBProgressBar;
import com.intellij.ui.components.JBLabel;
@@ -7,7 +23,6 @@ import com.intellij.util.ui.UIUtil;
import com.intellij.util.ui.components.BorderLayoutPanel;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.debugger.memory.view.InstancesWindow.FilteringCompletionReason;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
@@ -19,7 +34,7 @@ class FilteringProgressView extends BorderLayoutPanel {
private final JBProgressBar myProgressBar = new JBProgressBar();
private final BorderLayoutPanel myProgressPanel = new BorderLayoutPanel();
private final JBLabel myStopButton = new JBLabel(UIUtil.isUnderDarcula()
? AllIcons.Actions.Clean : AllIcons.Actions.CleanLight);
? AllIcons.Actions.Clean : AllIcons.Actions.CleanLight);
private final JBLabel myProgressText = new JBLabel();
private int myProceedCount = 0;
@@ -29,7 +44,7 @@ class FilteringProgressView extends BorderLayoutPanel {
private boolean myIsInProcess = false;
@Nullable
private FilteringCompletionReason myCompletionReason = null;
private FilteringResult myCompletionReason = null;
FilteringProgressView() {
myStopButton.setOpaque(true);
@@ -50,9 +65,9 @@ class FilteringProgressView extends BorderLayoutPanel {
void updateProgress(int proceedCount, int matchedCount, int errorCount) {
if (myIsInProcess) {
myProceedCount += proceedCount;
myMatchedCount += matchedCount;
myErrorCount += errorCount;
myProceedCount = proceedCount;
myMatchedCount = matchedCount;
myErrorCount = errorCount;
myProgressBar.setValue(myProceedCount);
myProgressText.setText(getDescription());
}
@@ -68,7 +83,7 @@ class FilteringProgressView extends BorderLayoutPanel {
setProgressBarVisible(true);
}
void complete(@NotNull FilteringCompletionReason reason) {
void complete(@NotNull FilteringResult reason) {
if (!myIsInProcess) {
throw new IllegalStateException("First you need to start progress");
}
@@ -1,4 +1,19 @@
package org.jetbrains.debugger.memory.view;
/*
* Copyright 2000-2016 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.debugger.memory.ui;
import com.intellij.debugger.ui.impl.watch.NodeDescriptorProvider;
import com.intellij.debugger.ui.tree.NodeDescriptor;
@@ -11,6 +26,7 @@ import com.intellij.xdebugger.evaluation.XDebuggerEditorsProvider;
import com.intellij.xdebugger.frame.*;
import com.intellij.xdebugger.impl.actions.XDebuggerActions;
import com.intellij.xdebugger.impl.frame.XValueMarkers;
import com.intellij.xdebugger.impl.ui.XDebuggerUIConstants;
import com.intellij.xdebugger.impl.ui.tree.XDebuggerTree;
import com.intellij.xdebugger.impl.ui.tree.XDebuggerTreeState;
import com.intellij.xdebugger.impl.ui.tree.nodes.XValueNodeImpl;
@@ -20,7 +36,6 @@ import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import javax.swing.tree.TreePath;
import java.util.ArrayList;
import java.util.List;
@@ -70,10 +85,10 @@ public class InstancesTree extends XDebuggerTree {
rebuildTree(policy, XDebuggerTreeState.saveState(this));
}
void setMessage(@Nullable Icon icon, @NotNull String text, @NotNull SimpleTextAttributes textAttributes) {
void setInfoMessage(@SuppressWarnings("SameParameterValue") @NotNull String text) {
myChildren = null;
myRoot.clearChildren();
myRoot.setMessage(text, icon, textAttributes, null);
myRoot.setMessage(text, XDebuggerUIConstants.INFORMATION_MESSAGE_ICON, SimpleTextAttributes.REGULAR_ATTRIBUTES, null);
}
@Nullable
@@ -1,33 +1,47 @@
package org.jetbrains.debugger.memory.view;
/*
* Copyright 2000-2016 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.debugger.memory.ui;
import com.intellij.debugger.DebuggerManager;
import com.intellij.debugger.engine.DebugProcessImpl;
import com.intellij.debugger.engine.JavaValue;
import com.intellij.debugger.engine.SuspendContextImpl;
import com.intellij.debugger.engine.evaluation.EvaluateException;
import com.intellij.debugger.engine.evaluation.EvaluationContext;
import com.intellij.debugger.engine.evaluation.EvaluationContextImpl;
import com.intellij.debugger.engine.evaluation.TextWithImportsImpl;
import com.intellij.debugger.engine.evaluation.expression.ExpressionEvaluator;
import com.intellij.debugger.engine.events.DebuggerContextCommandImpl;
import com.intellij.debugger.memory.filtering.FilteringResult;
import com.intellij.debugger.memory.filtering.FilteringTask;
import com.intellij.debugger.memory.filtering.FilteringTaskCallback;
import com.intellij.debugger.memory.utils.*;
import com.intellij.debugger.ui.impl.watch.DebuggerTreeNodeImpl;
import com.intellij.debugger.ui.impl.watch.MessageDescriptor;
import com.intellij.debugger.ui.impl.watch.NodeManagerImpl;
import com.intellij.debugger.ui.tree.NodeDescriptor;
import com.intellij.debugger.ui.tree.render.CachedEvaluator;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.actionSystem.ex.AnActionListener;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.wm.IdeFocusManager;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.ui.DoubleClickListener;
import com.intellij.ui.JBColor;
import com.intellij.ui.SimpleTextAttributes;
import com.intellij.ui.components.JBLabel;
import com.intellij.ui.components.JBPanel;
import com.intellij.util.ui.JBDimension;
@@ -43,17 +57,13 @@ import com.intellij.xdebugger.impl.XDebugSessionImpl;
import com.intellij.xdebugger.impl.actions.XDebuggerActionBase;
import com.intellij.xdebugger.impl.frame.XValueMarkers;
import com.intellij.xdebugger.impl.ui.XDebuggerExpressionEditor;
import com.intellij.xdebugger.impl.ui.XDebuggerUIConstants;
import com.intellij.xdebugger.impl.ui.tree.ValueMarkup;
import com.intellij.xdebugger.impl.ui.tree.XDebuggerTreeState;
import com.intellij.xdebugger.impl.ui.tree.actions.XDebuggerTreeActionBase;
import com.intellij.xdebugger.impl.ui.tree.nodes.XValueNodeImpl;
import com.sun.jdi.BooleanValue;
import com.sun.jdi.ObjectReference;
import com.sun.jdi.Value;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.debugger.memory.utils.*;
import org.jetbrains.java.debugger.JavaDebuggerEditorsProvider;
import javax.swing.*;
@@ -63,9 +73,6 @@ import java.awt.event.MouseEvent;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import static java.lang.Math.min;
public class InstancesWindow extends DialogWrapper {
private static final Logger LOG = Logger.getInstance(InstancesWindow.class);
@@ -74,7 +81,7 @@ public class InstancesWindow extends DialogWrapper {
private static final int DEFAULT_WINDOW_HEIGHT = 400;
private static final int FILTERING_BUTTON_ADDITIONAL_WIDTH = 30;
private static final int BORDER_LAYOUT_DEFAULT_GAP = 5;
private static final int DEFAULT_INSTANCES_LIMIT = 500000; // All
private static final int DEFAULT_INSTANCES_LIMIT = 500000;
private final Project myProject;
private final XDebugSession myDebugSession;
@@ -96,7 +103,7 @@ public class InstancesWindow extends DialogWrapper {
myDebugSession.addSessionListener(new XDebugSessionListener() {
@Override
public void sessionStopped() {
SwingUtilities.invokeLater(() -> close(OK_EXIT_CODE));
ApplicationManager.getApplication().invokeLater(() -> close(OK_EXIT_CODE));
}
}, myDisposable);
setModal(false);
@@ -105,10 +112,6 @@ public class InstancesWindow extends DialogWrapper {
root.setDefaultButton(myInstancesView.myFilterButton);
}
enum FilteringCompletionReason {
ALL_CHECKED, INTERRUPTED, LIMIT_REACHED
}
private void addWarningMessage(@Nullable String message) {
String warning = message == null ? "" : String.format(". Warning: %s", message);
setTitle(String.format("Instances of %s%s", myClassName, warning));
@@ -125,7 +128,7 @@ public class InstancesWindow extends DialogWrapper {
protected JComponent createCenterPanel() {
myInstancesView = new MyInstancesView();
myInstancesView.setPreferredSize(
new JBDimension(DEFAULT_WINDOW_WIDTH, DEFAULT_WINDOW_HEIGHT));
new JBDimension(DEFAULT_WINDOW_WIDTH, DEFAULT_WINDOW_HEIGHT));
return myInstancesView;
}
@@ -154,7 +157,6 @@ public class InstancesWindow extends DialogWrapper {
private final XDebuggerExpressionEditor myFilterConditionEditor;
private final XDebugSessionListener myDebugSessionListener = new MySessionListener();
private final MyCachedEvaluator myEvaluator = new MyCachedEvaluator();
private final MyNodeManager myNodeManager = new MyNodeManager(myProject);
private final JButton myFilterButton = new JButton("Filter");
@@ -170,19 +172,19 @@ public class InstancesWindow extends DialogWrapper {
MyInstancesView() {
super(new BorderLayout(0, JBUI.scale(BORDER_LAYOUT_DEFAULT_GAP)));
Disposer.register(InstancesWindow.this.myDisposable, MyInstancesView.this);
Disposer.register(InstancesWindow.this.myDisposable, this);
XValueMarkers<?, ?> markers = getValueMarkers();
ActionManager.getInstance().addAnActionListener(myActionListener, InstancesWindow.this.myDisposable);
myDebugSession.addSessionListener(myDebugSessionListener, InstancesWindow.this.myDisposable);
JavaDebuggerEditorsProvider editorsProvider = new JavaDebuggerEditorsProvider();
myFilterConditionEditor = new ExpressionEditorWithHistory(myProject, myClassName,
editorsProvider, InstancesWindow.this.myDisposable);
editorsProvider, InstancesWindow.this.myDisposable);
myFilterButton.setBorder(BorderFactory.createEmptyBorder());
Dimension filteringButtonSize = myFilterConditionEditor.getEditorComponent().getPreferredSize();
filteringButtonSize.width = JBUI.scale(FILTERING_BUTTON_ADDITIONAL_WIDTH) +
myFilterButton.getPreferredSize().width;
myFilterButton.getPreferredSize().width;
myFilterButton.setPreferredSize(filteringButtonSize);
JBPanel filteringPane = new JBPanel(new BorderLayout(JBUI.scale(BORDER_LAYOUT_DEFAULT_GAP), 0));
@@ -212,8 +214,8 @@ public class InstancesWindow extends DialogWrapper {
StackFrameList list = new StackFrameList(myProject,
Collections.emptyList(),
GlobalSearchScope.allScope(myProject));
Collections.emptyList(),
GlobalSearchScope.allScope(myProject));
list.addListSelectionListener(e -> list.navigateToSelectedValue(false));
new DoubleClickListener() {
@@ -225,15 +227,15 @@ public class InstancesWindow extends DialogWrapper {
}.installOn(list);
InstancesWithStackFrameView instancesWithStackFrame = new InstancesWithStackFrameView(myDebugSession,
myInstancesTree, list, myClassName);
myInstancesTree, list, myClassName);
add(filteringPane, BorderLayout.NORTH);
add(instancesWithStackFrame.getComponent(), BorderLayout.CENTER);
JComponent focusedComponent = myFilterConditionEditor.getEditorComponent();
UiNotifyConnector.doWhenFirstShown(focusedComponent, () ->
IdeFocusManager.findInstanceByComponent(focusedComponent)
.requestFocus(focusedComponent, true));
IdeFocusManager.findInstanceByComponent(focusedComponent)
.requestFocus(focusedComponent, true));
}
@Override
@@ -243,8 +245,8 @@ public class InstancesWindow extends DialogWrapper {
}
private void updateInstances() {
DebugProcessImpl debugProcess = (DebugProcessImpl) DebuggerManager.getInstance(myProject)
.getDebugProcess(myDebugSession.getDebugProcess().getProcessHandler());
DebugProcessImpl debugProcess = (DebugProcessImpl)DebuggerManager.getInstance(myProject)
.getDebugProcess(myDebugSession.getDebugProcess().getProcessHandler());
cancelFilteringTask();
@@ -258,49 +260,28 @@ public class InstancesWindow extends DialogWrapper {
public void threadAction(@NotNull SuspendContextImpl suspendContext) {
myIsAndroidVM = AndroidUtil.isAndroidVM(debugProcess.getVirtualMachineProxy().getVirtualMachine());
int limit = myIsAndroidVM
? AndroidUtil.ANDROID_INSTANCES_LIMIT
: DEFAULT_INSTANCES_LIMIT;
? AndroidUtil.ANDROID_INSTANCES_LIMIT
: DEFAULT_INSTANCES_LIMIT;
List<ObjectReference> instances = myInstancesProvider.getInstances(limit + 1);
EvaluationContextImpl evaluationContext = debugProcess
.getDebuggerContext().createEvaluationContext();
.getDebuggerContext().createEvaluationContext();
if (instances.size() > limit) {
addWarningMessage(String.format("Not all instances will be loaded (only %d)", limit));
instances = instances.subList(0, limit);
}
final int progressSize = instances.size();
if (evaluationContext != null) {
synchronized (myFilteringTaskLock) {
myFilteringTask = new MyFilteringWorker(instances, evaluationContext, createEvaluator());
SwingUtilities.invokeLater(() -> {
myProgress.start(progressSize);
myFilteringTask.execute();
});
myFilteringTask = new MyFilteringWorker(instances, myFilterConditionEditor.getExpression(), evaluationContext);
myFilteringTask.execute();
}
}
}
});
}
@Nullable
private ExpressionEvaluator createEvaluator() {
ExpressionEvaluator evaluator = null;
XExpression expression = myFilterConditionEditor.getExpression();
if (expression != null && !expression.getExpression().isEmpty()) {
try {
myEvaluator.setReferenceExpression(TextWithImportsImpl.fromXExpression(expression));
evaluator = myEvaluator.getEvaluator();
} catch (EvaluateException ignored) {
LOG.info("cannot create evaluator by the expression = " + expression.getExpression());
}
}
return evaluator;
}
private void cancelFilteringTask() {
if (myFilteringTask != null) {
synchronized (myFilteringTaskLock) {
@@ -314,8 +295,8 @@ public class InstancesWindow extends DialogWrapper {
private XValueMarkers<?, ?> getValueMarkers() {
return myDebugSession instanceof XDebugSessionImpl
? ((XDebugSessionImpl) myDebugSession).getValueMarkers()
: null;
? ((XDebugSessionImpl)myDebugSession).getValueMarkers()
: null;
}
private class MySessionListener implements XDebugSessionListener {
@@ -323,18 +304,18 @@ public class InstancesWindow extends DialogWrapper {
@Override
public void sessionResumed() {
SwingUtilities.invokeLater(() -> {
ApplicationManager.getApplication().invokeLater(() -> {
myTreeState = XDebuggerTreeState.saveState(myInstancesTree);
cancelFilteringTask();
myInstancesTree.setMessage(XDebuggerUIConstants.INFORMATION_MESSAGE_ICON,
"The application is running", SimpleTextAttributes.REGULAR_ATTRIBUTES);
myInstancesTree.setInfoMessage(
"The application is running");
});
}
@Override
public void sessionPaused() {
SwingUtilities.invokeLater(() -> {
ApplicationManager.getApplication().invokeLater(() -> {
myProgress.setVisible(true);
myInstancesTree.rebuildTree(InstancesTree.RebuildPolicy.RELOAD_INSTANCES, myTreeState);
});
@@ -346,8 +327,8 @@ public class InstancesWindow extends DialogWrapper {
public void beforeActionPerformed(AnAction action, DataContext dataContext, AnActionEvent event) {
if (dataContext.getData(PlatformDataKeys.CONTEXT_COMPONENT) == myInstancesView.myInstancesTree &&
(isAddToWatchesAction(action) || isEvaluateExpressionAction(action))) {
XValueNodeImpl selectedNode = XDebuggerTreeActionBase.getSelectedNode(dataContext);
XValueMarkers<?, ?> markers = getValueMarkers();
final XValueNodeImpl selectedNode = XDebuggerTreeActionBase.getSelectedNode(dataContext);
final XValueMarkers<?, ?> markers = getValueMarkers();
if (markers != null && selectedNode != null) {
@@ -356,175 +337,143 @@ public class InstancesWindow extends DialogWrapper {
currentNode = currentNode.getParent();
}
XValue valueContainer = ((XValueNodeImpl) currentNode).getValueContainer();
final XValue valueContainer = ((XValueNodeImpl)currentNode).getValueContainer();
String expression = valueContainer.getEvaluationExpression();
final String expression = valueContainer.getEvaluationExpression();
if (expression != null) {
markers.markValue(valueContainer,
new ValueMarkup(expression.replace("@", ""), new JBColor(0, 0), null));
new ValueMarkup(expression.replace("@", ""), new JBColor(0, 0), null));
}
SwingUtilities.invokeLater(() -> myInstancesTree
.rebuildTree(InstancesTree.RebuildPolicy.ONLY_UPDATE_LABELS));
ApplicationManager.getApplication().invokeLater(() -> myInstancesTree
.rebuildTree(InstancesTree.RebuildPolicy.ONLY_UPDATE_LABELS));
}
}
}
private boolean isAddToWatchesAction(AnAction action) {
String className = action.getClass().getSimpleName();
final String className = action.getClass().getSimpleName();
return action instanceof XDebuggerTreeActionBase && className.equals("XAddToWatchesAction");
}
private boolean isEvaluateExpressionAction(AnAction action) {
String className = action.getClass().getSimpleName();
final String className = action.getClass().getSimpleName();
return action instanceof XDebuggerActionBase && className.equals("EvaluateAction");
}
}
private final class MyCachedEvaluator extends CachedEvaluator {
@Override
@NotNull
protected String getClassName() {
return myClassName;
private class MyFilteringCallback implements FilteringTaskCallback {
private final ErrorsValueGroup myErrorsGroup = new ErrorsValueGroup();
private final EvaluationContextImpl myEvaluationContext;
private long myFilteringStartedTime;
private int myProceedCount = 0;
private int myMatchedCount = 0;
private int myErrorsCount = 0;
public MyFilteringCallback(@NotNull EvaluationContextImpl evaluationContext) {
myEvaluationContext = evaluationContext;
}
ExpressionEvaluator getEvaluator() throws EvaluateException {
return getEvaluator(myProject);
private XValueChildrenList myChildren = new XValueChildrenList();
@Override
public void started(int total) {
myFilteringStartedTime = System.nanoTime();
ApplicationManager.getApplication().invokeLater(() -> myProgress.start(total));
}
@NotNull
@Override
public Action matched(@NotNull ObjectReference ref) {
final JavaValue val = new InstanceJavaValue(new InstanceValueDescriptor(myProject, ref),
myEvaluationContext, myNodeManager);
myMatchedCount++;
myProceedCount++;
myChildren.add(val);
if (myChildren.size() >= FILTERING_CHUNK_SIZE) {
final int proceed = myProceedCount;
final int matched = myMatchedCount;
final int errors = myErrorsCount;
XValueChildrenList children = myChildren;
ApplicationManager.getApplication().invokeLater(() -> {
myProgress.updateProgress(proceed, matched, errors);
myInstancesTree.addChildren(children, false);
});
myChildren = new XValueChildrenList();
}
return myMatchedCount < MAX_TREE_NODE_COUNT ? Action.CONTINUE : Action.STOP;
}
@NotNull
@Override
public Action notMatched(@NotNull ObjectReference ref) {
myProceedCount++;
return Action.CONTINUE;
}
@NotNull
@Override
public Action error(@NotNull ObjectReference ref, @NotNull String description) {
final JavaValue val = new InstanceJavaValue(new InstanceValueDescriptor(myProject, ref),
myEvaluationContext, myNodeManager);
myErrorsGroup.addErrorValue(description, val);
myProceedCount++;
myErrorsCount++;
return Action.CONTINUE;
}
@Override
public void completed(@NotNull FilteringResult reason) {
if (!myErrorsGroup.isEmpty()) {
myChildren.addBottomGroup(myErrorsGroup);
}
final long duration = System.nanoTime() - myFilteringStartedTime;
LOG.info(String.format("Filtering completed in %d ms for %d instances",
TimeUnit.NANOSECONDS.toMillis(duration),
myProceedCount));
final int proceed = myProceedCount;
final int matched = myMatchedCount;
final int errors = myErrorsCount;
final XValueChildrenList childrenList = myChildren;
ApplicationManager.getApplication().invokeLater(() -> {
myProgress.updateProgress(proceed, matched, errors);
myInstancesTree.addChildren(childrenList, true);
myFilterButton.setEnabled(true);
myProgress.complete(reason);
});
}
}
private class MyFilteringWorker extends SwingWorker<Void, Void> {
private final List<ObjectReference> myReferences;
private final ErrorsValueGroup myErrorsGroup = new ErrorsValueGroup("Errors");
private final ExpressionEvaluator myExpressionEvaluator;
private final EvaluationContextImpl myEvaluationContext;
private volatile boolean myDebuggerTaskCompleted = false;
@NotNull
private volatile FilteringCompletionReason myCompletionReason = FilteringCompletionReason.INTERRUPTED;
private final FilteringTask myTask;
MyFilteringWorker(@NotNull List<ObjectReference> refs,
@NotNull EvaluationContextImpl evaluationContext,
@Nullable ExpressionEvaluator evaluator) {
myReferences = refs;
myEvaluationContext = evaluationContext;
myExpressionEvaluator = evaluator;
}
@Override
protected void done() {
if (!myErrorsGroup.isEmpty()) {
XValueChildrenList lst = new XValueChildrenList();
lst.addBottomGroup(myErrorsGroup);
myInstancesTree.addChildren(lst, true);
} else {
myInstancesTree.addChildren(XValueChildrenList.EMPTY, true);
@NotNull XExpression expression,
@NotNull EvaluationContextImpl evaluationContext) {
if (refs.size() != 0) {
DebugProcessImpl debugProcess =
(DebugProcessImpl)DebuggerManager.getInstance(myProject).getDebugProcess(myDebugSession.getDebugProcess().getProcessHandler());
myTask = new FilteringTask(refs.get(0).referenceType(), debugProcess, expression, refs,
new MyFilteringCallback(evaluationContext));
}
else {
myTask = null;
}
myFilterButton.setEnabled(true);
SwingUtilities.invokeLater(() -> myProgress.complete(myCompletionReason));
}
@Override
protected Void doInBackground() throws Exception {
DebugProcessImpl debugProcess = (DebugProcessImpl) DebuggerManager.getInstance(myProject)
.getDebugProcess(myDebugSession.getDebugProcess().getProcessHandler());
AtomicInteger totalChildren = new AtomicInteger(0);
AtomicInteger totalViewed = new AtomicInteger(0);
long start = System.nanoTime();
for (int i = 0, size = myReferences.size(); i < size && totalChildren.get() < MAX_TREE_NODE_COUNT;
i += FILTERING_CHUNK_SIZE) {
myDebuggerTaskCompleted = false;
final int chunkBegin = i;
debugProcess.getManagerThread().schedule(new DebuggerContextCommandImpl(debugProcess.getDebuggerContext()) {
@Override
public Priority getPriority() {
return Priority.LOWEST;
}
@Override
public void threadAction(@NotNull SuspendContextImpl suspendContext) {
// TODO: need to rewrite this
XValueChildrenList children = new XValueChildrenList();
int endOfChunk = min(chunkBegin + FILTERING_CHUNK_SIZE, size);
int errorCount = 0;
for (int j = chunkBegin; j < endOfChunk && totalChildren.get() < MAX_TREE_NODE_COUNT; j++) {
ObjectReference ref = myReferences.get(j);
totalViewed.incrementAndGet();
Pair<MyFilteringResult, String> comparison = null;
if (myExpressionEvaluator != null) {
comparison = isSatisfy(myExpressionEvaluator, ref);
if (comparison.first == MyFilteringResult.EVAL_ERROR) {
errorCount++;
}
if (comparison.first == MyFilteringResult.NO_MATCH) {
continue;
}
}
JavaValue val = new InstanceJavaValue(null, new InstanceValueDescriptor(myProject, ref),
myEvaluationContext, myNodeManager, true);
if (comparison == null || comparison.first == MyFilteringResult.MATCH) {
children.add(val);
} else {
myErrorsGroup.addErrorValue(comparison.second, val);
}
totalChildren.incrementAndGet();
}
if (children.size() > 0) {
SwingUtilities.invokeLater(() -> {
if (MyFilteringWorker.this == myFilteringTask) {
myInstancesTree.addChildren(children, false);
}
});
}
final int childrenSize = children.size();
final int finalErrorsCount = errorCount;
SwingUtilities.invokeLater(() ->
myProgress.updateProgress(endOfChunk - chunkBegin, childrenSize, finalErrorsCount));
synchronized (MyFilteringWorker.this) {
myDebuggerTaskCompleted = true;
MyFilteringWorker.this.notify();
}
}
});
synchronized (MyFilteringWorker.this) {
while (!myDebuggerTaskCompleted) {
MyFilteringWorker.this.wait();
}
}
if (myTask != null) {
myTask.run();
}
LOG.info(String.format("Filtering time = %d ms, count = %d, matched = %d",
TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - start), totalViewed.get(), totalChildren.get()));
myCompletionReason = totalViewed.get() == myReferences.size()
? FilteringCompletionReason.ALL_CHECKED
: FilteringCompletionReason.LIMIT_REACHED;
return null;
}
private Pair<MyFilteringResult, String> isSatisfy(@NotNull ExpressionEvaluator evaluator, @NotNull Value value) {
try {
Value result = evaluator.evaluate(myEvaluationContext.createEvaluationContext(value));
if (result instanceof BooleanValue && ((BooleanValue) result).value()) {
return Pair.create(MyFilteringResult.MATCH, "");
}
} catch (EvaluateException e) {
return Pair.create(MyFilteringResult.EVAL_ERROR, e.getMessage());
}
return Pair.create(MyFilteringResult.NO_MATCH, "");
}
}
}
@@ -548,8 +497,4 @@ public class InstancesWindow extends DialogWrapper {
return new DebuggerTreeNodeImpl(null, new MessageDescriptor(message));
}
}
private enum MyFilteringResult {
MATCH, NO_MATCH, EVAL_ERROR
}
}
@@ -1,5 +1,21 @@
package org.jetbrains.debugger.memory.view;
/*
* Copyright 2000-2016 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.debugger.memory.ui;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.ui.JBSplitter;
@@ -8,13 +24,12 @@ import com.intellij.ui.components.JBScrollPane;
import com.intellij.ui.components.labels.ActionLink;
import com.intellij.xdebugger.XDebugSession;
import com.sun.jdi.ObjectReference;
import icons.MemoryViewIcons;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.debugger.memory.component.CreationPositionTracker;
import org.jetbrains.debugger.memory.component.InstancesTracker;
import org.jetbrains.debugger.memory.event.InstancesTrackerListener;
import org.jetbrains.debugger.memory.tracking.TrackingType;
import org.jetbrains.debugger.memory.utils.StackFrameDescriptor;
import com.intellij.debugger.memory.component.CreationPositionTracker;
import com.intellij.debugger.memory.component.InstancesTracker;
import com.intellij.debugger.memory.event.InstancesTrackerListener;
import com.intellij.debugger.memory.tracking.TrackingType;
import com.intellij.debugger.memory.utils.StackFrameDescriptor;
import javax.swing.*;
import java.util.Collections;
@@ -41,13 +56,17 @@ class InstancesWithStackFrameView {
JLabel stackTraceLabel;
if (isArrayType(className)) {
stackTraceLabel = new JBLabel(TEXT_FOR_ARRAYS, SwingConstants.CENTER);
} else {
ActionLink actionLink = new ActionLink("Enable tracking for new instances", MemoryViewIcons.CLASS_TRACKED, new AnAction() {
@Override
public void actionPerformed(AnActionEvent e) {
InstancesTracker.getInstance(debugSession.getProject()).add(className, TrackingType.CREATION);
}
});
}
else {
ActionLink actionLink = new ActionLink("Enable tracking for new instances",
AllIcons.Debugger.MemoryView.ClassTracked,
new AnAction() {
@Override
public void actionPerformed(AnActionEvent e) {
InstancesTracker.getInstance(debugSession.getProject())
.add(className, TrackingType.CREATION);
}
});
actionLink.setHorizontalAlignment(SwingConstants.CENTER);
actionLink.setPaintUnderline(false);
@@ -87,13 +106,14 @@ class InstancesWithStackFrameView {
List<StackFrameDescriptor> stack = tracker.getStack(debugSession, ref);
if (stack != null) {
list.setFrame(stack);
if(mySplitter.getProportion() == 1.f) {
if (mySplitter.getProportion() == 1.f) {
mySplitter.setProportion(DEFAULT_SPLITTER_PROPORTION);
}
return;
}
list.setEmptyText(EMPTY_TEXT_WHEN_STACK_NOT_FOUND);
} else {
}
else {
list.setEmptyText(EMPTY_TEXT_WHEN_ITEM_NOT_SELECTED);
}
@@ -1,4 +1,19 @@
package org.jetbrains.debugger.memory.view;
/*
* Copyright 2000-2016 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.debugger.memory.ui;
import com.intellij.debugger.engine.DebuggerUtils;
import com.intellij.execution.filters.OpenFileHyperlinkInfo;
@@ -17,15 +32,14 @@ import com.intellij.psi.util.PsiUtilCore;
import com.intellij.ui.ColoredListCellRenderer;
import com.intellij.ui.SimpleTextAttributes;
import com.intellij.ui.components.JBList;
import org.apache.commons.lang.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.debugger.memory.utils.StackFrameDescriptor;
import com.intellij.debugger.memory.utils.StackFrameDescriptor;
import javax.swing.*;
import java.util.ArrayList;
import java.util.List;
class StackFrameList extends JBList {
class StackFrameList extends JBList<StackFrameDescriptor> {
private static final char ANONYMOUS_CLASS_DELIMITER = '$';
private static final MyOpenFilesState myEditorState = new MyOpenFilesState();
@@ -45,7 +59,6 @@ class StackFrameList extends JBList {
setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
//noinspection unchecked
setModel(myModel);
setCellRenderer(new ColoredListCellRenderer<StackFrameDescriptor>() {
@@ -54,7 +67,7 @@ class StackFrameList extends JBList {
StackFrameDescriptor value, int index, boolean isSelected, boolean hasFocus) {
append(String.format("%s:%d, %s", value.methodName(), value.line(), value.className()));
String packageName = value.packageName();
if (!StringUtils.isEmpty(packageName)) {
if (packageName.trim().isEmpty() /*!StringUtils.isEmpty(packageName)*/) {
append(String.format(" (%s)", value.packageName()), SimpleTextAttributes.GRAYED_ITALIC_ATTRIBUTES);
}
}
@@ -66,7 +79,7 @@ class StackFrameList extends JBList {
}
void navigateToSelectedValue(boolean focusOnEditor) {
StackFrameDescriptor selectedValue = (StackFrameDescriptor) getSelectedValue();
StackFrameDescriptor selectedValue = getSelectedValue();
if (selectedValue != null) {
navigateToFrame(selectedValue, focusOnEditor);
}
@@ -88,7 +101,7 @@ class StackFrameList extends JBList {
}
OpenFileHyperlinkInfo info =
new OpenFileHyperlinkInfo(myProject, file, frame.line() - 1);
new OpenFileHyperlinkInfo(myProject, file, frame.line() - 1);
OpenFileDescriptor descriptor = info.getDescriptor();
if (descriptor != null) {
FileEditorManagerImpl manager = (FileEditorManagerImpl)FileEditorManager.getInstance(myProject);
@@ -1,11 +1,26 @@
package org.jetbrains.debugger.memory.view;
/*
* Copyright 2000-2016 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.debugger.memory.ui;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.popup.JBPopup;
import com.intellij.openapi.ui.popup.JBPopupFactory;
import com.intellij.psi.search.GlobalSearchScope;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.debugger.memory.utils.StackFrameDescriptor;
import com.intellij.debugger.memory.utils.StackFrameDescriptor;
import java.util.List;
@@ -1,4 +1,19 @@
package org.jetbrains.debugger.memory.utils;
/*
* Copyright 2000-2016 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.debugger.memory.utils;
public abstract class AbstractTableColumnDescriptor implements AbstractTableModelWithColumns.TableColumnDescriptor {
private final String myName;
@@ -1,4 +1,19 @@
package org.jetbrains.debugger.memory.utils;
/*
* Copyright 2000-2016 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.debugger.memory.utils;
import javax.swing.table.AbstractTableModel;
@@ -1,13 +1,30 @@
package org.jetbrains.debugger.memory.utils;
/*
* Copyright 2000-2016 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.debugger.memory.utils;
import com.sun.jdi.VirtualMachine;
import org.jetbrains.annotations.NotNull;
import java.util.Locale;
public class AndroidUtil {
public static final int ANDROID_COUNT_BY_CLASSES_BATCH_SIZE = 500;
public static final int ANDROID_INSTANCES_LIMIT = 30000;
public static boolean isAndroidVM(@NotNull VirtualMachine vm) {
return vm.name().toLowerCase().contains("dalvik");
return vm.name().toLowerCase(Locale.ENGLISH).contains("dalvik");
}
}
@@ -1,4 +1,19 @@
package org.jetbrains.debugger.memory.utils;
/*
* Copyright 2000-2016 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.debugger.memory.utils;
import com.intellij.icons.AllIcons;
import com.intellij.util.containers.HashMap;
@@ -17,8 +32,8 @@ import java.util.Map;
public class ErrorsValueGroup extends XValueGroup {
private final Map<String, List<XNamedValue>> myErrorMessage2ValueMap = new HashMap<>();
public ErrorsValueGroup(@NotNull String name) {
super(name);
public ErrorsValueGroup() {
super("Errors");
}
public void addErrorValue(@NotNull String message, @NotNull XNamedValue value) {
@@ -1,4 +1,19 @@
package org.jetbrains.debugger.memory.utils;
/*
* Copyright 2000-2016 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.debugger.memory.utils;
import com.intellij.debugger.engine.JavaValue;
import com.intellij.debugger.engine.evaluation.EvaluationContextImpl;
@@ -9,12 +24,10 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class InstanceJavaValue extends JavaValue {
public InstanceJavaValue(JavaValue javaValue,
@NotNull ValueDescriptorImpl valueDescriptor,
@NotNull EvaluationContextImpl evaluationContext,
NodeManagerImpl nodeManager,
boolean contextSet) {
super(javaValue, valueDescriptor, evaluationContext, nodeManager, contextSet);
public InstanceJavaValue(@NotNull ValueDescriptorImpl valueDescriptor,
@NotNull EvaluationContextImpl evaluationContext,
NodeManagerImpl nodeManager) {
super(null, valueDescriptor, evaluationContext, nodeManager, false);
}
@Nullable
@@ -1,4 +1,19 @@
package org.jetbrains.debugger.memory.utils;
/*
* Copyright 2000-2016 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.debugger.memory.utils;
import com.intellij.debugger.DebuggerContext;
import com.intellij.debugger.engine.ContextUtil;
@@ -1,4 +1,19 @@
package org.jetbrains.debugger.memory.utils;
/*
* Copyright 2000-2016 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.debugger.memory.utils;
import com.sun.jdi.ObjectReference;
import org.jetbrains.annotations.NotNull;
@@ -1,4 +1,19 @@
package org.jetbrains.debugger.memory.utils;
/*
* Copyright 2000-2016 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.debugger.memory.utils;
import java.awt.event.KeyEvent;
@@ -1,4 +1,19 @@
package org.jetbrains.debugger.memory.utils;
/*
* Copyright 2000-2016 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.debugger.memory.utils;
import com.intellij.debugger.engine.SuspendContextImpl;
import com.intellij.debugger.engine.events.SuspendContextCommandImpl;
@@ -1,4 +1,19 @@
package org.jetbrains.debugger.memory.utils;
/*
* Copyright 2000-2016 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.debugger.memory.utils;
import com.intellij.openapi.util.text.StringUtil;
import com.sun.jdi.ArrayReference;
@@ -1,4 +1,19 @@
package org.jetbrains.debugger.memory.utils;
/*
* Copyright 2000-2016 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.debugger.memory.utils;
import com.intellij.openapi.Disposable;
import com.intellij.util.Alarm;
@@ -1,4 +1,19 @@
package org.jetbrains.debugger.memory.utils;
/*
* Copyright 2000-2016 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.debugger.memory.utils;
import com.intellij.openapi.util.text.StringUtil;
import org.jetbrains.annotations.NotNull;
Binary file not shown.

After

Width:  |  Height:  |  Size: 378 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 351 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 241 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 472 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 469 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 245 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 291 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 604 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 589 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 304 B

@@ -281,6 +281,13 @@ public class AllIcons {
public static final Icon Frame = IconLoader.getIcon("/debugger/frame.png"); // 16x16
public static final Icon KillProcess = IconLoader.getIcon("/debugger/killProcess.png"); // 16x16
public static final Icon LambdaBreakpoint = IconLoader.getIcon("/debugger/LambdaBreakpoint.png"); // 12x12
public static class MemoryView {
public static final Icon ClassTracked = IconLoader.getIcon("/debugger/memoryView/classTracked.png"); // 16x16
public static final Icon ToolWindowDisabled = IconLoader.getIcon("/debugger/memoryView/toolWindowDisabled.png"); // 13x13
public static final Icon ToolWindowEnabled = IconLoader.getIcon("/debugger/memoryView/toolWindowEnabled.png"); // 13x13
}
public static final Icon MultipleBreakpoints = IconLoader.getIcon("/debugger/MultipleBreakpoints.png"); // 12x12
public static final Icon MuteBreakpoints = IconLoader.getIcon("/debugger/muteBreakpoints.png"); // 16x16
public static final Icon NewWatch = IconLoader.getIcon("/debugger/newWatch.png"); // 16x16
+23 -1
View File
@@ -1,4 +1,10 @@
<idea-plugin>
<application-components>
<component>
<implementation-class>com.intellij.debugger.memory.component.MemoryViewManager</implementation-class>
</component>
</application-components>
<project-components>
<component>
<interface-class>com.intellij.debugger.ui.DebuggerPanelsManager</interface-class>
@@ -10,7 +16,7 @@
</component>
<component>
<interface-class>com.intellij.debugger.ui.HotSwapUI</interface-class>
<implementation-class>com.intellij.debugger.ui.HotSwapUIImpl</implementation-class>
<implementation-class>com.intellij.debugger.ui.HotSwapUIImpl</implementation-class>
</component>
<component>
@@ -19,8 +25,24 @@
<option name="workspace" value="true"/>
<loadForDefaultProject/>
</component>
<component>
<implementation-class>com.intellij.debugger.memory.component.InstancesTracker</implementation-class>
</component>
<component>
<implementation-class>com.intellij.debugger.memory.component.CreationPositionTracker</implementation-class>
</component>
</project-components>
<extensions defaultExtensionNs="com.intellij">
<toolWindow id="Memory View"
anchor="right"
icon="AllIcons.Debugger.MemoryView.ToolWindowDisabled"
factoryClass="com.intellij.debugger.memory.toolwindow.MemoryViewToolWindowFactory"
conditionClass="com.intellij.debugger.memory.toolwindow.MemoryViewToolWindowFactory$Condition"/>
</extensions>
<!--
<actions>
<group id="CommonViews">
+54 -1
View File
@@ -69,7 +69,7 @@
<group id="RefactoringMenu2">
<action id="MethodDuplicates" class="com.intellij.refactoring.actions.MethodDuplicatesAction"/>
<add-to-group group-id="RefactoringMenu" anchor="after" relative-to-action="Inline"/>
</group>
@@ -212,6 +212,59 @@
<action id="Debugger.AutoRenderer" class="com.intellij.debugger.actions.AutoRendererAction"/>
</group>
<action class="com.intellij.debugger.memory.action.ShowInstancesByClassAction"
id="MemoryView.ShowInstancesFromDebuggerTree"
text="Show Instances">
<add-to-group group-id="XDebugger.ValueGroup" anchor="after"
relative-to-action="Debugger.ShowReferring"/>
</action>
<action class="com.intellij.debugger.memory.action.tracking.JumpToAllocationSourceAction"
id="MemoryView.ShowAllocationStackTrace"
text="Jump To Allocation Position">
<add-to-group group-id="XDebugger.ValueGroup" anchor="after"
relative-to-action="XDebugger.JumpToTypeSource"/>
</action>
<group id="MemoryView.SettingsPopupActionGroup">
<action class="com.intellij.debugger.memory.action.ShowClassesWithInstanceAction"
id="MemoryView.ShowOnlyWithInstances"
text="Show With Instances Only"/>
<action class="com.intellij.debugger.memory.action.ShowClassesWithDiffAction"
id="MemoryView.ShowOnlyWithDiff"
text="Show Non-Zero Diff Only"/>
<action class="com.intellij.debugger.memory.action.ShowTrackedAction"
id="MemoryView.ShowOnlyTracked"
text="Show Tracked Classes Only"/>
<separator/>
<action class="com.intellij.debugger.memory.action.EnableBackgroundTrackingAction"
id="MemoryView.EnableTrackingWithClosedWindow"
text="Enable Tracking With Hidden Memory View"/>
</group>
<group id="MemoryView.ClassesPopupActionGroup">
<action class="com.intellij.debugger.memory.action.ShowInstancesFromClassesViewAction"
id="MemoryView.ShowInstances"
text="Show Instances"/>
<action class="com.intellij.debugger.memory.action.ShowNewInstancesAction"
id="MemoryView.ShowNewInstances"
text="Show New Instances"/>
<action class="com.intellij.debugger.memory.action.JumpToTypeSourceAction"
id="MemoryView.JumpToTypeSource"
text="Jump To Type Source"/>
<separator/>
<action class="com.intellij.debugger.memory.action.tracking.TrackInstancesToggleAction"
id="MemoryView.TrackingAction.NewInstancesTracking"
text="Track New Instances"/>
</group>
<group id="Debugger.Representation">
<reference ref="Debugger.CreateRenderer"/>
<separator/>