package jetbrains.mps.debugger.java.runtime.evaluation.model;
/*Generated by MPS */
import jetbrains.mps.debugger.java.runtime.evaluation.container.EvaluationContainer;
import org.apache.log4j.Logger;
import org.apache.log4j.LogManager;
import jetbrains.mps.project.Project;
import jetbrains.mps.debugger.java.runtime.state.DebugSession;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.mps.openapi.module.SModuleReference;
import java.util.List;
import org.jetbrains.mps.openapi.model.SNodeReference;
import jetbrains.mps.baseLanguage.closures.runtime._FunctionTypes;
import jetbrains.mps.debugger.java.runtime.evaluation.container.IEvaluationContainer;
import jetbrains.mps.debugger.java.runtime.evaluation.container.EvaluationModule;
import org.jetbrains.mps.openapi.model.SModel;
import org.jetbrains.mps.openapi.model.SNode;
import jetbrains.mps.smodel.ModelDependencyUpdate;
import jetbrains.mps.internal.collections.runtime.ListSequence;
import jetbrains.mps.internal.collections.runtime.IVisitor;
import jetbrains.mps.smodel.ModelImports;
import jetbrains.mps.smodel.adapter.structure.MetaAdapterFactory;
import org.jetbrains.mps.openapi.persistence.PersistenceFacade;
import jetbrains.mps.debugger.java.runtime.evaluation.container.BaseLanguagesImportHelper;
import jetbrains.mps.smodel.behaviour.BHReflection;
import jetbrains.mps.core.aspects.behaviour.SMethodTrimmedId;
import jetbrains.mps.smodel.action.SNodeFactoryOperations;
import jetbrains.mps.lang.smodel.generator.smodelAdapter.SPropertyOperations;
import jetbrains.mps.lang.smodel.generator.smodelAdapter.SNodeOperations;
import java.util.Map;
import jetbrains.mps.internal.collections.runtime.MapSequence;
import java.util.LinkedHashMap;
import jetbrains.mps.lang.smodel.generator.smodelAdapter.SLinkOperations;
import java.util.Set;
import jetbrains.mps.internal.collections.runtime.SetSequence;
import java.util.HashSet;
import jetbrains.mps.lang.smodel.generator.smodelAdapter.SConceptOperations;
import jetbrains.mps.internal.collections.runtime.Sequence;
import com.sun.jdi.InvalidStackFrameException;
import org.apache.log4j.Level;
import org.jetbrains.annotations.Nullable;
import jetbrains.mps.lang.smodel.generator.smodelAdapter.SModelOperations;
import jetbrains.mps.internal.collections.runtime.IWhereFilter;
import org.jetbrains.mps.openapi.module.FindUsagesFacade;
import org.jetbrains.mps.openapi.language.SAbstractConcept;
import jetbrains.mps.ide.findusages.model.scopes.ModelsScope;
import java.util.Collections;
import jetbrains.mps.progress.EmptyProgressMonitor;
import jetbrains.mps.smodel.ModuleRepositoryFacade;
import org.jetbrains.mps.openapi.model.SModelName;
import jetbrains.mps.smodel.SModelStereotype;
import java.util.ArrayList;
import jetbrains.mps.smodel.CopyUtil;
import com.intellij.openapi.extensions.PluginId;
import com.intellij.ide.plugins.PluginManager;
import jetbrains.mps.debug.api.Debuggers;
import jetbrains.mps.debugger.java.runtime.JavaDebugger;
import java.io.File;
import com.intellij.ide.plugins.IdeaPluginDescriptorImpl;
import jetbrains.mps.internal.collections.runtime.ISelector;
import org.jetbrains.mps.openapi.model.SReference;
import jetbrains.mps.smodel.SNodePointer;
public class EvaluationWithContextContainer extends EvaluationContainer {
private static final Logger LOG = LogManager.getLogger(EvaluationWithContextContainer.class);
private final boolean myIsInWatch;
private boolean myVariablesInitialized = false;
protected final EvaluationContext myEvaluationContext;
public EvaluationWithContextContainer(Project project, DebugSession session, @NotNull SModuleReference containerModule, List<SNodeReference> nodesToImport, boolean isInWatch, _FunctionTypes._void_P1_E0<? super IEvaluationContainer> onNodeSetUp) {
super(project, session, containerModule, nodesToImport, onNodeSetUp);
myIsInWatch = isInWatch;
myEvaluationContext = new StackFrameContext(session.getUiState());
}
@Override
protected void setUpNode(List<SNodeReference> nodesToImport) {
EvaluationModule containerModule = (EvaluationModule) myContainerModule.resolve(myDebuggerRepository);
SModel containerModel = myContainerModel.resolve(myDebuggerRepository);
setUpDependencies(containerModule, containerModel);
final SNode evaluatorNode = createEvaluatorNode();
containerModel.addRootNode(evaluatorNode);
myNode = evaluatorNode.getReference();
createVars();
tryToImport(evaluatorNode, nodesToImport);
// XXX updateImportedModels() likely could live with null here, accessory models may be imported directly
new ModelDependencyUpdate(containerModel).updateUsedLanguages().updateImportedModels(myDebuggerRepository).updateModuleDependencies(myDebuggerRepository);
}
private void setUpDependencies(final EvaluationModule containerModule, SModel containerModel) {
ListSequence.fromList(myEvaluationContext.getClassPath()).union(ListSequence.fromList(getDebuggerStubPath())).visitAll(new IVisitor<String>() {
public void visit(String it) {
containerModule.addClassPathItem(it);
}
});
containerModule.updateModelsSet();
ModelImports modelImports = new ModelImports(containerModel);
modelImports.addUsedLanguage(MetaAdapterFactory.getLanguage(0x7da4580f9d754603L, 0x816251a896d78375L, "jetbrains.mps.debugger.java.evaluation"));
modelImports.addUsedLanguage(MetaAdapterFactory.getLanguage(0x802088974572437dL, 0xb50e8f050cba9566L, "jetbrains.mps.debugger.java.privateMembers"));
containerModule.addDependency(PersistenceFacade.getInstance().createModuleReference("6354ebe7-c22a-4a0f-ac54-50b52ab9b065(JDK)"), false);
}
private void tryToImport(final SNode evaluatorNode, List<SNodeReference> nodesToImport) {
BaseLanguagesImportHelper helper = new EvaluationWithContextContainer.MyBaseLanguagesImportHelper(evaluatorNode);
helper.tryToImport(((SNode) BHReflection.invoke(evaluatorNode, SMethodTrimmedId.create("getCode", null, "hASWOEj0jB"))), nodesToImport);
}
@Override
protected SNode createEvaluatorNode() {
SNode evaluatorConcept = SNodeFactoryOperations.createNewNode(SNodeFactoryOperations.asInstanceConcept(MetaAdapterFactory.getConcept(0x7da4580f9d754603L, 0x816251a896d78375L, 0x53c5060c6b18d925L, "jetbrains.mps.debugger.java.evaluation.structure.EvaluatorConcept")), null);
SPropertyOperations.set(evaluatorConcept, MetaAdapterFactory.getProperty(0x7da4580f9d754603L, 0x816251a896d78375L, 0x53c5060c6b18d925L, 0x53c5060c6b19c79bL, "isShowContext"), "" + (myIsInWatch));
return evaluatorConcept;
}
private void createVars() {
// 2 uses. setUpNode() is invoked within command; updateState runs new command itself
fillVariables(SNodeOperations.cast(getNode(), MetaAdapterFactory.getConcept(0x7da4580f9d754603L, 0x816251a896d78375L, 0x53c5060c6b18d925L, "jetbrains.mps.debugger.java.evaluation.structure.EvaluatorConcept")));
}
private void fillVariables(SNode evaluatorConcept) {
try {
_FunctionTypes._return_P1_E0<? extends SNode, ? super String> createClassifierType = new _FunctionTypes._return_P1_E0<SNode, String>() {
public SNode invoke(String name) {
return createClassifierType(name);
}
};
Map<String, VariableDescription> contextVariables = myEvaluationContext.getVariables(createClassifierType);
Map<String, SNode> declaredVariables = MapSequence.fromMap(new LinkedHashMap<String, SNode>(16, (float) 0.75, false));
for (SNode var : ListSequence.fromList(SLinkOperations.getChildren(evaluatorConcept, MetaAdapterFactory.getContainmentLink(0x7da4580f9d754603L, 0x816251a896d78375L, 0x53c5060c6b18d925L, 0x53c5060c6b19c797L, "variables")))) {
MapSequence.fromMap(declaredVariables).put(SPropertyOperations.getString(var, MetaAdapterFactory.getProperty(0x7da4580f9d754603L, 0x816251a896d78375L, 0x53c5060c6b18d926L, 0x4db8c07036eb94eeL, "lowLevelName")), var);
}
final Set<SNode> foundVars = SetSequence.fromSet(new HashSet<SNode>());
for (String variable : MapSequence.fromMap(contextVariables).keySet()) {
String name = variable;
SNode lowLevelVarNode = MapSequence.fromMap(declaredVariables).get(name);
if (needUpdateVariables()) {
// we should update variables if we are first time here or if we do not show context (i.e. in evaluation)
if (lowLevelVarNode == null) {
lowLevelVarNode = SConceptOperations.createNewNode(MetaAdapterFactory.getConcept(0x7da4580f9d754603L, 0x816251a896d78375L, 0x53c5060c6b18d926L, "jetbrains.mps.debugger.java.evaluation.structure.LowLevelVariable"));
ListSequence.fromList(SLinkOperations.getChildren(evaluatorConcept, MetaAdapterFactory.getContainmentLink(0x7da4580f9d754603L, 0x816251a896d78375L, 0x53c5060c6b18d925L, 0x53c5060c6b19c797L, "variables"))).addElement(lowLevelVarNode);
MapSequence.fromMap(declaredVariables).put(name, lowLevelVarNode);
}
MapSequence.fromMap(contextVariables).get(variable).updateLowLevelVariable(lowLevelVarNode);
}
SetSequence.fromSet(foundVars).addElement(lowLevelVarNode);
}
// now mark vars which are currently out of scope
Sequence.fromIterable(MapSequence.fromMap(declaredVariables).values()).visitAll(new IVisitor<SNode>() {
public void visit(SNode it) {
SPropertyOperations.set(it, MetaAdapterFactory.getProperty(0x7da4580f9d754603L, 0x816251a896d78375L, 0x53c5060c6b18d926L, 0x554b4e03d5950431L, "isOutOfScope"), "" + (!(SetSequence.fromSet(foundVars).contains(it))));
}
});
if (needUpdateVariables()) {
// create static context type
SLinkOperations.setTarget(evaluatorConcept, MetaAdapterFactory.getContainmentLink(0x7da4580f9d754603L, 0x816251a896d78375L, 0x53c5060c6b18d925L, 0x3f11b1341fa23615L, "contextNode"), myEvaluationContext.getStaticContextType(createClassifierType));
// create this
SLinkOperations.setTarget(evaluatorConcept, MetaAdapterFactory.getContainmentLink(0x7da4580f9d754603L, 0x816251a896d78375L, 0x53c5060c6b18d925L, 0x3f11b1341fa23613L, "thisNode"), myEvaluationContext.getThisClassifierType(createClassifierType));
}
// todo highlight when this type or static context type are invalid
} catch (InvalidStackFrameException e) {
if (LOG.isEnabledFor(Level.WARN)) {
LOG.warn("InvalidStackFrameException", e);
}
}
myVariablesInitialized = true;
}
@Override
public void updateState() {
super.updateState();
if (myDebugSession.getEvaluationProvider().canEvaluate()) {
// createVars used to execute command (runWriteActionInCommand), hence I assume (a) we've got proper thread here
// (b) there's need to run inside a command. Although it looks undoTransparent (the one that doesn't record any changes)
// is suited much better here.
myDebuggerRepository.getModelAccess().executeCommand(new Runnable() {
public void run() {
createVars();
}
});
}
}
@Nullable
private SNode createClassifierType(final String unitFqName) {
SNode unit = findUnit(unitFqName);
if (unit == null) {
return null;
}
SNode classifierType = SConceptOperations.createNewNode(MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x101de48bf9eL, "jetbrains.mps.baseLanguage.structure.ClassifierType"));
SLinkOperations.setTarget(classifierType, MetaAdapterFactory.getReferenceLink(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x101de48bf9eL, 0x101de490babL, "classifier"), SNodeOperations.cast(unit, MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x101d9d3ca30L, "jetbrains.mps.baseLanguage.structure.Classifier")));
return classifierType;
}
public SNode findUnit(final String unitName) {
// I hate the next piece of code
// (and this class in general, since it inherited a lot of the ugly stuff from the old evaluation code)
SModel stub = findStubForFqName(modelFqNameFromUnitName(unitName));
if (stub != null) {
SModel model = stub;
SNode node = ListSequence.fromList(SModelOperations.nodes(model, MetaAdapterFactory.getInterfaceConcept(0x9ded098bad6a4657L, 0xbfd948636cfe8bc3L, 0x465516cf87c705a4L, "jetbrains.mps.lang.traceable.structure.UnitConcept"))).findFirst(new IWhereFilter<SNode>() {
public boolean accept(SNode it) {
return eq_v5yv3u_a0a0a0a0a0a0b0d0p(((String) BHReflection.invoke(it, SMethodTrimmedId.create("getUnitName", null, "4pl5GY7LKmR"))), unitName) && SNodeOperations.isInstanceOf(it, MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x101d9d3ca30L, "jetbrains.mps.baseLanguage.structure.Classifier"));
}
});
if (node != null) {
return node;
}
}
FindUsagesFacade findUsages = FindUsagesFacade.getInstance();
SAbstractConcept concept = MetaAdapterFactory.getInterfaceConcept(0x9ded098bad6a4657L, 0xbfd948636cfe8bc3L, 0x465516cf87c705a4L, "jetbrains.mps.lang.traceable.structure.UnitConcept");
Set<SNode> instances = findUsages.findInstances(new ModelsScope(getCandidateNonStubModels(unitName)), Collections.singleton(concept), false, new EmptyProgressMonitor());
return SNodeOperations.cast(SetSequence.fromSet(instances).findFirst(new IWhereFilter<SNode>() {
public boolean accept(SNode it) {
return SNodeOperations.isInstanceOf(((SNode) it), MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x101d9d3ca30L, "jetbrains.mps.baseLanguage.structure.Classifier")) && ((String) BHReflection.invoke(SNodeOperations.cast(it, MetaAdapterFactory.getInterfaceConcept(0x9ded098bad6a4657L, 0xbfd948636cfe8bc3L, 0x465516cf87c705a4L, "jetbrains.mps.lang.traceable.structure.UnitConcept")), SMethodTrimmedId.create("getUnitName", null, "4pl5GY7LKmR"))).equals(unitName);
}
}), MetaAdapterFactory.getInterfaceConcept(0x9ded098bad6a4657L, 0xbfd948636cfe8bc3L, 0x465516cf87c705a4L, "jetbrains.mps.lang.traceable.structure.UnitConcept"));
}
@Nullable
private SModel findStubForFqName(String fqName) {
return new ModuleRepositoryFacade(myDebuggerRepository).getModelByName(new SModelName(fqName, SModelStereotype.JAVA_STUB).getValue());
}
private boolean needUpdateVariables() {
return !(myVariablesInitialized) || !(myIsInWatch);
}
@Override
public EvaluationWithContextContainer copy(final boolean isInWatch, _FunctionTypes._void_P1_E0<? super IEvaluationContainer> onNodeSetUp) {
final SNodeReference reference = myNode;
return new EvaluationWithContextContainer(myProject, myDebugSession, myContainerModule, ListSequence.fromList(new ArrayList<SNodeReference>()), isInWatch, onNodeSetUp) {
@Override
protected SNode createEvaluatorNode() {
SNode newEvaluator = (SNode) CopyUtil.copyAndPreserveId(reference.resolve(myDebuggerRepository), true);
SPropertyOperations.set(newEvaluator, MetaAdapterFactory.getProperty(0x7da4580f9d754603L, 0x816251a896d78375L, 0x53c5060c6b18d925L, 0x53c5060c6b19c79bL, "isShowContext"), "" + (isInWatch));
return newEvaluator;
}
};
}
public static List<String> getDebuggerStubPath() {
PluginId apiPlugin = PluginManager.getPluginByClassName(Debuggers.class.getName());
PluginId javaPlugin = PluginManager.getPluginByClassName(JavaDebugger.class.getName());
List<File> paths = ListSequence.fromList(new ArrayList<File>());
ListSequence.fromList(paths).addSequence(ListSequence.fromList(((IdeaPluginDescriptorImpl) PluginManager.getPlugin(apiPlugin)).getClassPath()));
ListSequence.fromList(paths).addSequence(ListSequence.fromList(((IdeaPluginDescriptorImpl) PluginManager.getPlugin(javaPlugin)).getClassPath()));
return ListSequence.fromList(paths).select(new ISelector<File, String>() {
public String select(File it) {
return (String) it.getAbsolutePath();
}
}).toListSequence();
}
/*package*/ Iterable<SModel> getCandidateNonStubModels(String unitName) {
final String modelFqName = modelFqNameFromUnitName(unitName);
final ModuleRepositoryFacade mrf = new ModuleRepositoryFacade(myDebuggerRepository);
return Sequence.fromIterable(Sequence.fromArray(SModelStereotype.values)).select(new ISelector<CharSequence, SModel>() {
public SModel select(CharSequence stereotype) {
return mrf.getModelByName(new SModelName(modelFqName, stereotype).getValue());
}
}).where(new IWhereFilter<SModel>() {
public boolean accept(SModel it) {
return it != null;
}
});
}
public static String modelFqNameFromUnitName(String unitName) {
int lastDot = unitName.lastIndexOf('.');
return ((lastDot == -1 ? "" : unitName.substring(0, lastDot)));
}
private class MyBaseLanguagesImportHelper extends BaseLanguagesImportHelper {
private final SNode myEvaluatorNode;
public MyBaseLanguagesImportHelper(SNode evaluatorNode) {
myEvaluatorNode = evaluatorNode;
}
@Override
public SNode findVariable(final SReference variableReference) {
SNode matchingVar = ListSequence.fromList(SLinkOperations.getChildren(myEvaluatorNode, MetaAdapterFactory.getContainmentLink(0x7da4580f9d754603L, 0x816251a896d78375L, 0x53c5060c6b18d925L, 0x53c5060c6b19c797L, "variables"))).findFirst(new IWhereFilter<SNode>() {
public boolean accept(SNode variable) {
return eq_v5yv3u_a0a0a0a0a0a0a2w(SNodePointer.deserialize(SPropertyOperations.getString(variable, MetaAdapterFactory.getProperty(0x7da4580f9d754603L, 0x816251a896d78375L, 0x53c5060c6b18d926L, 0x6db8b4aef007e84fL, "highLevelNodeId"))), SLinkOperations.getTargetNode(variableReference).getReference());
}
});
if (matchingVar == null) {
matchingVar = ListSequence.fromList(SLinkOperations.getChildren(myEvaluatorNode, MetaAdapterFactory.getContainmentLink(0x7da4580f9d754603L, 0x816251a896d78375L, 0x53c5060c6b18d925L, 0x53c5060c6b19c797L, "variables"))).findFirst(new IWhereFilter<SNode>() {
public boolean accept(SNode variable) {
return eq_v5yv3u_a0a0a0a0a0a0a1a2w(SPropertyOperations.getString(variable, MetaAdapterFactory.getProperty(0xceab519525ea4f22L, 0x9b92103b95ca8c0cL, 0x110396eaaa4L, 0x110396ec041L, "name")), SPropertyOperations.getString(SNodeOperations.cast(SLinkOperations.getTargetNode(variableReference), MetaAdapterFactory.getInterfaceConcept(0xceab519525ea4f22L, 0x9b92103b95ca8c0cL, 0x110396eaaa4L, "jetbrains.mps.lang.core.structure.INamedConcept")), MetaAdapterFactory.getProperty(0xceab519525ea4f22L, 0x9b92103b95ca8c0cL, 0x110396eaaa4L, 0x110396ec041L, "name")));
}
});
}
return matchingVar;
}
@Override
public SNode createVariableReference(SNode variable) {
SNode newVariableReference = SConceptOperations.createNewNode(MetaAdapterFactory.getConcept(0x7da4580f9d754603L, 0x816251a896d78375L, 0x7d9a547f857a394bL, "jetbrains.mps.debugger.java.evaluation.structure.LowLevelVariableReference"));
SLinkOperations.setTarget(newVariableReference, MetaAdapterFactory.getReferenceLink(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x4c4b92003e49a704L, 0x4c4b92003e49a705L, "baseVariableDeclaration"), variable);
return newVariableReference;
}
}
private static boolean eq_v5yv3u_a0a0a0a0a0a0b0d0p(Object a, Object b) {
return (a != null ? a.equals(b) : a == b);
}
private static boolean eq_v5yv3u_a0a0a0a0a0a0a2w(Object a, Object b) {
return (a != null ? a.equals(b) : a == b);
}
private static boolean eq_v5yv3u_a0a0a0a0a0a0a1a2w(Object a, Object b) {
return (a != null ? a.equals(b) : a == b);
}
}