Initial Commit
[packages] / xemacs-packages / jde / java / src / jde / debugger / command / Step.java
1 package jde.debugger.command;
2 import java.util.Iterator;
3 import java.util.List;
4
5 import com.sun.jdi.ThreadReference;
6 import com.sun.jdi.request.EventRequestManager;
7 import com.sun.jdi.request.StepRequest;
8 import jde.debugger.Etc;
9 import jde.debugger.JDEException;
10
11
12
13 /**
14  * 'step' command. This is only possible if the current thread is
15  * suspended.
16  * <p>
17  *
18  * <b>Syntax:</b>
19  * <pre>
20  * step <u>type</u> threadID
21  *      [{@link Etc#getSuspendPolicyFromArgs(List) suspend-policy}]
22  * </pre>
23  *
24  * <b>Comments:</b>
25  * <ul>
26  * <li> <u>type</u> is one of "over", "into", "into-all" and "out"
27  * There are three kinds of steps that are being supported currently:
28  * <ul>
29  * <li> step over: steps over method calls</li>
30  * <li> step into: goes into called methods except java and sun methods</li>
31  * <li> step into-all: goes into all methods except excluded methods</li>
32  * <li> step out: executes till it returns to the calling method</li>
33  * </ul>
34  *
35  * <li>
36  *      threadID is required. Also, this is only possible on a
37  *      suspended thread. jde should check this before calling
38  *      step.
39  * </li>
40  * </ul>
41  *
42  * <p>
43  * @see jde.debugger.EventHandler#stepEvent(StepEvent)
44  *
45  * @author Paul Kinnucan
46  * @version $Revision: 1.3 $
47  *
48  * Copyright (c) 2000, 2001, 2003    Paul Kinnucan
49  * 
50  */
51 public class Step extends DebugProcessCommand {
52   
53   /**
54    *
55    * @exception jde.debugger.JDEException <description>
56    */
57   public void doCommand() throws JDEException {
58
59     if (m_args.size() < 2)
60       throw new JDEException("Insufficient arguments");
61         
62     // ascertain the kind of step
63     String arg = m_args.remove(0).toString().toLowerCase();
64     int depth;
65     boolean into_all = false;
66     if (arg.equals("over")) {
67       depth = StepRequest.STEP_OVER;
68     } else if (arg.equals("out")) {
69       depth = StepRequest.STEP_OUT;
70     } else if (arg.equals("into")) {
71       depth = StepRequest.STEP_INTO;
72     } else if (arg.equals("into-all")) {
73       depth = StepRequest.STEP_INTO;
74       into_all = true;
75     }else {
76       throw new JDEException("Syntax error: use step over/out/into");
77     }
78
79     // find the thread on which to step
80     Long uniqueID = Etc.safeGetLong(m_args.remove(0), "thread ID");
81
82     ThreadReference tRef = (ThreadReference) m_debugger.getStore().get(uniqueID);
83     
84     // it should exist
85     if (tRef == null) {
86       throw new JDEException("Invalid thread ID or the thread is dead");
87     }
88
89     // we need to be suspended.
90     // also see ThreadCommands.getThreadStringRep for some info
91     if (tRef.suspendCount() == 0) {
92       throw new  JDEException("The specified thread is not suspended");
93     }
94
95     // clear any previous steps on this thread
96     clearPreviousStep(tRef);
97
98     // set a new request!
99     EventRequestManager erm = m_debugger.getVM().eventRequestManager();
100     StepRequest request =
101       erm.createStepRequest(tRef, StepRequest.STEP_LINE, depth);
102     request.setSuspendPolicy(Etc.getSuspendPolicyFromArgs(m_args));
103
104     if (depth == StepRequest.STEP_INTO) 
105       if (into_all) {
106         
107       } else {
108         request.addClassExclusionFilter("java.*");
109         request.addClassExclusionFilter("javax.*");     
110         request.addClassExclusionFilter("sun.*"); 
111       }
112
113     // a single step event... will set it again if need be.
114     request.addCountFilter(1);
115     request.enable();
116
117     // and now resume the vm. the thread suspended is resumed now.
118     m_debugger.getVM().resume();
119
120     m_debugger.signalCommandResult(m_cmdID, null, CMD_OK);
121   }
122
123
124   /**
125    * Clear a previous step request on this thread: only one is allowed
126    * per thread
127    */
128   private void clearPreviousStep(ThreadReference thread) {
129     EventRequestManager mgr      = m_debugger.getVM().eventRequestManager();
130     List                requests = mgr.stepRequests();
131     Iterator            iter     = requests.iterator();
132     while (iter.hasNext()) {
133       StepRequest     request       = (StepRequest)iter.next();
134       ThreadReference requestThread =  request.thread();
135       if (request.thread().equals(thread)) {
136         mgr.deleteEventRequest(request);
137         break;
138       }
139     }
140   }
141
142   public Object clone() {return new Step();}
143   
144 } // Step
145
146 /*
147  * $Log: Step.java,v $
148  * Revision 1.3  2003/01/15 05:56:26  paulk
149  * Add Petter Mahlen's changes.
150  *
151  * Revision 1.2  2001/03/24 05:42:37  paulk
152  * Updated to reflect reorganization of debugger code.
153  *
154  * Revision 1.1  2000/08/14 02:40:40  paulk
155  * Initial revision.
156  *
157  *
158  *
159  */
160
161 // End of Step.java