/******************************************************************************* * Copyright (c) 2007 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.jdt.debug.test.stepping; import org.eclipse.debug.core.DebugEvent; import org.eclipse.debug.core.DebugException; import org.eclipse.debug.core.model.ILineBreakpoint; import org.eclipse.jdt.debug.core.IJavaDebugTarget; import org.eclipse.jdt.debug.core.IJavaStackFrame; import org.eclipse.jdt.debug.core.IJavaThread; import org.eclipse.jdt.debug.core.IJavaValue; import org.eclipse.jdt.debug.core.IJavaVariable; import org.eclipse.jdt.debug.testplugin.DebugElementEventWaiter; import org.eclipse.jdt.debug.tests.AbstractDebugTest; import com.sun.jdi.InvalidTypeException; /** * Tests forcing return from method. * * @since 3.3 */ public class ForceReturnTests extends AbstractDebugTest { /** * Creates test case. * * @param name test name */ public ForceReturnTests(String name) { super(name); } /** * Tests forcing the return of an integer from top stack frame * * @throws Exception */ public void testForceIntReturnTopFrame() throws Exception { String typeName = "ForceReturnTests"; ILineBreakpoint bp2 = createLineBreakpoint(22, typeName); ILineBreakpoint bp = createLineBreakpoint(31, typeName); IJavaThread thread = null; try { thread= launchToLineBreakpoint(typeName, bp, false); IJavaStackFrame stackFrame = (IJavaStackFrame) thread.getTopStackFrame(); IJavaDebugTarget target = (IJavaDebugTarget) stackFrame.getDebugTarget(); if (target.supportsForceReturn()) { assertTrue("Force return should be enabled", stackFrame.canForceReturn()); DebugElementEventWaiter waiter = new DebugElementEventWaiter(DebugEvent.SUSPEND, thread); stackFrame.forceReturn(target.newValue(42)); Object source = waiter.waitForEvent(); assertTrue("Suspend should be from thread", source instanceof IJavaThread); thread = (IJavaThread) source; stackFrame = (IJavaStackFrame) thread.getTopStackFrame(); if (stackFrame.getLineNumber() < 22) { // @see bug 197282. Some VMs optimize the variable assignment and may // already have performed the assignment thread = resumeToLineBreakpoint(thread, bp2); stackFrame = (IJavaStackFrame) thread.getTopStackFrame(); } IJavaVariable var = stackFrame.findVariable("x"); assertNotNull("Missing variable 'x'", var); assertEquals("Return value incorrect", target.newValue(42), var.getValue()); } } finally { terminateAndRemove(thread); removeAllBreakpoints(); } } /** * Tests forcing the return of an integer from non-top stack frame * * @throws Exception */ public void testForceIntReturn() throws Exception { String typeName = "ForceReturnTestsTwo"; ILineBreakpoint bp2 = createLineBreakpoint(23, typeName); ILineBreakpoint bp = createLineBreakpoint(37, typeName); IJavaThread thread = null; try { thread= launchToLineBreakpoint(typeName, bp, false); IJavaStackFrame stackFrame = (IJavaStackFrame) thread.getTopStackFrame(); IJavaDebugTarget target = (IJavaDebugTarget) stackFrame.getDebugTarget(); if (target.supportsForceReturn()) { assertTrue("Force return should be enabled", stackFrame.canForceReturn()); DebugElementEventWaiter waiter = new DebugElementEventWaiter(DebugEvent.SUSPEND, thread); IJavaValue retValue = target.newValue(1); stackFrame = (IJavaStackFrame) thread.getStackFrames()[1]; stackFrame.forceReturn(retValue); Object source = waiter.waitForEvent(); assertTrue("Suspend should be from thread", source instanceof IJavaThread); thread = (IJavaThread) source; stackFrame = (IJavaStackFrame) thread.getTopStackFrame(); if (stackFrame.getLineNumber() < 23) { // @see bug 197282. Some VMs optimize the variable assignment and may // already have performed the assignment thread = resumeToLineBreakpoint(thread, bp2); stackFrame = (IJavaStackFrame) thread.getTopStackFrame(); } IJavaVariable var = stackFrame.findVariable("x"); assertNotNull("Missing variable 'x'", var); assertEquals("Return value incorrect", retValue, var.getValue()); } } finally { terminateAndRemove(thread); removeAllBreakpoints(); } } /** * Tests forcing the return of a string from top frame * * @throws Exception */ public void testForceStringReturnTopFrame() throws Exception { String typeName = "ForceReturnTests"; ILineBreakpoint bp2 = createLineBreakpoint(24, typeName); ILineBreakpoint bp = createLineBreakpoint(36, typeName); IJavaThread thread = null; try { thread= launchToLineBreakpoint(typeName, bp, false); IJavaStackFrame stackFrame = (IJavaStackFrame) thread.getTopStackFrame(); IJavaDebugTarget target = (IJavaDebugTarget) stackFrame.getDebugTarget(); if (target.supportsForceReturn()) { assertTrue("Force return should be enabled", stackFrame.canForceReturn()); DebugElementEventWaiter waiter = new DebugElementEventWaiter(DebugEvent.SUSPEND, thread); IJavaValue stringValue = target.newValue("forty two"); stackFrame.forceReturn(stringValue); Object source = waiter.waitForEvent(); assertTrue("Suspend should be from thread", source instanceof IJavaThread); thread = (IJavaThread) source; stackFrame = (IJavaStackFrame) thread.getTopStackFrame(); if (stackFrame.getLineNumber() < 24) { // @see bug 197282. Some VMs optimize the variable assignment and may // already have performed the assignment thread = resumeToLineBreakpoint(thread, bp2); stackFrame = (IJavaStackFrame) thread.getTopStackFrame(); } IJavaVariable var = stackFrame.findVariable("s"); assertNotNull("Missing variable 's'", var); assertEquals("Return value incorrect", stringValue, var.getValue()); } } finally { terminateAndRemove(thread); removeAllBreakpoints(); } } /** * Tests forcing the return of a string from a non top frame * * @throws Exception */ public void testForceStringReturn() throws Exception { String typeName = "ForceReturnTestsTwo"; ILineBreakpoint bp2 = createLineBreakpoint(25, typeName); ILineBreakpoint bp = createLineBreakpoint(46, typeName); IJavaThread thread = null; try { thread= launchToLineBreakpoint(typeName, bp, false); IJavaStackFrame stackFrame = (IJavaStackFrame) thread.getTopStackFrame(); IJavaDebugTarget target = (IJavaDebugTarget) stackFrame.getDebugTarget(); if (target.supportsForceReturn()) { assertTrue("Force return should be enabled", stackFrame.canForceReturn()); DebugElementEventWaiter waiter = new DebugElementEventWaiter(DebugEvent.SUSPEND, thread); IJavaValue stringValue = target.newValue("forty two"); stackFrame = (IJavaStackFrame) thread.getStackFrames()[1]; stackFrame.forceReturn(stringValue); Object source = waiter.waitForEvent(); assertTrue("Suspend should be from thread", source instanceof IJavaThread); thread = (IJavaThread) source; stackFrame = (IJavaStackFrame) thread.getTopStackFrame(); if (stackFrame.getLineNumber() < 25) { // @see bug 197282. Some VMs optimize the variable assignment and may // already have performed the assignment thread = resumeToLineBreakpoint(thread, bp2); stackFrame = (IJavaStackFrame) thread.getTopStackFrame(); } IJavaVariable var = stackFrame.findVariable("s"); assertNotNull("Missing variable 's'", var); assertEquals("Return value incorrect", stringValue, var.getValue()); } } finally { terminateAndRemove(thread); removeAllBreakpoints(); } } /** * Tests forcing the return of an object from top frame. * * @throws Exception */ public void testForceObjectReturnTopFrame() throws Exception { String typeName = "ForceReturnTests"; ILineBreakpoint bp2 = createLineBreakpoint(26, typeName); ILineBreakpoint bp = createLineBreakpoint(43, typeName); IJavaThread thread = null; try { thread= launchToLineBreakpoint(typeName, bp, false); IJavaStackFrame stackFrame = (IJavaStackFrame) thread.getTopStackFrame(); IJavaDebugTarget target = (IJavaDebugTarget) stackFrame.getDebugTarget(); if (target.supportsForceReturn()) { assertTrue("Force return should be enabled", stackFrame.canForceReturn()); DebugElementEventWaiter waiter = new DebugElementEventWaiter(DebugEvent.SUSPEND, thread); IJavaValue objectValue = target.newValue("a string"); stackFrame.forceReturn(objectValue); Object source = waiter.waitForEvent(); assertTrue("Suspend should be from thread", source instanceof IJavaThread); thread = (IJavaThread) source; stackFrame = (IJavaStackFrame) thread.getTopStackFrame(); if (stackFrame.getLineNumber() < 26) { // @see bug 197282. Some VMs optimize the variable assignment and may // already have performed the assignment thread = resumeToLineBreakpoint(thread, bp2); stackFrame = (IJavaStackFrame) thread.getTopStackFrame(); } IJavaVariable var = stackFrame.findVariable("v"); assertNotNull("Missing variable 'v'", var); assertEquals("Return value incorrect", objectValue, var.getValue()); } } finally { terminateAndRemove(thread); removeAllBreakpoints(); } } /** * Tests forcing the return of an object from non-top frame. * * @throws Exception */ public void testForceObjectReturn() throws Exception { String typeName = "ForceReturnTestsTwo"; ILineBreakpoint bp2 = createLineBreakpoint(27, typeName); ILineBreakpoint bp = createLineBreakpoint(56, typeName); IJavaThread thread = null; try { thread= launchToLineBreakpoint(typeName, bp, false); IJavaStackFrame stackFrame = (IJavaStackFrame) thread.getTopStackFrame(); IJavaDebugTarget target = (IJavaDebugTarget) stackFrame.getDebugTarget(); if (target.supportsForceReturn()) { assertTrue("Force return should be enabled", stackFrame.canForceReturn()); DebugElementEventWaiter waiter = new DebugElementEventWaiter(DebugEvent.SUSPEND, thread); IJavaValue objectValue = target.newValue("a string"); stackFrame = (IJavaStackFrame) thread.getStackFrames()[1]; stackFrame.forceReturn(objectValue); Object source = waiter.waitForEvent(); assertTrue("Suspend should be from thread", source instanceof IJavaThread); thread = (IJavaThread) source; stackFrame = (IJavaStackFrame) thread.getTopStackFrame(); if (stackFrame.getLineNumber() < 27) { // @see bug 197282. Some VMs optimize the variable assignment and may // already have performed the assignment thread = resumeToLineBreakpoint(thread, bp2); stackFrame = (IJavaStackFrame) thread.getTopStackFrame(); } IJavaVariable var = stackFrame.findVariable("v"); assertNotNull("Missing variable 'v'", var); assertEquals("Return value incorrect", objectValue, var.getValue()); } } finally { terminateAndRemove(thread); removeAllBreakpoints(); } } /** * Tests that an incompatible type causes an exception in top frame * * @throws Exception */ public void testIncompatibleReturnTypeTopFrame() throws Exception { String typeName = "ForceReturnTests"; ILineBreakpoint bp = createLineBreakpoint(43, typeName); IJavaThread thread = null; try { thread= launchToLineBreakpoint(typeName, bp, false); IJavaStackFrame stackFrame = (IJavaStackFrame) thread.getTopStackFrame(); IJavaDebugTarget target = (IJavaDebugTarget) stackFrame.getDebugTarget(); if (target.supportsForceReturn()) { assertTrue("Force return should be enabled", stackFrame.canForceReturn()); IJavaValue objectValue = target.newValue(42); try { stackFrame.forceReturn(objectValue); } catch (DebugException e) { assertTrue("Should be invalid type exception", e.getStatus().getException() instanceof InvalidTypeException); return; } assertTrue("Should have caused incompatible return type exception", false); } } finally { terminateAndRemove(thread); removeAllBreakpoints(); } } /** * Tests that an incompatible type causes an exception in non top frame * * @throws Exception */ public void testIncompatibleReturnType() throws Exception { String typeName = "ForceReturnTestsTwo"; ILineBreakpoint bp = createLineBreakpoint(46, typeName); IJavaThread thread = null; try { thread= launchToLineBreakpoint(typeName, bp, false); IJavaStackFrame stackFrame = (IJavaStackFrame) thread.getTopStackFrame(); IJavaDebugTarget target = (IJavaDebugTarget) stackFrame.getDebugTarget(); if (target.supportsForceReturn()) { assertTrue("Force return should be enabled", stackFrame.canForceReturn()); IJavaValue objectValue = target.newValue(42); stackFrame = (IJavaStackFrame) thread.getStackFrames()[1]; try { stackFrame.forceReturn(objectValue); } catch (DebugException e) { assertTrue("Should be invalid type exception", e.getStatus().getException() instanceof InvalidTypeException); return; } assertTrue("Should have caused incompatible return type exception", false); } } finally { terminateAndRemove(thread); removeAllBreakpoints(); } } }