*** empty log message ***
diff --git a/org.eclipse.jdt.debug/model/org/eclipse/jdt/debug/core/JDIDebugModel.java b/org.eclipse.jdt.debug/model/org/eclipse/jdt/debug/core/JDIDebugModel.java index 7b3e2e3..3be5fc5 100644 --- a/org.eclipse.jdt.debug/model/org/eclipse/jdt/debug/core/JDIDebugModel.java +++ b/org.eclipse.jdt.debug/model/org/eclipse/jdt/debug/core/JDIDebugModel.java
@@ -182,7 +182,7 @@ public static IType getType(IMarker marker) { JavaBreakpoint breakpoint= getBreakpoint(marker); if (breakpoint != null) { - return breakpoint.getBreakpointType(); + return breakpoint.getInstalledType(); } return null; }
diff --git a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/ExceptionBreakpoint.java b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/ExceptionBreakpoint.java index b8aa7ad..34d37a6 100644 --- a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/ExceptionBreakpoint.java +++ b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/ExceptionBreakpoint.java
@@ -121,7 +121,7 @@ boolean uncaught= isUncaught(); if (caught || uncaught) { - IType exceptionType = getBreakpointType(); + IType exceptionType = getInstalledType(); if (exceptionType == null) { // internalError(ERROR_BREAKPOINT_NO_TYPE); return; @@ -167,7 +167,7 @@ * An exception breakpoint has been removed */ public void removeFromTarget(JDIDebugTarget target) { - IType type = getBreakpointType(); + IType type = getInstalledType(); if (type == null) { // internalError(ERROR_BREAKPOINT_NO_TYPE); return; @@ -338,9 +338,9 @@ public String getMarkerText(boolean showQualified) { String name; if (showQualified) { - name= getBreakpointType().getFullyQualifiedName(); + name= getInstalledType().getFullyQualifiedName(); } else { - name= getBreakpointType().getElementName(); + name= getInstalledType().getElementName(); } String state= null;
diff --git a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/JDIThread.java b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/JDIThread.java index cf6f26f..efd2b72 100644 --- a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/JDIThread.java +++ b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/JDIThread.java
@@ -76,6 +76,10 @@ */ protected boolean fStepping; protected int fStepCount= 0; + /** + * Whether we should notify of suspend/resume events. + */ + protected boolean fNotify= true; /** * Whether suspended by an event in the VM such as a @@ -584,6 +588,28 @@ setRunning(false, DebugEvent.BREAKPOINT); } + /** + * Suspend this thread for the given breakpoint without sending + * notification of the change. + */ + protected void handleSuspendForBreakpointQuiet(JavaBreakpoint breakpoint) { + fNotify= false; + handleSuspendForBreakpoint(breakpoint); + } + + /** + * Notify interested parties that this thread has been suspended by + * a breakpoint + */ + protected void notifyOfSuspendForBreakpoint(JavaBreakpoint breakpoint) { + fNotify= true; + fireSuspendEvent(DebugEvent.BREAKPOINT); + } + + /** + * Suspend this thread for the given breakpoint. If notify equals <code>true</code>, + * send notification of the change. Otherwise, do not. + */ protected void handleSuspendForBreakpoint(JavaBreakpoint breakpoint) { abortDropAndStep(); fCurrentBreakpoint= breakpoint; @@ -725,7 +751,7 @@ } else { fChildren = null; } - if (!fStepping || fStepCount == 1) { + if ((!fStepping || fStepCount == 1) && fNotify){ fireResumeEvent(detail); } } else { @@ -741,7 +767,9 @@ internalError(e); } fStepping= false; - fireSuspendEvent(detail); + if (fNotify) { + fireSuspendEvent(detail); + } } fEventSuspend = detail != DebugEvent.CLIENT_REQUEST; }
diff --git a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/JavaBreakpoint.java b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/JavaBreakpoint.java index 7c0adf8..1695d52 100644 --- a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/JavaBreakpoint.java +++ b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/JavaBreakpoint.java
@@ -243,7 +243,7 @@ * Returns the type the given breakpoint is installed in * or <code>null</code> a type cannot be resolved. */ - public IType getBreakpointType() { + public IType getInstalledType() { try { String handle = getTypeHandleIdentifier(); if (handle != null) { @@ -267,7 +267,7 @@ * the given breakpoint is associated with, or <code>null</code>. */ public String getTopLevelTypeName() { - IType type = getBreakpointType(); + IType type = getInstalledType(); if (type != null) { while (type.getDeclaringType() != null) { type = type.getDeclaringType(); @@ -294,7 +294,7 @@ public String getBreakpointTypeName(boolean qualified) { String typeName= ""; - typeName= getBreakpointType().getFullyQualifiedName(); + typeName= getInstalledType().getFullyQualifiedName(); if (!qualified) { int index= typeName.lastIndexOf('.'); if (index != -1) {
diff --git a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/LineBreakpoint.java b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/LineBreakpoint.java index 082bf2a..6a6d49b 100644 --- a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/LineBreakpoint.java +++ b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/LineBreakpoint.java
@@ -7,8 +7,9 @@ import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.debug.core.DebugException; import org.eclipse.debug.core.IDebugConstants; +import org.eclipse.debug.core.model.*; import org.eclipse.jdt.core.*; -import org.eclipse.jdt.debug.core.IJavaDebugConstants; +import org.eclipse.jdt.debug.core.*; import com.sun.jdi.*; import com.sun.jdi.event.Event; @@ -16,7 +17,7 @@ import com.sun.jdi.request.BreakpointRequest; import com.sun.jdi.request.EventRequest; -public class LineBreakpoint extends JavaBreakpoint { +public class LineBreakpoint extends JavaBreakpoint implements IJavaEvaluationListener { // Thread label String keys private static final String LINE_BREAKPOINT_SYS= THREAD_LABEL + "line_breakpoint_sys"; @@ -26,6 +27,9 @@ private static final String HITCOUNT= "hitCount"; static String fMarkerType= IJavaDebugConstants.JAVA_LINE_BREAKPOINT; + + protected Event fEvent= null; + /** * Sets of attributes used to configure a line breakpoint */ @@ -46,11 +50,8 @@ public LineBreakpoint(final IType type, final int lineNumber, final int charStart, final int charEnd, final int hitCount, final String markerType) throws DebugException { IWorkspaceRunnable wr= new IWorkspaceRunnable() { public void run(IProgressMonitor monitor) throws CoreException { - IResource resource= null; - resource= type.getUnderlyingResource(); - if (resource == null) { - resource= type.getJavaProject().getProject(); - } + IResource resource= getResource(type); + // create the marker fMarker= resource.createMarker(markerType); @@ -69,9 +70,27 @@ } /** + * Get the resource associated with the given type. This is + * used to set the breakpoint's resource during initialization. + */ + protected IResource getResource(IType type) { + IResource resource= null; + try { + resource= type.getUnderlyingResource(); + if (resource == null) { + resource= type.getJavaProject().getProject(); + } + } catch (JavaModelException jme) { + logError(jme); + } + return resource; + } + + /** * @see JavaBreakpoint#installIn(JDIDebugTarget) */ public void addToTarget(JDIDebugTarget target) { + fTarget= target; String topLevelName= getTopLevelTypeName(); if (topLevelName == null) { // internalError(ERROR_BREAKPOINT_NO_TYPE); @@ -285,18 +304,102 @@ if (!(event instanceof LocatableEvent)) { return; } - ThreadReference threadRef= ((LocatableEvent)event).thread(); - JDIThread thread= target.findThread(threadRef); - if (thread == null) { - target.resume(threadRef); - return; - } else { - thread.handleSuspendForBreakpoint(this); - expireHitCount((LocatableEvent)event); - } + fEvent= event; + ThreadReference threadRef= ((LocatableEvent)fEvent).thread(); + JDIThread thread= target.findThread(threadRef); + thread.handleSuspendForBreakpointQuiet(this); + evaluateCondition(getCondition()); } /** + * Evaluate the given condition in the context of this breakpoint's + * last known target. + */ + public void evaluateCondition(String conditionString) { + if (conditionString.equals("")) { + evaluationComplete(null); + } + IStackFrame stackFrame= getContextFromTarget(fTarget); + IJavaStackFrame adapter= (IJavaStackFrame) stackFrame.getAdapter(IJavaStackFrame.class); + IJavaElement javaElement= getJavaElement(stackFrame); + if (javaElement == null) { + return; + } + IJavaProject project = javaElement.getJavaProject(); + try { + adapter.evaluate(conditionString, this, project); + } catch (DebugException e) { + logError(e); + } + } + + /** + * @see IJavaEvaluationListener + */ + public void evaluationComplete(IJavaEvaluationResult result) { + IValue value= null; + ThreadReference threadRef= ((LocatableEvent)fEvent).thread(); + JDIThread thread= fTarget.findThread(threadRef); + if (result != null) { + value= result.getValue(); + } + if (result == null || result.hasProblems() || value == null || !trueCondition(value)){ + fTarget.resume(threadRef); + } + else { + thread.notifyOfSuspendForBreakpoint(this); + expireHitCount((LocatableEvent)fEvent); + } + } + + /** + * Returns whether the given value represents the boolean value + * "true". + */ + private boolean trueCondition(IValue value) { + try { + if (value.getValueString() == "true") { + return true; + } + } catch (DebugException de) { + } + return false; + } + + protected IJavaElement getJavaElement(IStackFrame stackFrame) { + // Get the corresponding element. + ISourceLocator locator= stackFrame.getSourceLocator(); + if (locator == null) + return null; + + Object sourceElement = locator.getSourceElement(stackFrame); + if (sourceElement instanceof IType) + return (IType) sourceElement; + + return null; + } + + /** + * Resolves a stack frame context from the model + */ + protected IStackFrame getContextFromTarget(IDebugTarget dt) { + if (!dt.isTerminated()) { + try { + IDebugElement[] threads= dt.getChildren(); + for (int i= 0; i < threads.length; i++) { + IThread thread= (IThread)threads[i]; + if (thread.isSuspended()) { + return thread.getTopStackFrame(); + } + } + } catch(DebugException x) { + logError(x); + } + } + return null; + } + + /** * Called when a breakpoint event is encountered */ public void expireHitCount(LocatableEvent event) { @@ -355,6 +458,14 @@ } /** + * Returns the <code>CONDITION</code> attribute of the given breakpoint + * or "" if the attribute is not set. + */ + public String getCondition() { + return "grah() == 3"; + } + + /** * Returns the <code>HIT_COUNT</code> attribute of the given breakpoint * or -1 if the attribute is not set. */ @@ -448,7 +559,7 @@ public IMember getMember() { int start = getCharStart(); int end = getCharEnd(); - IType type = getBreakpointType(); + IType type = getInstalledType(); IMember member = null; if (type != null && end >= start && start >= 0) { try { @@ -535,7 +646,7 @@ } public String getMarkerText(boolean showQualified, String memberString) { - IType type= getBreakpointType(); + IType type= getInstalledType(); if (type != null) { StringBuffer label= new StringBuffer(); if (showQualified) {
diff --git a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/MethodEntryBreakpoint.java b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/MethodEntryBreakpoint.java index 838dadc..d35251b 100644 --- a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/MethodEntryBreakpoint.java +++ b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/MethodEntryBreakpoint.java
@@ -94,7 +94,7 @@ * Create or update the request. */ public void addToTarget(JDIDebugTarget target) { - IType type = getBreakpointType(); + IType type = getInstalledType(); if (type == null) { // internalError(ERROR_BREAKPOINT_NO_TYPE); return;
diff --git a/org.eclipse.jdt.debug/plugin.xml b/org.eclipse.jdt.debug/plugin.xml index fc7a07b..c5d99aa 100644 --- a/org.eclipse.jdt.debug/plugin.xml +++ b/org.eclipse.jdt.debug/plugin.xml
@@ -60,6 +60,9 @@ <attribute name="expired"> </attribute> + <attribute + name="condition"> + </attribute> </extension> <extension id="javaRunToLineBreakpoint"