package jetbrains.mps.debug.api.breakpoints;
/*Generated by MPS */
import jetbrains.mps.textgen.trace.NodeTraceInfo;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.mps.openapi.model.SNodeReference;
import org.jetbrains.mps.openapi.model.SNode;
import jetbrains.mps.textgen.trace.TraceInfoCache;
import org.jetbrains.annotations.Nullable;
import jetbrains.mps.textgen.trace.TraceablePositionInfo;
import org.jetbrains.mps.openapi.model.SModelReference;
/**
* Connects node breakpoint with target code location using generation trace information.
* Given debug info may disappear between debug sessions, location may become invalid. It's up to specific breakpoint to update the location.
* XXX Seems reasonable to have persistence-friendly abstraction for location (i.e. smth we persist regardless of actual node/trace info availability)
* Now it's SNodeReference, while this class serves both to identify location and perform logic around it. Perhaps, shall strip this class down to
* persistence stuff (i.e. SNodeReference), and move target code association code elsewhere?
*
* NOTE, with all the attempts to improve it, it's bad design anyway. Location API shall not expose implementation details like TraceablePositionInfo at all.
*/
public class BreakpointLocation {
private final NodeTraceInfo myTargetCodeLocation;
public BreakpointLocation(@NotNull SNodeReference nodePointer) {
myTargetCodeLocation = new NodeTraceInfo(nodePointer);
}
public BreakpointLocation(@NotNull SNode node) {
assert node.getModel() != null : "Tracing doesn't make sense for free-floating nodes";
myTargetCodeLocation = new NodeTraceInfo(node, TraceInfoCache.getInstance().get(node.getModel()));
}
@NotNull
public SNodeReference getNodePointer() {
return myTargetCodeLocation.getNode();
}
@Nullable
public TraceablePositionInfo getTargetCodePosition() {
return myTargetCodeLocation.getPosition();
}
@Nullable
public String getTargetUnitName() {
return myTargetCodeLocation.getUnitName();
}
/**
*
* @deprecated meaningless and unused
*/
@Deprecated
public boolean isValid() {
return getTargetCodePosition() != null;
}
public int getLineIndexInFile() {
TraceablePositionInfo pos = getTargetCodePosition();
return (pos == null ? -1 : pos.getStartLine() + 1);
}
@Nullable
public String getFileName() {
return myTargetCodeLocation.getFileName();
}
public String getPresentation() {
SNodeReference nodePointer = myTargetCodeLocation.getNode();
return String.format("%s/%s", nodePointer.getModelReference().getModelName(), nodePointer.getNodeId());
}
public SModelReference getModelReference() {
return myTargetCodeLocation.getNode().getModelReference();
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || this.getClass() != o.getClass()) {
return false;
}
SNodeReference nodePointer = myTargetCodeLocation.getNode();
return nodePointer.equals(((BreakpointLocation) o).myTargetCodeLocation.getNode());
}
@Override
public int hashCode() {
return myTargetCodeLocation.getNode().hashCode();
}
}