blob: 6081417b3c95c673776660591ca485230e1ef294 [file] [log] [blame]
/**********************************************************************
* This file is part of "Object Teams Development Tooling"-Software
*
* Copyright 2004, 2019 Fraunhofer Gesellschaft, Munich, Germany,
* for its Fraunhofer Institute for Computer Architecture and Software
* Technology (FIRST), Berlin, Germany and Technical University Berlin,
* Germany.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
* $Id$
*
* Please visit http://www.eclipse.org/objectteams for updates and contact.
*
* Contributors:
* Fraunhofer FIRST - Initial API and implementation
* Technical University Berlin - Initial API and implementation
**********************************************************************/
package org.eclipse.objectteams.otdt.debug.internal;
import org.eclipse.debug.core.DebugEvent;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.IDebugEventFilter;
import org.eclipse.debug.core.model.IStackFrame;
import org.eclipse.jdt.debug.core.IJavaDebugTarget;
import org.eclipse.jdt.internal.debug.core.model.JDIStackFrame;
import org.eclipse.jdt.internal.debug.core.model.JDIThread;
import org.eclipse.objectteams.otdt.core.compiler.ISMAPConstants;
/**
* @author ike
*
*/
public class StepFromLinenumberGenerator implements IDebugEventFilter, ISMAPConstants
{
private static StepFromLinenumberGenerator _stepGenerator;
public static StepFromLinenumberGenerator getInstance()
{
if (_stepGenerator == null)
{
_stepGenerator = new StepFromLinenumberGenerator();
}
return _stepGenerator;
}
public DebugEvent[] filterDebugEvents(DebugEvent[] events)
{
for (int index = 0; index < events.length; index++)
{
DebugEvent event = events[index];
JDIThread thread = getThreadFromEvent(event);
if (thread == null)
{
return events;
}
try
{
IStackFrame topStackframe = getStackFrame(thread);
if (isResumeEvent(event) || (topStackframe == null))
{
return events;
}
//every time a STEP_OVER_LINENUMBER is detected, step over it
if (isStepOverElement(topStackframe) && isSuspendEvent(event))
{
generateStepOver(thread);
return filterEvent(events, index);
}
//every time a STEP_INTO_LINENUMBER is detected step into it
if (isStepIntoElement(topStackframe) && isSuspendEvent(event))
{
generateStepInto(thread);
return filterEvent(events, index);
}
}
catch (DebugException e)
{
//TODO(ike): handle exception
e.printStackTrace();
return events;
}
}
return events;
}
private boolean isResumeEvent(DebugEvent event)
{
return (event.getKind() == DebugEvent.RESUME);
}
private boolean isSuspendEvent(DebugEvent event)
{
return (event.getKind() == DebugEvent.SUSPEND);
}
private boolean isStepOverElement(IStackFrame topStackframe) throws DebugException
{
if (topStackframe.getLineNumber() == STEP_OVER_LINENUMBER)
return true;
String currClass = ((JDIStackFrame)topStackframe).getDeclaringTypeName();
if (currClass.equals("org.objectteams.Team")) { //$NON-NLS-1$
String currMethod = ((JDIStackFrame)topStackframe).getMethodName();
if (currMethod.equals("_OT$callBefore") || currMethod.equals("_OT$callAfter")) { //$NON-NLS-1$ //$NON-NLS-2$
return true;
}
}
return false;
}
private boolean isStepIntoElement(IStackFrame topStackframe) throws DebugException
{
if (topStackframe.getLineNumber() == STEP_INTO_LINENUMBER)
return true;
String currClass = ((JDIStackFrame)topStackframe).getDeclaringTypeName();
if (currClass.equals("org.objectteams.Team")) { //$NON-NLS-1$
String currMethod = ((JDIStackFrame)topStackframe).getMethodName();
switch (currMethod) {
case "_OT$callAllBindings": //$NON-NLS-1$
case "_OT$callReplace": //$NON-NLS-1$
case "_OT$callNext": //$NON-NLS-1$
case "_OT$terminalCallNext": //$NON-NLS-1$
return true;
}
}
return false;
}
private IStackFrame getStackFrame(JDIThread thread) throws DebugException
{
if (thread.hasStackFrames())
{
return thread.getTopStackFrame();
}
return null;
}
private JDIThread getThreadFromEvent(DebugEvent event)
{
if (event.getSource() instanceof JDIThread)
{
return (JDIThread) event.getSource();
}
return null;
}
/** Filter event with given index.
*/
private DebugEvent[] filterEvent(DebugEvent[] events, int index)
{
DebugEvent[] filtered = new DebugEvent[events.length - 1];
if (filtered.length > 0)
{
int j = 0;
for (int idx = 0; idx < events.length; idx++)
{
if (idx != index)
{
filtered[j] = events[idx];
j++;
}
}
}
return filtered;
}
/** Generates and performs a single stepInto in the given thread.
*/
private void generateStepInto(JDIThread thread)
{
IJavaDebugTarget debugTarget = (IJavaDebugTarget) thread.getDebugTarget();
try
{
thread.stepInto();
}
catch (DebugException e)
{
DebugPlugin.getDefault().fireDebugEventSet( new DebugEvent[] { new DebugEvent(debugTarget, DebugEvent.CHANGE) });
}
}
/** Generates and performs a single stepOver in the given thread.
*/
private void generateStepOver(JDIThread thread)
{
IJavaDebugTarget debugTarget = (IJavaDebugTarget) thread.getDebugTarget();
try
{
thread.stepOver();
}
catch (DebugException e)
{
DebugPlugin.getDefault().fireDebugEventSet( new DebugEvent[] { new DebugEvent(debugTarget, DebugEvent.CHANGE) });
}
}
}