Lines 49-54
Link Here
|
49 |
import java.lang.annotation.RetentionPolicy; |
49 |
import java.lang.annotation.RetentionPolicy; |
50 |
import java.lang.annotation.Target; |
50 |
import java.lang.annotation.Target; |
51 |
import java.util.Map; |
51 |
import java.util.Map; |
|
|
52 |
import java.util.Objects; |
53 |
import org.netbeans.api.debugger.jpda.CallStackFrame; |
54 |
import org.netbeans.api.debugger.jpda.JPDAStep; |
52 |
import org.netbeans.api.debugger.jpda.JPDAThread; |
55 |
import org.netbeans.api.debugger.jpda.JPDAThread; |
53 |
import org.netbeans.api.debugger.jpda.SmartSteppingFilter; |
56 |
import org.netbeans.api.debugger.jpda.SmartSteppingFilter; |
54 |
import org.netbeans.modules.debugger.jpda.apiregistry.DebuggerProcessor; |
57 |
import org.netbeans.modules.debugger.jpda.apiregistry.DebuggerProcessor; |
Lines 85-90
Link Here
|
85 |
*/ |
88 |
*/ |
86 |
public abstract boolean stopHere (ContextProvider lookupProvider, JPDAThread thread, SmartSteppingFilter f); |
89 |
public abstract boolean stopHere (ContextProvider lookupProvider, JPDAThread thread, SmartSteppingFilter f); |
87 |
|
90 |
|
|
|
91 |
/** |
92 |
* This is an enhanced version of former {@link #stopHere(org.netbeans.spi.debugger.ContextProvider, org.netbeans.api.debugger.jpda.JPDAThread, org.netbeans.api.debugger.jpda.SmartSteppingFilter)} |
93 |
* method, which is called during stepping through debugged application. |
94 |
* The <code>frame</code> argument allows this method to be called for specific stack frames, |
95 |
* to check if the execution could be suspended there. This is valuable e.g. for step out. |
96 |
* When a top frame is provided, this method can suggest a specific step to continue with, |
97 |
* in case it's not possible to stop at the given location. |
98 |
* |
99 |
* The default implementation calls {@link #stopHere(org.netbeans.spi.debugger.ContextProvider, org.netbeans.api.debugger.jpda.JPDAThread, org.netbeans.api.debugger.jpda.SmartSteppingFilter)} |
100 |
* when called with a top frame and throws an {@link UnsupportedOperationException} otherwise. |
101 |
* |
102 |
* @param lookupProvider The debugger services lookup |
103 |
* @param frame The frame in question |
104 |
* @param f a filter |
105 |
* @return whether the debugger can stop at this location, or whether it should continue with a step. |
106 |
* @since 3.5 |
107 |
*/ |
108 |
public StopOrStep stopAt(ContextProvider lookupProvider, CallStackFrame frame, SmartSteppingFilter f) { |
109 |
int depth = frame.getFrameDepth(); |
110 |
if (depth > 0) { |
111 |
throw new UnsupportedOperationException("Not supporting frames with depth > 0"); |
112 |
} |
113 |
boolean stop = stopHere(lookupProvider, frame.getThread(), f); |
114 |
return stop ? StopOrStep.stop() : StopOrStep.skip(); |
115 |
} |
116 |
|
117 |
/** |
118 |
* Information about a possibility to stop at the given location, |
119 |
* or suggestion to perform a step. |
120 |
* Used by {@link #stopAt(org.netbeans.spi.debugger.ContextProvider, org.netbeans.api.debugger.jpda.CallStackFrame, org.netbeans.api.debugger.jpda.SmartSteppingFilter)} |
121 |
* @since 3.5 |
122 |
*/ |
123 |
public static final class StopOrStep { |
124 |
|
125 |
private static final StopOrStep STOP = new StopOrStep(true, 0, 0); |
126 |
private static final StopOrStep SKIP = new StopOrStep(false, 0, 0); |
127 |
|
128 |
private final boolean stop; |
129 |
private final int stepSize; |
130 |
private final int stepDepth; |
131 |
|
132 |
/** |
133 |
* Express the possibility to stop. |
134 |
* @return information about a possibility to stop at the given location. |
135 |
*/ |
136 |
public static StopOrStep stop() { |
137 |
return STOP; |
138 |
} |
139 |
|
140 |
/** |
141 |
* Express the necessity to skip the given location, |
142 |
* using whatever the default debugger action is at the moment. |
143 |
* @return information about the necessity to skip the given location. |
144 |
*/ |
145 |
public static StopOrStep skip() { |
146 |
return SKIP; |
147 |
} |
148 |
|
149 |
/** |
150 |
* Express the necessity to perform a step at the given location. |
151 |
* @param stepSize the step size, |
152 |
* one of {@link #JPDAStep.STEP_LINE} or {@link #JPDAStep.STEP_MIN}, |
153 |
* or <code>0</code> for the default size. |
154 |
* @param stepDepth the step depth, |
155 |
* one of {@link #JPDAStep.STEP_INTO}, {@link #JPDAStep.STEP_OVER}, |
156 |
* {@link #JPDAStep.STEP_OUT}, or <code>0</code> for the default depth. |
157 |
* @return the step information instance. |
158 |
* throws {@link IllegalArgumentException} when the size or depth is wrong. |
159 |
*/ |
160 |
public static StopOrStep step(int stepSize, int stepDepth) { |
161 |
return new StopOrStep(false, stepSize, stepDepth); |
162 |
} |
163 |
|
164 |
private StopOrStep(boolean stop, int stepSize, int stepDepth) { |
165 |
this.stop = stop; |
166 |
switch (stepSize) { |
167 |
case 0: |
168 |
case JPDAStep.STEP_MIN: |
169 |
case JPDAStep.STEP_LINE: |
170 |
// O.K. |
171 |
break; |
172 |
default: |
173 |
throw new IllegalArgumentException("Wrong step size: "+stepSize); |
174 |
} |
175 |
switch (stepDepth) { |
176 |
case 0: |
177 |
case JPDAStep.STEP_INTO: |
178 |
case JPDAStep.STEP_OVER: |
179 |
case JPDAStep.STEP_OUT: |
180 |
// O.K. |
181 |
break; |
182 |
default: |
183 |
throw new IllegalArgumentException("Wrong step depth: "+stepDepth); |
184 |
} |
185 |
this.stepSize = stepSize; |
186 |
this.stepDepth = stepDepth; |
187 |
} |
188 |
|
189 |
/** |
190 |
* Whether this is a possibility to stop. |
191 |
* If yes, values of step size and step depth are irrelevant. |
192 |
* @return <code>true</code> if it's possible to stop, <code>false</code> otherwise. |
193 |
*/ |
194 |
public boolean isStop() { |
195 |
return stop; |
196 |
} |
197 |
|
198 |
/** |
199 |
* Get the step size. |
200 |
* @return One of {@link #JPDAStep.STEP_LINE} or {@link #JPDAStep.STEP_MIN}, |
201 |
* or <code>0</code> for the default size. |
202 |
*/ |
203 |
public int getStepSize() { |
204 |
return stepSize; |
205 |
} |
206 |
|
207 |
/** |
208 |
* Get the step depth. |
209 |
* @return One of {@link #JPDAStep.STEP_INTO}, {@link #JPDAStep.STEP_OVER}, |
210 |
* {@link #JPDAStep.STEP_OUT}, or <code>0</code> for the default depth. |
211 |
*/ |
212 |
public int getStepDepth() { |
213 |
return stepDepth; |
214 |
} |
215 |
|
216 |
@Override |
217 |
public boolean equals(Object obj) { |
218 |
if (!(obj instanceof StopOrStep)) { |
219 |
return false; |
220 |
} |
221 |
StopOrStep ss = (StopOrStep) obj; |
222 |
return stop == ss.stop && |
223 |
stepSize == ss.stepSize && |
224 |
stepDepth == ss.stepDepth; |
225 |
} |
226 |
|
227 |
@Override |
228 |
public int hashCode() { |
229 |
return Objects.hash(stop, stepSize, stepDepth); |
230 |
} |
231 |
|
232 |
@Override |
233 |
public String toString() { |
234 |
return "StopOrStep["+stop+","+stepSize+","+stepDepth+"]"; |
235 |
} |
236 |
|
237 |
} |
88 |
|
238 |
|
89 |
/** |
239 |
/** |
90 |
* Declarative registration of a SmartSteppingCallback implementation. |
240 |
* Declarative registration of a SmartSteppingCallback implementation. |