package jetbrains.mps.ide.java.platform.highlighters.methodcallsfixer; /*Generated by MPS */ import jetbrains.mps.nodeEditor.checking.BaseEditorChecker; import org.jetbrains.mps.openapi.module.SRepository; import java.util.List; import jetbrains.mps.smodel.event.SModelEvent; import jetbrains.mps.internal.collections.runtime.ListSequence; import jetbrains.mps.smodel.event.SModelReplacedEvent; import jetbrains.mps.nodeEditor.EditorComponent; import org.jetbrains.annotations.NotNull; import jetbrains.mps.nodeEditor.checking.UpdateResult; import jetbrains.mps.util.Cancellable; import org.jetbrains.mps.openapi.model.SNode; import jetbrains.mps.typesystem.inference.TypeContextManager; import jetbrains.mps.typesystem.inference.ITypechecking; import jetbrains.mps.typesystem.inference.TypeCheckingContext; import java.util.Collections; import jetbrains.mps.nodeEditor.EditorMessage; import org.jetbrains.mps.openapi.model.SModel; import jetbrains.mps.lang.smodel.generator.smodelAdapter.SNodeOperations; import org.jetbrains.mps.openapi.model.EditableSModel; import jetbrains.mps.extapi.module.TransientSModule; import jetbrains.mps.smodel.adapter.structure.MetaAdapterFactory; import org.jetbrains.mps.openapi.language.SAbstractConcept; import java.util.Map; import jetbrains.mps.ide.ThreadUtils; import org.jetbrains.mps.openapi.model.SNodeUtil; import jetbrains.mps.lang.smodel.generator.smodelAdapter.SLinkOperations; public class MethodCallsFixer extends BaseEditorChecker { private static boolean DISABLED = false; private final SRepository myRepository; private MethodCallsUpdateSession myCurrentSession; public MethodCallsFixer(SRepository repository) { myRepository = repository; } @Override public void processEvents(final List<SModelEvent> events) { if (myCurrentSession == null) { return; } final UpdateSessionEventVisitor visitor = new UpdateSessionEventVisitor(myCurrentSession); // Start a read action here since MethodDeclarationFixer used to process events in a read action. // Ideally we should not need read action and we should avoid walking through the model since we receive events // asynchronously and with a delay, so the model may be in an unexpected state. myRepository.getModelAccess().runReadAction(new Runnable() { public void run() { for (SModelEvent event : ListSequence.fromList(events)) { if (event instanceof SModelReplacedEvent) { myCurrentSession = null; break; } event.accept(visitor); } } }); } @Override public boolean needsUpdate(EditorComponent component) { return myCurrentSession == null || myCurrentSession.hasMethodCallsToUpdate(); } @NotNull @Override public UpdateResult update(EditorComponent editorComponent, final boolean incremental, boolean applyQuickFixes, Cancellable cancellable) { try { final SRepository repository = editorComponent.getEditorContext().getRepository(); final SNode editedNode = editorComponent.getEditedNode(); if (editedNode == null) { return UpdateResult.CANCELLED; } TypeContextManager.getInstance().runTypeCheckingAction(editorComponent.getTypecheckingContextOwner(), editedNode, new ITypechecking.Action() { @Override public void run(TypeCheckingContext context) { doCreateMessages(editedNode, incremental, repository); } }); return new UpdateResult.Completed(true, Collections.<EditorMessage>emptySet()); } catch (RuntimeException e) { myCurrentSession = null; throw e; } } private void doCreateMessages(SNode rootNode, boolean incremental, final SRepository repository) { if (DISABLED) { return; } SModel model = SNodeOperations.getModel(rootNode); if (!(model instanceof EditableSModel) || model.getModule() instanceof TransientSModule || jetbrains.mps.util.SNodeOperations.isModelDisposed(model)) { return; } if (!(incremental)) { myCurrentSession = null; } if (myCurrentSession == null) { myCurrentSession = new MethodCallsUpdateSession(myRepository); incremental = false; } if (!(incremental)) { for (SNode methodCall : SNodeOperations.getNodeDescendants(rootNode, MetaAdapterFactory.getInterfaceConcept(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x11857355952L, "jetbrains.mps.baseLanguage.structure.IMethodCall"), false, new SAbstractConcept[]{})) { myCurrentSession.checkMethodCall(methodCall); } } final Map<SNode, SNode> methodCallsToUpdate = myCurrentSession.collectMethodCallsToUpdate(); if (!(methodCallsToUpdate.isEmpty()) && repository != null) { ThreadUtils.runInUIThreadNoWait(new Runnable() { public void run() { repository.getModelAccess().executeUndoTransparentCommand(new Runnable() { public void run() { for (SNode methodCall : methodCallsToUpdate.keySet()) { SNode referent = methodCallsToUpdate.get(methodCall); if (referent != null && SNodeUtil.isAccessible(referent, repository)) { SLinkOperations.setTarget(methodCall, MetaAdapterFactory.getReferenceLink(0xf3061a5392264cc5L, 0xa443f952ceaf5816L, 0x11857355952L, 0xf8c78301adL, "baseMethodDeclaration"), referent); } } } }); } }); } } }