package jetbrains.mps.debugger.java.runtime.evaluation.model;
/*Generated by MPS */
import org.apache.log4j.Logger;
import org.apache.log4j.LogManager;
import jetbrains.mps.debugger.java.api.state.JavaUiState;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.mps.openapi.model.SNode;
import jetbrains.mps.debugger.java.api.state.proxy.JavaStackFrame;
import jetbrains.mps.debugger.java.api.state.proxy.JavaLocation;
import jetbrains.mps.debug.api.AbstractDebugSession;
import jetbrains.mps.textgen.trace.TraceInfoProvider;
import java.util.Iterator;
import jetbrains.mps.textgen.trace.DebugInfo;
import org.jetbrains.mps.openapi.model.SNodeReference;
import jetbrains.mps.textgen.trace.BaseLanguageNodeLookup;
import org.jetbrains.annotations.NotNull;
import java.util.List;
import org.jetbrains.mps.openapi.module.SModule;
import java.util.Set;
import jetbrains.mps.project.facets.JavaModuleOperations;
import java.util.Collections;
import jetbrains.mps.reloading.CommonPaths;
import jetbrains.mps.internal.collections.runtime.ListSequence;
import java.util.ArrayList;
import java.util.Map;
import jetbrains.mps.baseLanguage.closures.runtime._FunctionTypes;
import jetbrains.mps.internal.collections.runtime.MapSequence;
import java.util.LinkedHashMap;
import jetbrains.mps.debugger.java.api.state.watchables.JavaLocalVariable;
import com.sun.jdi.Type;
import org.apache.log4j.Level;
import com.sun.jdi.ClassNotLoadedException;
import com.sun.jdi.InvalidStackFrameException;
import jetbrains.mps.lang.smodel.generator.smodelAdapter.SConceptOperations;
import jetbrains.mps.smodel.adapter.structure.MetaAdapterFactory;
import jetbrains.mps.lang.smodel.generator.smodelAdapter.SNodeOperations;
import jetbrains.mps.lang.smodel.generator.smodelAdapter.SLinkOperations;
import jetbrains.mps.smodel.behaviour.BHReflection;
import jetbrains.mps.core.aspects.behaviour.SMethodTrimmedId;
import jetbrains.mps.lang.smodel.generator.smodelAdapter.SPropertyOperations;
import jetbrains.mps.debug.api.programState.IWatchable;
import jetbrains.mps.debugger.java.api.state.watchables.JavaThisObject;
import com.sun.jdi.PrimitiveType;
import com.sun.jdi.BooleanType;
import com.sun.jdi.ByteType;
import com.sun.jdi.ShortType;
import com.sun.jdi.LongType;
import com.sun.jdi.IntegerType;
import com.sun.jdi.DoubleType;
import com.sun.jdi.FloatType;
import com.sun.jdi.CharType;
import com.sun.jdi.ArrayType;
import jetbrains.mps.baseLanguage.closures.runtime.Wrappers;
import jetbrains.mps.debugger.java.api.evaluation.transform.TransformatorBuilder;
import com.sun.jdi.ObjectReference;
import org.jetbrains.mps.openapi.model.SNodeId;
import org.jetbrains.mps.openapi.persistence.PersistenceFacade;
import jetbrains.mps.smodel.SModelUtil_new;
import jetbrains.mps.lang.typesystem.runtime.HUtil;
/*package*/ class StackFrameContext extends EvaluationContext {
private static final Logger LOG = LogManager.getLogger(StackFrameContext.class);
public StackFrameContext(JavaUiState uiState) {
super(uiState);
}
@Nullable
@Override
public SNode getLocationNode() {
JavaStackFrame javaStackFrame = myUiState.getStackFrame();
JavaLocation location;
// FIXME is there true need to access node, not SNodeReference here?
if (javaStackFrame != null && (location = javaStackFrame.getLocation()) != null) {
AbstractDebugSession<?> debugSession = javaStackFrame.getThread().getDebugSession();
TraceInfoProvider traceProvider = debugSession.getTraceProvider();
for (Iterator<DebugInfo> it = traceProvider.debugInfo(JavaUiState.modelNameFromLocation(location)).iterator(); it.hasNext();) {
SNodeReference n = new BaseLanguageNodeLookup(it.next()).getNodeAt(location.getFileName(), location.getLineNumber());
if (n == null) {
continue;
}
SNode resolved = n.resolve(debugSession.getProject().getRepository());
if (resolved != null) {
return resolved;
}
}
}
return null;
}
@NotNull
@Override
public List<String> getClassPath() {
SModule locationModule = getLocationModule();
if (locationModule == null) {
return super.getClassPath();
}
// todo duplication between this method and java.getClasspath
// but java command is in execution.configurations plugin, so the dependency is backward
Set<String> classpath = JavaModuleOperations.collectExecuteClasspath(Collections.singleton(locationModule));
classpath.removeAll(CommonPaths.getJDKPath());
return ListSequence.fromListWithValues(new ArrayList<String>(), classpath);
}
@NotNull
@Override
public Map<String, VariableDescription> getVariables(final _FunctionTypes._return_P1_E0<? extends SNode, ? super String> createClassifierType) {
final Map<String, VariableDescription> result = MapSequence.fromMap(new LinkedHashMap<String, VariableDescription>(16, (float) 0.75, false));
foreachVariable(new _FunctionTypes._return_P1_E0<Boolean, JavaLocalVariable>() {
public Boolean invoke(JavaLocalVariable variable) {
String name = variable.getName();
Type jdiType = null;
try {
jdiType = variable.getLocalVariable().type();
SNode type = getMpsTypeFromJdiType(jdiType, createClassifierType);
if (type == null) {
if (LOG.isEnabledFor(Level.WARN)) {
LOG.warn("Could not deduce type for a variable " + name);
}
} else {
VariableDescription variableDescription = new VariableDescription(name, type);
fillVariableDescription(name, variableDescription);
MapSequence.fromMap(result).put(name, variableDescription);
}
} catch (ClassNotLoadedException cne) {
if (jdiType == null) {
SNode classifierType = createClassifierType.invoke(variable.getLocalVariable().typeName());
if (classifierType == null) {
if (LOG.isEnabledFor(Level.WARN)) {
LOG.warn("Could not deduce type for a variable " + name);
}
} else {
VariableDescription variableDescription = new VariableDescription(name, classifierType);
fillVariableDescription(name, variableDescription);
MapSequence.fromMap(result).put(name, variableDescription);
}
} else {
if (LOG.isEnabledFor(Level.WARN)) {
LOG.warn("Exception when creating variable " + name, cne);
}
}
}
return false;
}
});
return result;
}
public void fillVariableDescription(String varName, VariableDescription description) {
JavaStackFrame javaStackFrame = myUiState.getStackFrame();
JavaLocation javaLocation;
if (javaStackFrame != null && (javaLocation = javaStackFrame.getLocation()) != null) {
try {
// XXX Code identical to JavaLocalVariable.getSourceNode
AbstractDebugSession<?> debugSession = javaStackFrame.getThread().getDebugSession();
TraceInfoProvider traceProvider = debugSession.getTraceProvider();
for (Iterator<DebugInfo> it = traceProvider.debugInfo(JavaUiState.modelNameFromLocation(javaLocation)).iterator(); it.hasNext();) {
DebugInfo di = it.next();
List<SNodeReference> varNodes = di.getVariableNodesForPosition(javaLocation.getFileName(), javaLocation.getLineNumber(), varName);
if (varNodes.isEmpty()) {
continue;
}
SNode node = varNodes.get(0).resolve(debugSession.getProject().getRepository());
if (node != null) {
description.setHighLevelNode(node);
break;
}
}
} catch (InvalidStackFrameException e) {
if (LOG.isEnabledFor(Level.WARN)) {
LOG.warn("InvalidStackFrameException", e);
}
}
}
}
private void foreachVariable(_FunctionTypes._return_P1_E0<? extends Boolean, ? super JavaLocalVariable> action) {
JavaStackFrame javaStackFrame = myUiState.getStackFrame();
if (javaStackFrame != null) {
List<JavaLocalVariable> visibleVariables = javaStackFrame.getVisibleVariables();
for (JavaLocalVariable variable : ListSequence.fromList(visibleVariables)) {
if (action.invoke(variable)) {
return;
}
}
}
}
@Nullable
@Override
public SNode getStaticContextType(_FunctionTypes._return_P1_E0<? extends SNode, ? super String> createClassifierType) {
final String unitType = getStaticContextTypeName();
if (unitType == null) {
return null;
}
SNode result = SConceptOperations.createNewNode(MetaAdapterFactory.getConcept(0x7da4580f9d754603L, 0x816251a896d78375L, 0x3c2f40ee0bb3cbf5L, "jetbrains.mps.debugger.java.evaluation.structure.UnitNode"));
SNode lowLevelType = createClassifierType.invoke(unitType);
SNode highLevelNode = getStaticContextNode();
if (SNodeOperations.isInstanceOf(highLevelNode, MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x101d9d3ca30L, "jetbrains.mps.baseLanguage.structure.Classifier"))) {
SLinkOperations.setTarget(result, MetaAdapterFactory.getContainmentLink(0x7da4580f9d754603L, 0x816251a896d78375L, 0x3c2f40ee0bb3cbf5L, 0x3f11b1341fa2c39cL, "debuggedType"), VariableDescription.createDebuggedType(lowLevelType, ((SNode) BHReflection.invoke(SNodeOperations.cast(highLevelNode, MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x101d9d3ca30L, "jetbrains.mps.baseLanguage.structure.Classifier")), SMethodTrimmedId.create("getThisType", null, "2RtWPFZ12w7")))));
} else if (SNodeOperations.isInstanceOf(highLevelNode, MetaAdapterFactory.getInterfaceConcept(0x443f4c36fcf54eb6L, 0x95008d06ed259e3eL, 0x118bc6b2af5L, "jetbrains.mps.baseLanguage.classifiers.structure.IClassifier"))) {
SLinkOperations.setTarget(result, MetaAdapterFactory.getContainmentLink(0x7da4580f9d754603L, 0x816251a896d78375L, 0x3c2f40ee0bb3cbf5L, 0x3f11b1341fa2c39cL, "debuggedType"), VariableDescription.createDebuggedType(lowLevelType, ((SNode) BHReflection.invoke(SNodeOperations.cast(highLevelNode, MetaAdapterFactory.getInterfaceConcept(0x443f4c36fcf54eb6L, 0x95008d06ed259e3eL, 0x118bc6b2af5L, "jetbrains.mps.baseLanguage.classifiers.structure.IClassifier")), SMethodTrimmedId.create("createType", null, "hEwJimy")))));
} else {
SLinkOperations.setTarget(result, MetaAdapterFactory.getContainmentLink(0x7da4580f9d754603L, 0x816251a896d78375L, 0x3c2f40ee0bb3cbf5L, 0x3f11b1341fa2c39cL, "debuggedType"), VariableDescription.createDebuggedType(lowLevelType, null));
}
SPropertyOperations.set(result, MetaAdapterFactory.getProperty(0x7da4580f9d754603L, 0x816251a896d78375L, 0x3c2f40ee0bb3cbf5L, 0x3c2f40ee0bb3cbf8L, "highLevelNodeId"), check_4zsmpx_a0a6a6(check_4zsmpx_a0a0g0g(highLevelNode)));
return result;
}
private String getStaticContextTypeName() {
JavaStackFrame frame = myUiState.getStackFrame();
if (frame != null) {
JavaLocation location = frame.getLocation();
if (location != null) {
return location.getUnitName();
}
}
return null;
}
private SNode getStaticContextNode() {
JavaStackFrame frame = myUiState.getStackFrame();
if (frame != null) {
JavaLocation location = frame.getLocation();
if (location == null) {
return null;
}
// XXX Code almost identical to JavaThisObject.getSourceNode(), could reuse?
AbstractDebugSession<?> debugSession = frame.getThread().getDebugSession();
TraceInfoProvider traceProvider = debugSession.getTraceProvider();
for (Iterator<DebugInfo> it = traceProvider.debugInfo(JavaUiState.modelNameFromLocation(location)).iterator(); it.hasNext();) {
DebugInfo di = it.next();
List<SNodeReference> unitNodes = di.getUnitNodesForPosition(location.getFileName(), location.getLineNumber());
if (unitNodes.isEmpty()) {
continue;
}
SNode node = unitNodes.get(0).resolve(debugSession.getProject().getRepository());
if (node != null) {
return node;
}
}
}
return null;
}
@Nullable
@Override
public SNode getThisClassifierType(_FunctionTypes._return_P1_E0<? extends SNode, ? super String> createClassifierType) {
IWatchable contextWatchable = myUiState.getStackFrame().getContextWatchable();
// todo
if (contextWatchable == null || !(contextWatchable instanceof JavaThisObject)) {
return null;
}
return getStaticContextType(createClassifierType);
}
@Nullable
private SNode getMpsTypeFromJdiType(Type type, _FunctionTypes._return_P1_E0<? extends SNode, ? super String> createClassifierType) throws ClassNotLoadedException {
// TODO generics
if (type instanceof PrimitiveType) {
if (type instanceof BooleanType) {
return _quotation_createNode_4zsmpx_a0a0a1a01();
}
if (type instanceof ByteType) {
return _quotation_createNode_4zsmpx_a0a1a1a01();
}
if (type instanceof ShortType) {
return _quotation_createNode_4zsmpx_a0a2a1a01();
}
if (type instanceof LongType) {
return _quotation_createNode_4zsmpx_a0a3a1a01();
}
if (type instanceof IntegerType) {
return _quotation_createNode_4zsmpx_a0a4a1a01();
}
if (type instanceof DoubleType) {
return _quotation_createNode_4zsmpx_a0a5a1a01();
}
if (type instanceof FloatType) {
return _quotation_createNode_4zsmpx_a0a6a1a01();
}
if (type instanceof CharType) {
return _quotation_createNode_4zsmpx_a0a7a1a01();
}
} else if (type instanceof ArrayType) {
return _quotation_createNode_4zsmpx_a0a0b0k(getMpsTypeFromJdiType(((ArrayType) type).componentType(), createClassifierType));
}
return createClassifierType.invoke(type.name());
}
@Override
public boolean isVariableVisible(final String variableName, final SNode variableType) {
final Wrappers._boolean visible = new Wrappers._boolean(false);
foreachVariable(new _FunctionTypes._return_P1_E0<Boolean, JavaLocalVariable>() {
public Boolean invoke(JavaLocalVariable variable) {
if (eq_4zsmpx_a0a0a0a0a1a21(variable.getName(), variableName)) {
try {
String variableTypeSignature = TransformatorBuilder.getInstance().getJniSignatureFromType(variableType);
if (eq_4zsmpx_a0b0a0a0a0a0a1a21(variableTypeSignature, variable.getLocalVariable().type().signature())) {
visible.value = true;
return true;
}
} catch (ClassNotLoadedException ex) {
if (LOG.isEnabledFor(Level.WARN)) {
LOG.warn("Exception when checking variable " + variable, ex);
}
}
}
return false;
}
});
return visible.value;
}
@Override
public boolean isThisTypeValid(SNode thisType) {
ObjectReference thisObject = myUiState.getThisObject();
if (thisObject == null) {
return false;
}
return eq_4zsmpx_a0c0n(thisObject.referenceType().signature(), TransformatorBuilder.getInstance().getJniSignatureFromType(thisType));
}
@Override
public boolean isStaticContextTypeValid(SNode staticContextType) {
if (!(SNodeOperations.isInstanceOf(staticContextType, MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x101de48bf9eL, "jetbrains.mps.baseLanguage.structure.ClassifierType")))) {
return false;
}
String staticContextTypeName = getStaticContextTypeName();
if ((staticContextTypeName == null || staticContextTypeName.length() == 0)) {
return false;
}
return staticContextTypeName.equals(((String) BHReflection.invoke(SLinkOperations.getTarget(SNodeOperations.cast(staticContextType, MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x101de48bf9eL, "jetbrains.mps.baseLanguage.structure.ClassifierType")), MetaAdapterFactory.getReferenceLink(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x101de48bf9eL, 0x101de490babL, "classifier")), SMethodTrimmedId.create("getFqName", null, "hEwIO9y"))));
}
private static String check_4zsmpx_a0a6a6(SNodeId checkedDotOperand) {
if (null != checkedDotOperand) {
return checkedDotOperand.toString();
}
return null;
}
private static SNodeId check_4zsmpx_a0a0g0g(SNode checkedDotOperand) {
if (null != checkedDotOperand) {
return checkedDotOperand.getNodeId();
}
return null;
}
private static SNode _quotation_createNode_4zsmpx_a0a0a1a01() {
PersistenceFacade facade = PersistenceFacade.getInstance();
SNode quotedNode_1 = null;
quotedNode_1 = SModelUtil_new.instantiateConceptDeclaration(MetaAdapterFactory.getConcept(MetaAdapterFactory.getLanguage(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, "jetbrains.mps.baseLanguage"), 0xf940d6513eL, "BooleanType"), null, null, false);
return quotedNode_1;
}
private static SNode _quotation_createNode_4zsmpx_a0a1a1a01() {
PersistenceFacade facade = PersistenceFacade.getInstance();
SNode quotedNode_1 = null;
quotedNode_1 = SModelUtil_new.instantiateConceptDeclaration(MetaAdapterFactory.getConcept(MetaAdapterFactory.getLanguage(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, "jetbrains.mps.baseLanguage"), 0xf940d5b617L, "ByteType"), null, null, false);
return quotedNode_1;
}
private static SNode _quotation_createNode_4zsmpx_a0a2a1a01() {
PersistenceFacade facade = PersistenceFacade.getInstance();
SNode quotedNode_1 = null;
quotedNode_1 = SModelUtil_new.instantiateConceptDeclaration(MetaAdapterFactory.getConcept(MetaAdapterFactory.getLanguage(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, "jetbrains.mps.baseLanguage"), 0xf940cc380dL, "ShortType"), null, null, false);
return quotedNode_1;
}
private static SNode _quotation_createNode_4zsmpx_a0a3a1a01() {
PersistenceFacade facade = PersistenceFacade.getInstance();
SNode quotedNode_1 = null;
quotedNode_1 = SModelUtil_new.instantiateConceptDeclaration(MetaAdapterFactory.getConcept(MetaAdapterFactory.getLanguage(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, "jetbrains.mps.baseLanguage"), 0xf8cc67c7f3L, "LongType"), null, null, false);
return quotedNode_1;
}
private static SNode _quotation_createNode_4zsmpx_a0a4a1a01() {
PersistenceFacade facade = PersistenceFacade.getInstance();
SNode quotedNode_1 = null;
quotedNode_1 = SModelUtil_new.instantiateConceptDeclaration(MetaAdapterFactory.getConcept(MetaAdapterFactory.getLanguage(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, "jetbrains.mps.baseLanguage"), 0xf940d22479L, "IntegerType"), null, null, false);
return quotedNode_1;
}
private static SNode _quotation_createNode_4zsmpx_a0a5a1a01() {
PersistenceFacade facade = PersistenceFacade.getInstance();
SNode quotedNode_1 = null;
quotedNode_1 = SModelUtil_new.instantiateConceptDeclaration(MetaAdapterFactory.getConcept(MetaAdapterFactory.getLanguage(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, "jetbrains.mps.baseLanguage"), 0xf940d451a6L, "DoubleType"), null, null, false);
return quotedNode_1;
}
private static SNode _quotation_createNode_4zsmpx_a0a6a1a01() {
PersistenceFacade facade = PersistenceFacade.getInstance();
SNode quotedNode_1 = null;
quotedNode_1 = SModelUtil_new.instantiateConceptDeclaration(MetaAdapterFactory.getConcept(MetaAdapterFactory.getLanguage(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, "jetbrains.mps.baseLanguage"), 0xf940d327fdL, "FloatType"), null, null, false);
return quotedNode_1;
}
private static SNode _quotation_createNode_4zsmpx_a0a7a1a01() {
PersistenceFacade facade = PersistenceFacade.getInstance();
SNode quotedNode_1 = null;
quotedNode_1 = SModelUtil_new.instantiateConceptDeclaration(MetaAdapterFactory.getConcept(MetaAdapterFactory.getLanguage(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, "jetbrains.mps.baseLanguage"), 0xf940d4f826L, "CharType"), null, null, false);
return quotedNode_1;
}
private static SNode _quotation_createNode_4zsmpx_a0a0b0k(Object parameter_1) {
PersistenceFacade facade = PersistenceFacade.getInstance();
SNode quotedNode_2 = null;
SNode quotedNode_3 = null;
quotedNode_2 = SModelUtil_new.instantiateConceptDeclaration(MetaAdapterFactory.getConcept(MetaAdapterFactory.getLanguage(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, "jetbrains.mps.baseLanguage"), 0xf940d819f7L, "ArrayType"), null, null, false);
quotedNode_3 = (SNode) parameter_1;
if (quotedNode_3 != null) {
quotedNode_2.addChild(MetaAdapterFactory.getContainmentLink(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xf940d819f7L, 0xf940d819f8L, "componentType"), HUtil.copyIfNecessary(quotedNode_3));
}
return quotedNode_2;
}
private static boolean eq_4zsmpx_a0a0a0a0a1a21(Object a, Object b) {
return (a != null ? a.equals(b) : a == b);
}
private static boolean eq_4zsmpx_a0b0a0a0a0a0a1a21(Object a, Object b) {
return (a != null ? a.equals(b) : a == b);
}
private static boolean eq_4zsmpx_a0c0n(Object a, Object b) {
return (a != null ? a.equals(b) : a == b);
}
}