package jetbrains.mps.scope;
/*Generated by MPS */
import java.util.List;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import org.jetbrains.mps.openapi.model.SNode;
import org.jetbrains.annotations.Nullable;
import jetbrains.mps.internal.collections.runtime.ListSequence;
import jetbrains.mps.internal.collections.runtime.Sequence;
public class CompositeScope extends Scope {
private List<Scope> myScopes;
public CompositeScope(Scope... scopeChain) {
myScopes = new ArrayList<Scope>();
for (Scope scope : scopeChain) {
if (scope instanceof CompositeScope) {
myScopes.addAll(((CompositeScope) scope).getScopes());
} else if (scope != null) {
myScopes.add(scope);
}
}
}
public void addScope(Scope scope) {
if (scope instanceof CompositeScope) {
myScopes.addAll(((CompositeScope) scope).getScopes());
} else if (scope != null) {
myScopes.add(scope);
}
}
public Collection<Scope> getScopes() {
return Collections.unmodifiableCollection(myScopes);
}
@Override
public SNode resolve(SNode contextNode, String refText) {
SNode result = null;
for (Scope scope : myScopes) {
SNode r = scope.resolve(contextNode, refText);
if (r != null) {
if (result == null) {
result = r;
} else if (result != r) {
// ambiguity
return null;
}
}
}
return result;
}
@Override
public Iterable<SNode> getAvailableElements(@Nullable String prefix) {
List<SNode> result = new ArrayList<SNode>();
for (Scope scope : myScopes) {
ListSequence.fromList(result).addSequence(Sequence.fromIterable(scope.getAvailableElements(prefix)));
}
return result;
}
@Override
public String getReferenceText(SNode contextNode, SNode node) {
String result = null;
for (Scope scope : myScopes) {
String refText = scope.getReferenceText(contextNode, node);
if (refText != null) {
if (result == null) {
result = refText;
} else {
// ambiguity
return null;
}
}
}
return result;
}
public static Scope createComposite(Scope... scopes) {
Scope last = null;
for (Scope s : scopes) {
if (s == null) {
continue;
}
if (last == null) {
last = s;
} else if (last instanceof CompositeScope) {
((CompositeScope) last).addScope(s);
} else if (s instanceof CompositeScope) {
((CompositeScope) s).addScope(last);
last = s;
} else {
last = new CompositeScope(last, s);
}
}
return last;
}
}