This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.

View | Details | Raw Unified | Return to bug 255918
Collapse All | Expand All

(-)a/api.debugger.jpda/apichanges.xml (+16 lines)
Lines 922-927 Link Here
922
        <class package="org.netbeans.api.debugger.jpda" name="ClassVariable" />
922
        <class package="org.netbeans.api.debugger.jpda" name="ClassVariable" />
923
        <issue number="253295"/>
923
        <issue number="253295"/>
924
    </change>
924
    </change>
925
    
926
    <change>
927
        <api name="JPDADebuggerAPI"/>
928
        <summary>Enhanced smart-stepping.</summary>
929
        <version major="3" minor="5"/>
930
        <date day="21" month="10" year="2015"/>
931
        <author login="mentlicher"/>
932
        <compatibility addition="yes" source="compatible" binary="compatible"/>
933
        <description>
934
            <code>SmartSteppingCallback.stopAt()</code> method added to be able
935
            to override the default smart-stepping logic and provide specific
936
            steps that should be performed at given locations.
937
        </description>
938
        <class package="org.netbeans.spi.debugger.jpda" name="SmartSteppingCallback" />
939
        <issue number="255918"/>
940
    </change>
925
</changes>
941
</changes>
926
942
927
  <!-- Now the surrounding HTML text and document structure: -->
943
  <!-- Now the surrounding HTML text and document structure: -->
(-)a/api.debugger.jpda/manifest.mf (-1 / +1 lines)
Lines 1-6 Link Here
1
Manifest-Version: 1.0
1
Manifest-Version: 1.0
2
OpenIDE-Module: org.netbeans.api.debugger.jpda/2
2
OpenIDE-Module: org.netbeans.api.debugger.jpda/2
3
OpenIDE-Module-Localizing-Bundle: org/netbeans/api/debugger/jpda/Bundle.properties
3
OpenIDE-Module-Localizing-Bundle: org/netbeans/api/debugger/jpda/Bundle.properties
4
OpenIDE-Module-Specification-Version: 3.4
4
OpenIDE-Module-Specification-Version: 3.5
5
OpenIDE-Module-Package-Dependencies: com.sun.jdi[VirtualMachineManager]
5
OpenIDE-Module-Package-Dependencies: com.sun.jdi[VirtualMachineManager]
6
6
(-)a/api.debugger.jpda/src/org/netbeans/spi/debugger/jpda/SmartSteppingCallback.java (+150 lines)
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.

Return to bug 255918