package jetbrains.mps.baseLanguage.util.plugin.refactorings;
/*Generated by MPS */
import java.util.List;
import org.jetbrains.mps.openapi.model.SNode;
import java.util.Map;
import java.util.Set;
import jetbrains.mps.internal.collections.runtime.SetSequence;
import java.util.HashSet;
import jetbrains.mps.internal.collections.runtime.ListSequence;
import java.util.ArrayList;
import jetbrains.mps.lang.smodel.generator.smodelAdapter.SNodeOperations;
import jetbrains.mps.smodel.adapter.structure.MetaAdapterFactory;
import org.jetbrains.mps.openapi.language.SAbstractConcept;
import jetbrains.mps.lang.pattern.util.MatchingUtil;
import jetbrains.mps.lang.pattern.util.IMatchModifier;
import jetbrains.mps.internal.collections.runtime.MapSequence;
public class MethodDuplicatesFinder {
private List<SNode> myNodesToFind;
private final Map<SNode, SNode> myMapping;
private final List<SNode> myParameterOrder;
private Set<SNode> myOutputRefs;
private Set<SNode> myUsedNodes = SetSequence.fromSet(new HashSet<SNode>());
public MethodDuplicatesFinder(List<SNode> nodesToFind, Map<SNode, SNode> mapping, List<SNode> parametersOrder, Set<SNode> outputReferences) {
this.myNodesToFind = nodesToFind;
this.myMapping = mapping;
this.myParameterOrder = parametersOrder;
myOutputRefs = outputReferences;
SetSequence.fromSet(this.myUsedNodes).addSequence(ListSequence.fromList(this.myNodesToFind));
}
public List<MethodMatch> findDuplicates(SNode root) {
List<MethodMatch> found = new ArrayList<MethodMatch>();
for (SNode node : ListSequence.fromList(SNodeOperations.getNodeDescendants(root, MetaAdapterFactory.getConcept(0xceab519525ea4f22L, 0x9b92103b95ca8c0cL, 0x10802efe25aL, "jetbrains.mps.lang.core.structure.BaseConcept"), false, new SAbstractConcept[]{}))) {
SNode current = node;
MethodDuplicatesFinder.MethodMatchModifier modifier = new MethodDuplicatesFinder.MethodMatchModifier();
boolean hasNoErrors = true;
for (SNode nodeToFind : ListSequence.fromList(this.myNodesToFind)) {
if ((current == null) || SetSequence.fromSet(this.myUsedNodes).contains(current)) {
hasNoErrors = false;
break;
} else {
modifier.getMatch().putNode(current);
if (!(ExtractMethodFactory.isRefactoringAvailable(modifier.getMatch().getNodes())) || !(MatchingUtil.matchNodes(current, nodeToFind, modifier, true))) {
hasNoErrors = false;
break;
}
current = SNodeOperations.getNextSibling(current);
}
}
if (hasNoErrors) {
MethodMatch resultMatch = modifier.getMatch();
resultMatch.createRefactoring();
if (resultMatch.checkMatch()) {
for (SNode resultNode : ListSequence.fromList(resultMatch.getNodes())) {
SetSequence.fromSet(this.myUsedNodes).addElement(resultNode);
}
found.add(resultMatch);
}
}
}
return found;
}
public void matchNodes(SNode candidate, SNode node) {
}
public class MethodMatchModifier implements IMatchModifier {
private MethodMatch myMatch;
public MethodMatchModifier() {
this.myMatch = new MethodMatch(MethodDuplicatesFinder.this.myParameterOrder);
}
@Override
public boolean accept(SNode candidate, SNode original) {
if (SetSequence.fromSet(myOutputRefs).contains(original)) {
this.myMatch.putOutputReference(candidate);
}
if (MapSequence.fromMap(MethodDuplicatesFinder.this.myMapping).containsKey(original)) {
return true;
}
return false;
}
@Override
public boolean acceptList(List<SNode> list1, List<SNode> list2) {
return false;
}
@Override
public void performAction(SNode candidate, SNode original) {
this.myMatch.putMapping(candidate, MapSequence.fromMap(MethodDuplicatesFinder.this.myMapping).get(original));
}
@Override
public void performGroupAction(List<SNode> list1, List<SNode> list2) {
}
public MethodMatch getMatch() {
return this.myMatch;
}
}
}