/* * Copyright 2003-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 jetbrains.mps.idea.java.debugger; import com.intellij.debugger.DebuggerManagerEx; import com.intellij.debugger.SourcePosition; import com.intellij.debugger.engine.DebugProcess; import com.intellij.debugger.impl.DebuggerContextImpl; import com.intellij.debugger.impl.DebuggerContextListener; import com.intellij.debugger.impl.DebuggerManagerListener; import com.intellij.debugger.impl.DebuggerSession; import com.intellij.debugger.impl.DebuggerSession.Event; import com.intellij.execution.ExecutionManager; 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.openapi.components.ProjectComponent; import com.intellij.openapi.fileEditor.FileEditorManager; import com.intellij.openapi.project.Project; import jetbrains.mps.debugger.core.CurrentLinePositionComponentEx; import jetbrains.mps.idea.java.trace.MpsSourcePosition; import org.jetbrains.annotations.NotNull; import org.jetbrains.mps.openapi.model.SNode; import org.jetbrains.mps.openapi.model.SNodeReference; import java.util.Collection; public class IdeaDebuggerPositionHighlighter extends CurrentLinePositionComponentEx<DebuggerSession> implements ProjectComponent { private DebuggerManagerEx myDebuggerManager; private final DebuggerManagerListener myDebuggerManagerListener = new MyDebuggerManagerListener(); private final DebuggerContextListener mySessionListener = new MyDebuggerContextListener(); private final RunContentWithExecutorListener myRunContentListener = new MyRunContentListener(); private final ExecutionManager myExecutionManager; public IdeaDebuggerPositionHighlighter(Project project, FileEditorManager fileEditorManager) { super(project, fileEditorManager); myExecutionManager = ExecutionManager.getInstance(myProject); } @Override protected SNodeReference getNode(DebuggerSession session) { SourcePosition sourcePosition = session.getContextManager().getContext().getSourcePosition(); if (sourcePosition instanceof MpsSourcePosition) { return ((MpsSourcePosition) sourcePosition).getNode(); } return null; } @Override public void initComponent() { } @Override public void disposeComponent() { } @NotNull @Override public String getComponentName() { return "Idea Debugger Position Highlighter"; } @Override public void projectOpened() { myDebuggerManager = DebuggerManagerEx.getInstanceEx(myProject); myDebuggerManager.addDebuggerManagerListener(myDebuggerManagerListener); myProject.getMessageBus().connect(myProject).subscribe(RunContentManager.TOPIC, myRunContentListener); } @Override public void projectClosed() { myDebuggerManager.removeDebuggerManagerListener(myDebuggerManagerListener); } @Override protected DebuggerSession getCurrentSession() { RunContentDescriptor selectedContent = myExecutionManager.getContentManager().getSelectedContent(); if (selectedContent == null) return null; return myDebuggerManager.getSession(myDebuggerManager.getDebugProcess(selectedContent.getProcessHandler())); } @Override protected Collection<? extends DebuggerSession> getAllSessions() { return myDebuggerManager.getSessions(); } private class MyDebuggerManagerListener implements DebuggerManagerListener { @Override public void sessionCreated(DebuggerSession session) { session.getContextManager().addListener(mySessionListener); } public void sessionAttached(DebuggerSession session) { } public void sessionDetached(DebuggerSession session) { } @Override public void sessionRemoved(DebuggerSession session) { detachPainter(session); session.getContextManager().removeListener(mySessionListener); } } private class MyDebuggerContextListener implements DebuggerContextListener { @Override public void changeEvent(@NotNull DebuggerContextImpl newContext, Event event) { if (event != Event.REFRESH_WITH_STACK && event != Event.THREADS_REFRESH) { reAttachPainter(newContext.getDebuggerSession(), true); } } } private class MyRunContentListener implements RunContentWithExecutorListener { @Override public void contentSelected(RunContentDescriptor runContentDescriptor, @NotNull Executor executor) { if (runContentDescriptor != null) { DebugProcess debugProcess = myDebuggerManager.getDebugProcess(runContentDescriptor.getProcessHandler()); if (debugProcess != null) { DebuggerSession debuggerSession = myDebuggerManager.getSession(debugProcess); currentSessionChanged(debuggerSession); } } } @Override public void contentRemoved(RunContentDescriptor runContentDescriptor, @NotNull Executor executor) { } } }