Remove redundant files in Memory view, rename packages, add icons
@@ -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;
|
||||
|
||||
|
After Width: | Height: | Size: 378 B |
|
After Width: | Height: | Size: 1.0 KiB |
|
After Width: | Height: | Size: 1.0 KiB |
|
After Width: | Height: | Size: 351 B |
|
After Width: | Height: | Size: 241 B |
|
After Width: | Height: | Size: 472 B |
|
After Width: | Height: | Size: 469 B |
|
After Width: | Height: | Size: 245 B |
|
After Width: | Height: | Size: 291 B |
|
After Width: | Height: | Size: 604 B |
|
After Width: | Height: | Size: 589 B |
|
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
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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/>
|
||||
|
||||