package com.github.sdbg.debug.core.internal.webkit.model;
import com.github.sdbg.debug.core.SDBGDebugCorePlugin;
import com.github.sdbg.debug.core.internal.webkit.protocol.WebkitCallFrame;
import com.github.sdbg.debug.core.internal.webkit.protocol.WebkitDebugger.PausedReasonType;
import com.github.sdbg.debug.core.internal.webkit.protocol.WebkitLocation;
import com.github.sdbg.debug.core.internal.webkit.protocol.WebkitRemoteObject;
import com.github.sdbg.debug.core.internal.webkit.protocol.WebkitResteppingManager;
import java.util.List;
import org.eclipse.core.resources.IStorage;
public class WebkitResteppingManagerImpl implements WebkitResteppingManager {
private WebkitDebugTarget target;
private String stepCommand;
private SourceMapManager.SourceLocation stepLocation;
private boolean restep;
private String restepCommand;
public WebkitResteppingManagerImpl(WebkitDebugTarget target) {
this.target = target;
}
@Override
public String getRestepCommand() {
return restepCommand != null ? restepCommand : stepCommand;
}
@Override
public boolean isResteppingNeeded() {
return restep;
}
@Override
public void onDebuggerPaused(List<WebkitCallFrame> frames, PausedReasonType reason,
WebkitRemoteObject exception) {
SourceMapManager.SourceLocation currentLocation = null;
WebkitCallFrame frame = frames.isEmpty() ? null : frames.get(0);
if (frame != null) {
IStorage storage = target.getScriptStorageFor(frame);
if (target.getSourceMapManager().isMapSource(storage)) {
WebkitLocation location = frame.getLocation();
currentLocation = target.getSourceMapManager().getMappingFor(
storage,
location.getLineNumber(),
location.getColumnNumber());
}
}
if (SDBGDebugCorePlugin.getPlugin().getUseSmartStepInOut() && currentLocation == null
&& stepLocation != null) {
// Filter out frames that are NOT sourcemapped but are otherwise inside sourcemapped files
restepCommand = stepCommand.equals("Debugger.stepOver") ? "Debugger.stepInto" : stepCommand;
restep = true;
return;
} else if (SDBGDebugCorePlugin.getPlugin().getUseSmartStepOver() && exception == null
&& reason == PausedReasonType.other && currentLocation != null && stepLocation != null
&& stepCommand != null
&& currentLocation.getPath().equals(stepLocation.getPath())
&& currentLocation.getLine() == stepLocation.getLine()) {
// Restepping is needed if we are still on the same line in the same Java source file
// TODO: The above comparison is way too simplistic, the whole set of stackframes should be compared
restepCommand = null;
restep = true;
return;
}
stepLocation = currentLocation;
restep = false;
}
@Override
public void onStepping(String stepCommand) {
this.stepCommand = stepCommand;
}
}