blob: a7e00ee0dd72867f65a05437f6ff4f76aac6e141 [file] [log] [blame]
/*
* Copyright 2000-2009 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.actions;
import com.intellij.debugger.DebuggerBundle;
import com.intellij.debugger.DebuggerManagerEx;
import com.intellij.debugger.InstanceFilter;
import com.intellij.debugger.SourcePosition;
import com.intellij.debugger.engine.DebugProcessImpl;
import com.intellij.debugger.engine.DebuggerUtils;
import com.intellij.debugger.engine.events.DebuggerContextCommandImpl;
import com.intellij.debugger.engine.requests.RequestManagerImpl;
import com.intellij.debugger.impl.DebuggerContextImpl;
import com.intellij.debugger.impl.DebuggerSession;
import com.intellij.debugger.ui.breakpoints.Breakpoint;
import com.intellij.debugger.ui.breakpoints.BreakpointManager;
import com.intellij.debugger.ui.breakpoints.FieldBreakpoint;
import com.intellij.debugger.ui.impl.watch.DebuggerTree;
import com.intellij.debugger.ui.impl.watch.DebuggerTreeNodeImpl;
import com.intellij.debugger.ui.impl.watch.FieldDescriptorImpl;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.fileEditor.FileEditorManager;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.fileTypes.StdFileTypes;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
import com.intellij.psi.search.GlobalSearchScope;
import com.sun.jdi.Field;
import com.sun.jdi.ObjectReference;
import org.jetbrains.annotations.Nullable;
/**
* User: lex
* Date: Sep 4, 2003
* Time: 8:59:30 PM
*/
public class ToggleFieldBreakpointAction extends AnAction {
@Override
public void actionPerformed(AnActionEvent e) {
Project project = e.getData(CommonDataKeys.PROJECT);
if (project == null) {
return;
}
final SourcePosition place = getPlace(e);
if(place != null) {
Document document = PsiDocumentManager.getInstance(project).getDocument(place.getFile());
if (document != null) {
DebuggerManagerEx debuggerManager = DebuggerManagerEx.getInstanceEx(project);
BreakpointManager manager = debuggerManager.getBreakpointManager();
final int offset = place.getOffset();
final Breakpoint breakpoint = offset >= 0? manager.findBreakpoint(document, offset, FieldBreakpoint.CATEGORY) : null;
if(breakpoint == null) {
FieldBreakpoint fieldBreakpoint = manager.addFieldBreakpoint(document, offset);
if (fieldBreakpoint != null) {
if(DebuggerAction.isContextView(e)) {
final DebuggerTreeNodeImpl selectedNode = DebuggerAction.getSelectedNode(e.getDataContext());
if (selectedNode != null && selectedNode.getDescriptor() instanceof FieldDescriptorImpl) {
ObjectReference object = ((FieldDescriptorImpl)selectedNode.getDescriptor()).getObject();
if(object != null) {
long id = object.uniqueID();
InstanceFilter[] instanceFilters = new InstanceFilter[] { InstanceFilter.create(Long.toString(id))};
fieldBreakpoint.setInstanceFilters(instanceFilters);
fieldBreakpoint.setInstanceFiltersEnabled(true);
}
}
}
RequestManagerImpl.createRequests(fieldBreakpoint);
final Editor editor = CommonDataKeys.EDITOR.getData(e.getDataContext());
if (editor != null) {
manager.editBreakpoint(fieldBreakpoint, editor);
}
}
}
else {
manager.removeBreakpoint(breakpoint);
}
}
}
}
@Override
public void update(AnActionEvent event){
SourcePosition place = getPlace(event);
boolean toEnable = place != null;
Presentation presentation = event.getPresentation();
if(ActionPlaces.PROJECT_VIEW_POPUP.equals(event.getPlace()) ||
ActionPlaces.STRUCTURE_VIEW_POPUP.equals(event.getPlace()) ||
ActionPlaces.FAVORITES_VIEW_POPUP.equals(event.getPlace())) {
presentation.setVisible(toEnable);
}
else if(DebuggerAction.isContextView(event)) {
presentation.setText(DebuggerBundle.message("action.add.field.watchpoint.text"));
Project project = event.getData(CommonDataKeys.PROJECT);
if(project != null && place != null) {
Document document = PsiDocumentManager.getInstance(project).getDocument(place.getFile());
if (document != null) {
final int offset = place.getOffset();
final BreakpointManager breakpointManager = (DebuggerManagerEx.getInstanceEx(project)).getBreakpointManager();
final Breakpoint fieldBreakpoint = offset >= 0 ? breakpointManager.findBreakpoint(document, offset, FieldBreakpoint.CATEGORY) : null;
if (fieldBreakpoint != null) {
presentation.setEnabled(false);
return;
}
}
}
}
presentation.setVisible(toEnable);
}
@Nullable
public static SourcePosition getPlace(AnActionEvent event) {
final DataContext dataContext = event.getDataContext();
final Project project = event.getData(CommonDataKeys.PROJECT);
if(project == null) {
return null;
}
if (ActionPlaces.PROJECT_VIEW_POPUP.equals(event.getPlace()) ||
ActionPlaces.STRUCTURE_VIEW_POPUP.equals(event.getPlace()) ||
ActionPlaces.FAVORITES_VIEW_POPUP.equals(event.getPlace())) {
final PsiElement psiElement = event.getData(CommonDataKeys.PSI_ELEMENT);
if(psiElement instanceof PsiField) {
return SourcePosition.createFromElement(psiElement);
}
return null;
}
final DebuggerTreeNodeImpl selectedNode = DebuggerAction.getSelectedNode(dataContext);
if(selectedNode != null && selectedNode.getDescriptor() instanceof FieldDescriptorImpl) {
final DebuggerContextImpl debuggerContext = DebuggerAction.getDebuggerContext(dataContext);
final DebugProcessImpl debugProcess = debuggerContext.getDebugProcess();
if (debugProcess != null) { // if there is an active debugsession
final Ref<SourcePosition> positionRef = new Ref<SourcePosition>(null);
debugProcess.getManagerThread().invokeAndWait(new DebuggerContextCommandImpl(debuggerContext) {
public Priority getPriority() {
return Priority.HIGH;
}
public void threadAction() {
ApplicationManager.getApplication().runReadAction(new Runnable() {
public void run() {
final FieldDescriptorImpl descriptor = (FieldDescriptorImpl)selectedNode.getDescriptor();
positionRef.set(descriptor.getSourcePosition(project, debuggerContext));
}
});
}
});
final SourcePosition sourcePosition = positionRef.get();
if (sourcePosition != null) {
return sourcePosition;
}
}
}
if(DebuggerAction.isContextView(event)) {
DebuggerTree tree = DebuggerTree.DATA_KEY.getData(dataContext);
if(tree != null && tree.getSelectionPath() != null) {
DebuggerTreeNodeImpl node = ((DebuggerTreeNodeImpl)tree.getSelectionPath().getLastPathComponent());
if(node != null && node.getDescriptor() instanceof FieldDescriptorImpl) {
Field field = ((FieldDescriptorImpl)node.getDescriptor()).getField();
DebuggerSession session = tree.getDebuggerContext().getDebuggerSession();
PsiClass psiClass = DebuggerUtils.findClass(field.declaringType().name(), project, (session != null) ? session.getSearchScope() : GlobalSearchScope.allScope(project));
if(psiClass != null) {
psiClass = (PsiClass) psiClass.getNavigationElement();
final PsiField psiField = psiClass.findFieldByName(field.name(), true);
if (psiField != null) {
return SourcePosition.createFromElement(psiField);
}
}
}
}
return null;
}
Editor editor = event.getData(CommonDataKeys.EDITOR);
if(editor == null) {
editor = FileEditorManager.getInstance(project).getSelectedTextEditor();
}
if (editor != null) {
final Document document = editor.getDocument();
PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(document);
if (file != null) {
final VirtualFile virtualFile = file.getVirtualFile();
FileType fileType = virtualFile != null ? virtualFile.getFileType() : null;
if (StdFileTypes.JAVA == fileType || StdFileTypes.CLASS == fileType) {
final PsiField field = FieldBreakpoint.findField(project, document, editor.getCaretModel().getOffset());
if(field != null){
return SourcePosition.createFromElement(field);
}
}
}
}
return null;
}
}