replaced <code></code> with more concise {@code}
[idea/community.git] / platform / xdebugger-api / src / com / intellij / xdebugger / XDebugProcess.java
1 /*
2  * Copyright 2000-2017 JetBrains s.r.o.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package com.intellij.xdebugger;
18
19 import com.intellij.execution.filters.TextConsoleBuilderFactory;
20 import com.intellij.execution.process.ProcessHandler;
21 import com.intellij.execution.ui.ExecutionConsole;
22 import com.intellij.openapi.actionSystem.DefaultActionGroup;
23 import com.intellij.xdebugger.breakpoints.XBreakpointHandler;
24 import com.intellij.xdebugger.evaluation.XDebuggerEditorsProvider;
25 import com.intellij.xdebugger.evaluation.XDebuggerEvaluator;
26 import com.intellij.xdebugger.frame.XStackFrame;
27 import com.intellij.xdebugger.frame.XSuspendContext;
28 import com.intellij.xdebugger.frame.XValueMarkerProvider;
29 import com.intellij.xdebugger.stepping.XSmartStepIntoHandler;
30 import com.intellij.xdebugger.ui.XDebugTabLayouter;
31 import org.jetbrains.annotations.NotNull;
32 import org.jetbrains.annotations.Nullable;
33 import org.jetbrains.concurrency.Promise;
34 import org.jetbrains.concurrency.Promises;
35
36 import javax.swing.event.HyperlinkListener;
37
38 /**
39  * Extends this class to provide debugging capabilities for custom language/framework.
40  *
41  * In order to start debugger by 'Debug' action for a specific run configuration implement {@link com.intellij.execution.runners.ProgramRunner}
42  * and call {@link XDebuggerManager#startSession} from {@link com.intellij.execution.runners.ProgramRunner#execute} method
43  *
44  * Otherwise use method {@link XDebuggerManager#startSessionAndShowTab} to start new debugging session
45  *
46  * @author nik
47  */
48 public abstract class XDebugProcess {
49   private final XDebugSession mySession;
50   private ProcessHandler myProcessHandler;
51
52   /**
53    * @param session pass {@code session} parameter of {@link XDebugProcessStarter#start} method to this constructor
54    */
55   protected XDebugProcess(@NotNull XDebugSession session) {
56     mySession = session;
57   }
58
59   public final XDebugSession getSession() {
60     return mySession;
61   }
62
63   /**
64    * @return breakpoint handlers which will be used to set/clear breakpoints in the underlying debugging process
65    */
66   @NotNull
67   public XBreakpointHandler<?>[] getBreakpointHandlers() {
68     return XBreakpointHandler.EMPTY_ARRAY;
69   }
70
71   /**
72    * @return editor provider which will be used to produce editors for "Evaluate" and "Set Value" actions
73    */
74   @NotNull
75   public abstract XDebuggerEditorsProvider getEditorsProvider();
76
77   /**
78    * Called when {@link XDebugSession} is initialized and breakpoints are registered in
79    * {@link XBreakpointHandler}
80    */
81   public void sessionInitialized() {
82   }
83
84   /**
85    * Interrupt debugging process and call {@link XDebugSession#positionReached}
86    * when next line in current method/function is reached.
87    * Do not call this method directly. Use {@link XDebugSession#pause()} instead
88    */
89   public void startPausing() {
90   }
91
92   /**
93    * @deprecated Use {@link #startStepOver(XSuspendContext)} instead
94    */
95   @Deprecated
96   public void startStepOver() {
97     throw new AbstractMethodError();
98   }
99
100   /**
101    * Resume execution and call {@link XDebugSession#positionReached}
102    * when next line in current method/function is reached.
103    * Do not call this method directly. Use {@link XDebugSession#stepOver} instead
104    */
105   public void startStepOver(@Nullable XSuspendContext context) {
106     //noinspection deprecation
107     startStepOver();
108   }
109
110   /**
111    * @deprecated Use {@link #startForceStepInto(XSuspendContext)} instead
112    */
113   @Deprecated
114   public void startForceStepInto(){
115     //noinspection deprecation
116     startStepInto();
117   }
118
119   /**
120    * Steps into suppressed call
121    * <p>
122    * Resume execution and call {@link XDebugSession#positionReached}
123    * when next line is reached.
124    * Do not call this method directly. Use {@link XDebugSession#forceStepInto} instead
125    */
126   public void startForceStepInto(@Nullable XSuspendContext context) {
127     startStepInto(context);
128   }
129
130   /**
131    * @deprecated Use {@link #startStepInto(XSuspendContext)} instead
132    */
133   @Deprecated
134   public void startStepInto() {
135     throw new AbstractMethodError();
136   }
137
138   /**
139    * Resume execution and call {@link XDebugSession#positionReached}
140    * when next line is reached.
141    * Do not call this method directly. Use {@link XDebugSession#stepInto} instead
142    */
143   public void startStepInto(@Nullable XSuspendContext context) {
144     //noinspection deprecation
145     startStepInto();
146   }
147
148   /**
149    * @deprecated Use {@link #startStepOut(XSuspendContext)} instead
150    */
151   @Deprecated
152   public void startStepOut() {
153     throw new AbstractMethodError();
154   }
155
156   /**
157    * Resume execution and call {@link XDebugSession#positionReached}
158    * after returning from current method/function.
159    * Do not call this method directly. Use {@link XDebugSession#stepOut} instead
160    */
161   public void startStepOut(@Nullable XSuspendContext context) {
162     //noinspection deprecation
163     startStepOut();
164   }
165
166   /**
167    * Implement {@link XSmartStepIntoHandler} and return its instance from this method to enable Smart Step Into action
168    * @return {@link XSmartStepIntoHandler} instance
169    */
170   @Nullable
171   public XSmartStepIntoHandler<?> getSmartStepIntoHandler() {
172     return null;
173   }
174
175   /**
176    * Stop debugging and dispose resources.
177    * Do not call this method directly. Use {@link XDebugSession#stop} instead
178    */
179   public void stop() {
180     throw new AbstractMethodError();
181   }
182
183   @NotNull
184   public Promise stopAsync() {
185     stop();
186     return Promises.resolvedPromise();
187   }
188
189   /**
190    * @deprecated Use {@link #resume(XSuspendContext)} instead
191    */
192   @Deprecated
193   public void resume() {
194     throw new AbstractMethodError();
195   }
196
197   /**
198    * Resume execution.
199    * Do not call this method directly. Use {@link XDebugSession#resume} instead
200    */
201   public void resume(@Nullable XSuspendContext context) {
202     //noinspection deprecation
203     resume();
204   }
205
206   /**
207    * @deprecated Use {@link #runToPosition(XSourcePosition, XSuspendContext)} instead
208    */
209   @Deprecated
210   public void runToPosition(@NotNull XSourcePosition position) {
211     throw new AbstractMethodError();
212   }
213
214   /**
215    * Resume execution and call {@link XDebugSession#positionReached(XSuspendContext)}
216    * when {@code position} is reached.
217    * Do not call this method directly. Use {@link XDebugSession#runToPosition} instead
218    *
219    * @param position position in source code
220    */
221   public void runToPosition(@NotNull XSourcePosition position, @Nullable XSuspendContext context) {
222     //noinspection deprecation
223     runToPosition(position);
224   }
225
226   /**
227    * Check is it is possible to perform commands such as resume, step etc. And notify user if necessary
228    * @return {@code true} if process can actually perform user requests at this moment
229    */
230   public boolean checkCanPerformCommands() {
231     return true;
232   }
233
234   /**
235    * Check is it is possible to init breakpoints. Otherwise you should call {@link XDebugSession#initBreakpoints()} at the appropriate time
236    */
237   public boolean checkCanInitBreakpoints() {
238     return true;
239   }
240
241   @Nullable
242   protected ProcessHandler doGetProcessHandler() {
243     return null;
244   }
245
246   @NotNull
247   public final ProcessHandler getProcessHandler() {
248     if (myProcessHandler == null) {
249       myProcessHandler = doGetProcessHandler();
250       if (myProcessHandler == null) {
251         myProcessHandler = new DefaultDebugProcessHandler();
252       }
253     }
254     return myProcessHandler;
255   }
256
257   @NotNull
258   public ExecutionConsole createConsole() {
259     return TextConsoleBuilderFactory.getInstance().createBuilder(getSession().getProject()).getConsole();
260   }
261
262   /**
263    * Override this method to enable 'Mark Object' action
264    * @return new instance of {@link XValueMarkerProvider}'s implementation or {@code null} if 'Mark Object' feature isn't supported
265    */
266   @Nullable
267   public XValueMarkerProvider<?,?> createValueMarkerProvider() {
268     return null;
269   }
270
271   /**
272    * Override this method to provide additional actions in 'Debug' tool window
273    */
274   public void registerAdditionalActions(@NotNull DefaultActionGroup leftToolbar, @NotNull DefaultActionGroup topToolbar, @NotNull DefaultActionGroup settings) {
275   }
276
277   /**
278    * @return message to show in Variables View when debugger isn't paused
279    */
280   public String getCurrentStateMessage() {
281     return mySession.isStopped() ? XDebuggerBundle.message("debugger.state.message.disconnected") : XDebuggerBundle.message("debugger.state.message.connected");
282   }
283
284   @Nullable
285   public HyperlinkListener getCurrentStateHyperlinkListener() {
286     return null;
287   }
288
289   /**
290    * Override this method to customize content of tab in 'Debug' tool window
291    */
292   @NotNull
293   public XDebugTabLayouter createTabLayouter() {
294     return new XDebugTabLayouter() {
295     };
296   }
297
298   /**
299    * Add or not SortValuesAction (alphabetically sort)
300    * @todo this action should be moved to "Variables" as gear action
301    */
302   public boolean isValuesCustomSorted() {
303     return false;
304   }
305
306   @Nullable
307   public XDebuggerEvaluator getEvaluator() {
308     XStackFrame frame = getSession().getCurrentStackFrame();
309     return frame == null ? null : frame.getEvaluator();
310   }
311
312   /**
313    * Is "isShowLibraryStackFrames" setting respected. If true, ShowLibraryFramesAction will be shown, for example.
314    */
315   public boolean isLibraryFrameFilterSupported() {
316     return false;
317   }
318 }