diff --git a/src/Sindarin-Tests/SindarinDebuggerTest.class.st b/src/Sindarin-Tests/SindarinDebuggerTest.class.st index 4dd99e5..d89c2aa 100644 --- a/src/Sindarin-Tests/SindarinDebuggerTest.class.st +++ b/src/Sindarin-Tests/SindarinDebuggerTest.class.st @@ -145,6 +145,18 @@ SindarinDebuggerTest >> methodWithSeveralInstructionsInBlock [ ^ 42 ] +{ #category : #helpers } +SindarinDebuggerTest >> methodWithSeveralReturns [ + "There is only one explicit return but there is also an implicit return after `a := 3`. In that sense, there are several returns in this method" + + | a | + a := true. + a + ifFalse: [ ^ a := 1 ] + ifTrue: [ a := 2 ]. + a := 3 +] + { #category : #helpers } SindarinDebuggerTest >> methodWithTwoAssignments [ @@ -1311,6 +1323,52 @@ SindarinDebuggerTest >> testSkipBlockNode [ self assert: scdbg topStack equals: 43 ] +{ #category : #tests } +SindarinDebuggerTest >> testSkipCanSkipReturnIfItIsNotTheLastReturn [ + + | scdbg | + scdbg := SindarinDebugger debug: [ self methodWithSeveralReturns ]. + + "we step until we arrive on the node `^ a := 1` in `SindarinDebuggerTest>>#methodWithSeveralReturns`." + scdbg + step; + skip; + skip; + step. + + self assert: scdbg node isReturn. + self assert: scdbg topStack equals: 1. + + "We skip the return node" + self shouldnt: [ scdbg skip ] raise: SindarinSkippingReturnWarning. + + "We should be on the `a := 2` node" + self assert: scdbg node isAssignment. + self assert: scdbg node value value equals: 2 +] + +{ #category : #tests } +SindarinDebuggerTest >> testSkipCannotSkipReturnIfItIsTheLastReturn [ + + | scdbg nodeWithImplicitReturn | + scdbg := SindarinDebugger debug: [ self methodWithSeveralReturns ]. + + "we step until we arrive on the method node in `SindarinDebuggerTest>>#methodWithSeveralReturns`, which is mapped to the implicit return bycode." + scdbg step. + nodeWithImplicitReturn := scdbg methodNode. + 3 timesRepeat: [ scdbg step ]. + + self assert: scdbg node identicalTo: nodeWithImplicitReturn. + self assert: scdbg instructionStream willReturn. + + "We skip the return node" + self should: [ scdbg skip ] raise: SindarinSkippingReturnWarning. + + "We should still be on the method node" + self assert: scdbg node identicalTo: nodeWithImplicitReturn. + self assert: scdbg instructionStream willReturn +] + { #category : #tests } SindarinDebuggerTest >> testSkipDoesNotSkipReturn [ diff --git a/src/Sindarin/SindarinDebugger.class.st b/src/Sindarin/SindarinDebugger.class.st index ec10f5c..afa6a32 100644 --- a/src/Sindarin/SindarinDebugger.class.st +++ b/src/Sindarin/SindarinDebugger.class.st @@ -437,7 +437,11 @@ SindarinDebugger >> skipReturnNode [ "If this is the last node of the method that is mapped to a return bytecode, we can't skip it and we stop there." node == allReturnNodes last ifTrue: [ ^ SindarinSkippingReturnWarning signal: - 'Cannot skip the last return in the method' ] + 'Cannot skip the last return in the method' ]. + + self skipPcToNextBytecode. + self debugSession stepToFirstInterestingBytecodeWithJumpIn: + self debugSession interruptedProcess ] { #category : #'stepping - skip' }