package jetbrains.mps.ide.platform.actions.core;
/*Generated by MPS */
import org.apache.log4j.Logger;
import org.apache.log4j.LogManager;
import jetbrains.mps.baseLanguage.tuples.runtime.Tuples;
import java.util.List;
import jetbrains.mps.refactoring.participant.RefactoringParticipant;
import jetbrains.mps.ide.findusages.model.SearchTask;
import jetbrains.mps.refactoring.participant.RefactoringUI;
import org.jetbrains.mps.openapi.module.SRepository;
import org.jetbrains.mps.openapi.module.SearchScope;
import jetbrains.mps.internal.collections.runtime.ListSequence;
import java.util.ArrayList;
import jetbrains.mps.baseLanguage.closures.runtime.Wrappers;
import jetbrains.mps.internal.collections.runtime.Sequence;
import jetbrains.mps.internal.collections.runtime.ITranslator2;
import jetbrains.mps.internal.collections.runtime.ISelector;
import jetbrains.mps.ide.findusages.model.SearchResults;
import org.jetbrains.mps.openapi.module.ModelAccess;
import org.jetbrains.mps.openapi.util.ProgressMonitor;
import org.jetbrains.mps.openapi.util.SubProgressKind;
import org.apache.log4j.Level;
import jetbrains.mps.baseLanguage.tuples.runtime.MultiTuple;
import jetbrains.mps.project.MPSProject;
import jetbrains.mps.baseLanguage.closures.runtime._FunctionTypes;
import java.util.Map;
import jetbrains.mps.refactoring.participant.RefactoringSession;
import jetbrains.mps.project.Project;
import jetbrains.mps.util.annotation.ToRemove;
import org.jetbrains.annotations.Nullable;
import jetbrains.mps.refactoring.participant.RefactoringSessionImpl;
import jetbrains.mps.internal.collections.runtime.MapSequence;
public class RefactoringProcessor {
private static final Logger LOG = LogManager.getLogger(RefactoringProcessor.class);
public static <IP, FP, IS, FS> Tuples._2<List<RefactoringParticipant.ParticipantApplied<?, ?, IP, FP, IS, FS>>, SearchTask> askParticipantChanges(final RefactoringParticipant.ParticipantStateFactory<IP, FP, IS, FS> factory, RefactoringUI refactoringUI, final SRepository repository, final SearchScope searchScope, final Iterable<? extends RefactoringParticipant<?, ?, IP, FP>> participants, final List<IS> nodes) {
final List<RefactoringParticipant.ParticipantApplied<?, ?, IP, FP, IS, FS>> participantStates = ListSequence.fromList(new ArrayList<RefactoringParticipant.ParticipantApplied<?, ?, IP, FP, IS, FS>>());
final Wrappers._T<List<RefactoringParticipant.Option>> options = new Wrappers._T<List<RefactoringParticipant.Option>>();
refactoringUI.prepare(new Runnable() {
public void run() {
for (RefactoringParticipant<?, ?, IP, FP> participant : Sequence.fromIterable(participants)) {
ListSequence.fromList(participantStates).addElement(RefactoringParticipant.ParticipantApplied.create(factory, participant, nodes));
}
options.value = ListSequence.fromList(participantStates).translate(new ITranslator2<RefactoringParticipant.ParticipantApplied<?, ?, IP, FP, IS, FS>, RefactoringParticipant.Option>() {
public Iterable<RefactoringParticipant.Option> translate(RefactoringParticipant.ParticipantApplied<?, ?, IP, FP, IS, FS> it) {
return it.getAvaliableOptions(repository);
}
}).distinct().sort(new ISelector<RefactoringParticipant.Option, String>() {
public String select(RefactoringParticipant.Option it) {
return it.getDescription();
}
}, true).toListSequence();
}
});
final List<RefactoringParticipant.Option> selectedOptions = refactoringUI.selectParticipants(options.value);
if (selectedOptions == null) {
return null;
}
SearchTask searchTask = new SearchTask() {
public boolean canExecute() {
return true;
}
public SearchResults execute(ModelAccess modelAccess, final ProgressMonitor progressMonitor) {
final Wrappers._boolean cancelled = new Wrappers._boolean(false);
modelAccess.runReadAction(new Runnable() {
public void run() {
int steps = ListSequence.fromList(participantStates).count();
progressMonitor.start("Searching for usages", steps);
for (RefactoringParticipant.ParticipantApplied<?, ?, IP, FP, IS, FS> participantState : ListSequence.fromList(participantStates)) {
try {
participantState.findChanges(repository, selectedOptions, searchScope, progressMonitor.subTask(1, SubProgressKind.AS_COMMENT));
} catch (RuntimeException e) {
if (LOG.isEnabledFor(Level.ERROR)) {
LOG.error("Exception during usages search", e);
}
cancelled.value = true;
break;
}
if (progressMonitor.isCanceled()) {
cancelled.value = true;
break;
}
}
progressMonitor.done();
}
});
if (cancelled.value) {
return null;
}
SearchResults searchResults = new SearchResults();
for (RefactoringParticipant.ParticipantApplied<?, ?, IP, FP, IS, FS> participantState : ListSequence.fromList(participantStates)) {
List<? extends List<? extends RefactoringParticipant.Change<?, ?>>> participantChanges = participantState.getChanges();
for (List<? extends RefactoringParticipant.Change<?, ?>> nodeChanges : ListSequence.fromList(participantChanges)) {
for (RefactoringParticipant.Change<?, ?> change : ListSequence.fromList(nodeChanges)) {
searchResults.addAll(change.getSearchResults());
}
}
}
return searchResults;
}
};
return MultiTuple.<List<RefactoringParticipant.ParticipantApplied<?, ?, IP, FP, IS, FS>>,SearchTask>from(participantStates, searchTask);
}
public static <IP, FP> void performRefactoringUserInteractive(MPSProject project, String refactoringName, Iterable<? extends RefactoringParticipant<?, ?, IP, FP>> participants, final List<IP> initialStates, final _FunctionTypes._return_P2_E0<? extends Map<IP, FP>, ? super Iterable<RefactoringParticipant.ParticipantApplied<?, ?, IP, FP, IP, FP>>, ? super RefactoringSession> doRefactor) {
performRefactoringInProject(project, new DefaultRefactoringUI(project), refactoringName, participants, initialStates, doRefactor, null);
}
/**
*
* @see jetbrains.mps.ide.platform.actions.core.RefactoringProcessor#performRefactoringInProject(Project, RefactoringUI, String, Iterable<? extends RefactoringParticipant<?, ?, IP, FP>>, List<IP>, _FunctionTypes._return_P2_E0<? extends Map<IP, FP>, ? super Iterable<RefactoringParticipant.ParticipantApplied<?, ?, IP, FP, IP, FP>>, ? super RefactoringSession>, _FunctionTypes._void_P1_E0<? super RefactoringSession>)
* @deprecated
*/
@Deprecated
@ToRemove(version = 3.5)
public static <IP, FP> void performRefactoringUserInteractive(MPSProject project, String refactoringName, Iterable<? extends RefactoringParticipant<?, ?, IP, FP>> participants, final List<IP> initialStates, final _FunctionTypes._return_P2_E0<? extends Map<IP, FP>, ? super Iterable<RefactoringParticipant.ParticipantApplied<?, ?, IP, FP, IP, FP>>, ? super RefactoringSession> doRefactor, _FunctionTypes._void_P1_E0<? super RefactoringSession> doCleanup) {
performRefactoringInProject(project, new DefaultRefactoringUI(project), refactoringName, participants, initialStates, doRefactor, doCleanup);
}
/**
* Update usages during refactoring.
* For calling not in migration assistant but in interactive enviromnent, so performs all in single refactoring session with project scope.
*
* @see jetbrains.mps.refactoring.participant.RefactoringParticipant.KeepOldNodes
* @param doRefactor callback that performs refactoring itself (e.g. moves or renames smth)
* @param doCleanup cleanup that should be performed after all usages are updated (e.g. deletion of old code that can be used by participants), used only because of POSTPONE_REMOVE option
*/
public static <IP, FP> void performRefactoringInProject(Project project, RefactoringUI refactoringUI, String refactoringName, Iterable<? extends RefactoringParticipant<?, ?, IP, FP>> participants, final List<IP> initialStates, final _FunctionTypes._return_P2_E0<? extends Map<IP, FP>, ? super Iterable<RefactoringParticipant.ParticipantApplied<?, ?, IP, FP, IP, FP>>, ? super RefactoringSession> doRefactor, @Nullable final _FunctionTypes._void_P1_E0<? super RefactoringSession> doCleanup) {
final RefactoringSessionImpl refactoringSession = new RefactoringSessionImpl();
performRefactoring(new RefactoringParticipant.CollectingParticipantStateFactory<IP, FP>(), refactoringUI, refactoringSession, project.getRepository(), project.getScope(), refactoringName, participants, initialStates, new _FunctionTypes._return_P1_E0<Map<IP, FP>, Iterable<RefactoringParticipant.ParticipantApplied<?, ?, IP, FP, IP, FP>>>() {
public Map<IP, FP> invoke(Iterable<RefactoringParticipant.ParticipantApplied<?, ?, IP, FP, IP, FP>> participantStates) {
return doRefactor.invoke(participantStates, refactoringSession);
}
}, new _FunctionTypes._void_P0_E0() {
public void invoke() {
refactoringSession.performAllRegistered();
if (doCleanup != null) {
doCleanup.invoke(refactoringSession);
}
}
});
}
/**
* Update usages during refactoring.
* For calling from both 'during refactoring' and migration context.
*/
public static <IP, FP, IS, FS> void performRefactoring(final RefactoringParticipant.ParticipantStateFactory<IP, FP, IS, FS> factory, RefactoringUI refactoringUI, final RefactoringSession refactoringSession, final SRepository repository, SearchScope scope, String refactoringName, Iterable<? extends RefactoringParticipant<?, ?, IP, FP>> participants, final List<IS> initialStates, final _FunctionTypes._return_P1_E0<? extends Map<IS, FS>, ? super Iterable<RefactoringParticipant.ParticipantApplied<?, ?, IP, FP, IS, FS>>> doRefactor, @Nullable final _FunctionTypes._void_P0_E0 doCleanup) {
final Tuples._2<List<RefactoringParticipant.ParticipantApplied<?, ?, IP, FP, IS, FS>>, SearchTask> participantChanges = askParticipantChanges(factory, refactoringUI, repository, scope, participants, initialStates);
if (participantChanges == null) {
return;
}
final Wrappers._T<SearchResults> searchResults = new Wrappers._T<SearchResults>();
refactoringUI.runSearch(new _FunctionTypes._void_P1_E0<ProgressMonitor>() {
public void invoke(ProgressMonitor progressMonitor) {
searchResults.value = participantChanges._1().execute(repository.getModelAccess(), progressMonitor);
}
});
if (searchResults.value == null) {
return;
}
refactoringUI.showRefactoringView(new Runnable() {
public void run() {
final Map<IS, FS> getFinalObject = doRefactor.invoke(participantChanges._0());
if (getFinalObject == null) {
return;
}
for (RefactoringParticipant.ParticipantApplied<?, ?, IP, FP, IS, FS> participantState : ListSequence.fromList(participantChanges._0())) {
participantState.doRefactor(ListSequence.fromList(initialStates).select(new ISelector<IS, FS>() {
public FS select(IS it) {
return MapSequence.fromMap(getFinalObject).get(it);
}
}).toListSequence(), repository, refactoringSession, factory);
}
if (doCleanup != null) {
doCleanup.invoke();
}
}
}, refactoringName, searchResults.value, participantChanges._1(), refactoringSession);
}
}