package jetbrains.mps.ide.java.platform.highlighters.methodcallsfixer;
/*Generated by MPS */
import java.util.Map;
import org.jetbrains.mps.openapi.model.SNode;
import java.util.HashMap;
import org.jetbrains.mps.openapi.module.SRepository;
import org.jetbrains.annotations.NotNull;
import jetbrains.mps.lang.smodel.generator.smodelAdapter.SLinkOperations;
import jetbrains.mps.smodel.adapter.structure.MetaAdapterFactory;
import jetbrains.mps.baseLanguage.tuples.runtime.Tuples;
import jetbrains.mps.baseLanguage.search.MethodResolveUtil;
import jetbrains.mps.internal.collections.runtime.Sequence;
import jetbrains.mps.lang.smodel.generator.smodelAdapter.SNodeOperations;
import org.jetbrains.mps.openapi.language.SAbstractConcept;
import org.jetbrains.mps.openapi.model.SModel;
import jetbrains.mps.smodel.SNodePointer;
import jetbrains.mps.lang.smodel.generator.smodelAdapter.SPropertyOperations;
/**
* Maintains information for incremental updates.
*/
/*package*/ class MethodCallsUpdateSession {
private Map<SNode, SNode> myMethodCallsToUpdate = new HashMap<SNode, SNode>();
private final MethodCallsCache myCache;
/*package*/ MethodCallsUpdateSession(SRepository repository) {
myCache = new MethodCallsCache(repository);
}
/*package*/ void checkMethodCall(@NotNull SNode methodCallNode) {
SNode baseMethodDeclaration = SLinkOperations.getTarget(methodCallNode, MetaAdapterFactory.getReferenceLink(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x11857355952L, 0xf8c78301adL, "baseMethodDeclaration"));
String methodName = getMethodName(methodCallNode);
Tuples._2<SNode, Boolean> resolveResult = MethodResolveUtil.resolveMethod(methodCallNode, methodName);
SNode newTarget = resolveResult._0();
boolean good = (boolean) resolveResult._1();
if (newTarget != null) {
if (baseMethodDeclaration == null || (good && newTarget != baseMethodDeclaration)) {
myMethodCallsToUpdate.put(methodCallNode, newTarget);
}
myCache.putCheckedMethodCall(methodCallNode, newTarget, methodName);
}
}
/*package*/ void methodDeclarationSignatureChanged(SNode method) {
for (SNode methodCall : Sequence.fromIterable(myCache.getCheckedCallsToMethodByConceptAndName(method))) {
checkMethodCall(methodCall);
}
}
/*package*/ void methodCallChanged(SNode methodCall) {
if (myCache.isMethodCallUpToDate(methodCall)) {
return;
}
checkMethodCall(methodCall);
}
/*package*/ void nodeAdded(SNode child) {
for (SNode methodCall : SNodeOperations.getNodeDescendants(child, MetaAdapterFactory.getInterfaceConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x11857355952L, "jetbrains.mps.baseLanguage.structure.IMethodCall"), true, new SAbstractConcept[]{})) {
checkMethodCall(methodCall);
}
SNode parent = SNodeOperations.getParent(child);
if (myCache.wasChecked(parent)) {
SNode p = SNodeOperations.cast(parent, MetaAdapterFactory.getInterfaceConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x11857355952L, "jetbrains.mps.baseLanguage.structure.IMethodCall"));
checkMethodCall(p);
}
SNode formalParam = SNodeOperations.getNodeAncestor(child, MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xf8c77f1e94L, "jetbrains.mps.baseLanguage.structure.ParameterDeclaration"), true, false);
if ((SNodeOperations.getParent(formalParam) != null)) {
methodDeclarationSignatureChanged(SNodeOperations.getParent(formalParam));
}
}
/*package*/ void nodeRemoved(SNode child, SNode formerParent, SModel m) {
if (myCache.wasChecked(new SNodePointer(m.getReference(), formerParent.getNodeId()))) {
SNode methodCallNode = SNodeOperations.cast(formerParent, MetaAdapterFactory.getInterfaceConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x11857355952L, "jetbrains.mps.baseLanguage.structure.IMethodCall"));
checkMethodCall(methodCallNode);
}
if (SNodeOperations.isInstanceOf(child, MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xf8c77f1e94L, "jetbrains.mps.baseLanguage.structure.ParameterDeclaration"))) {
methodDeclarationSignatureChanged(formerParent);
} else {
SNode formalParam = SNodeOperations.getNodeAncestor(formerParent, MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0xf8c77f1e94L, "jetbrains.mps.baseLanguage.structure.ParameterDeclaration"), true, false);
if ((SNodeOperations.getParent(formalParam) != null)) {
methodDeclarationSignatureChanged(SNodeOperations.getParent(formalParam));
}
}
}
/*package*/ void methodDeclarationNameChanged(SNode method) {
Iterable<SNode> methodCalls = myCache.getCheckedCallsToMethodByNodeReference(method);
for (SNode methodCall : Sequence.fromIterable(methodCalls)) {
SNode methodCallNode = methodCall;
checkMethodCall(methodCallNode);
}
}
/*package*/ String getMethodName(SNode methodCall) {
SNode baseMethodDeclaration = SLinkOperations.getTarget(methodCall, MetaAdapterFactory.getReferenceLink(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x11857355952L, 0xf8c78301adL, "baseMethodDeclaration"));
if (baseMethodDeclaration == null) {
if (SLinkOperations.getTarget(SNodeOperations.as(methodCall, MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x1107e0cb103L, "jetbrains.mps.baseLanguage.structure.AnonymousClass")), MetaAdapterFactory.getReferenceLink(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x1107e0cb103L, 0x1107e0fd2a0L, "classifier")) != null) {
return SPropertyOperations.getString(SLinkOperations.getTarget(SNodeOperations.as(methodCall, MetaAdapterFactory.getConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x1107e0cb103L, "jetbrains.mps.baseLanguage.structure.AnonymousClass")), MetaAdapterFactory.getReferenceLink(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x1107e0cb103L, 0x1107e0fd2a0L, "classifier")), MetaAdapterFactory.getProperty(0xceab519525ea4f22L, 0x9b92103b95ca8c0cL, 0x110396eaaa4L, 0x110396ec041L, "name"));
} else {
return SLinkOperations.getResolveInfo(SNodeOperations.getReference(methodCall, MetaAdapterFactory.getReferenceLink(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x11857355952L, 0xf8c78301adL, "baseMethodDeclaration")));
}
} else {
return SPropertyOperations.getString(baseMethodDeclaration, MetaAdapterFactory.getProperty(0xceab519525ea4f22L, 0x9b92103b95ca8c0cL, 0x110396eaaa4L, 0x110396ec041L, "name"));
}
}
/**
* Returns a copy of the internally maintained collection of method calls that should be updated to new targets, and
* clears the original collection.
*
* @return a non-null map from IMethodCall to BaseMethodDeclaration
*/
@NotNull
/*package*/ Map<SNode, SNode> collectMethodCallsToUpdate() {
Map<SNode, SNode> result = myMethodCallsToUpdate;
myMethodCallsToUpdate = new HashMap<SNode, SNode>();
return result;
}
/*package*/ boolean hasMethodCallsToUpdate() {
return !(myMethodCallsToUpdate.isEmpty());
}
public void doneUpdating() {
myMethodCallsToUpdate.clear();
}
}