package jetbrains.mps.lang.scopes.runtime;
/*Generated by MPS */
import jetbrains.mps.scope.Scope;
import org.jetbrains.mps.openapi.language.SAbstractConcept;
import java.util.Set;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.mps.openapi.model.SNode;
import java.util.HashSet;
import jetbrains.mps.internal.collections.runtime.Sequence;
import jetbrains.mps.lang.smodel.generator.smodelAdapter.SNodeOperations;
import jetbrains.mps.internal.collections.runtime.SetSequence;
import org.jetbrains.annotations.Nullable;
import java.util.List;
import java.util.ArrayList;
import jetbrains.mps.internal.collections.runtime.ListSequence;
import jetbrains.mps.internal.collections.runtime.IWhereFilter;
import jetbrains.mps.smodel.adapter.structure.MetaAdapterFactory;
public class HidingByNameScope extends Scope {
private final SAbstractConcept hidingRootConcept;
private final SAbstractConcept kindConcept;
private final Scope scope;
private final Scope parentScope;
private final Set<String> names;
public HidingByNameScope(SAbstractConcept hidingConcept, SAbstractConcept kind, @NotNull Scope scope, @NotNull Scope parentScope) {
// hiding root: all subconcepts of hidingRoot hide each other
this.scope = scope;
this.parentScope = parentScope;
this.hidingRootConcept = hidingConcept;
this.kindConcept = kind;
// todo: maybe lazy in getAvailableElements?
// todo: I need this micro optimizations?
Iterable<SNode> tmpResult = scope.getAvailableElements(null);
this.names = new HashSet<String>(Sequence.fromIterable(tmpResult).count());
for (SNode node : Sequence.fromIterable(tmpResult)) {
if (SNodeOperations.isInstanceOf(node, SNodeOperations.asSConcept(hidingRootConcept))) {
SetSequence.fromSet(this.names).addElement(node.getName());
}
}
}
@Override
public Iterable<SNode> getAvailableElements(@Nullable String prefix) {
List<SNode> result = new ArrayList<SNode>();
ListSequence.fromList(result).addSequence(Sequence.fromIterable(scope.getAvailableElements(prefix)).where(new IWhereFilter<SNode>() {
public boolean accept(SNode it) {
return SNodeOperations.isInstanceOf(it, SNodeOperations.asSConcept(kindConcept));
}
}));
ListSequence.fromList(result).addSequence(Sequence.fromIterable(parentScope.getAvailableElements(prefix)).where(new IWhereFilter<SNode>() {
public boolean accept(SNode it) {
return SNodeOperations.isInstanceOf(it, SNodeOperations.asSConcept(kindConcept));
}
}).where(new IWhereFilter<SNode>() {
public boolean accept(SNode it) {
return !(SNodeOperations.isInstanceOf(it, SNodeOperations.asSConcept(hidingRootConcept))) || !(SetSequence.fromSet(names).contains(it.getName()));
}
}));
return result;
}
@Nullable
@Override
public SNode resolve(SNode contextNode, @NotNull String refText) {
// todo: recheck this code
return (SetSequence.fromSet(names).contains(refText) ? scope.resolve(contextNode, refText) : parentScope.resolve(contextNode, refText));
}
@Nullable
@Override
public String getReferenceText(SNode contextNode, @NotNull SNode node) {
return node.getName();
}
@Override
public boolean contains(SNode node) {
if (!(SNodeOperations.isInstanceOf(node, MetaAdapterFactory.getInterfaceConcept(0xceab519525ea4f22L, 0x9b92103b95ca8c0cL, 0x110396eaaa4L, "jetbrains.mps.lang.core.structure.INamedConcept"))) || !(SNodeOperations.isInstanceOf(node, SNodeOperations.asSConcept(kindConcept)))) {
return false;
}
if (scope.contains(node)) {
return true;
}
if (SetSequence.fromSet(names).contains(node.getName())) {
return false;
}
return parentScope.contains(node);
}
}