package scotch.symbol.type; import static java.util.stream.Collectors.joining; import static java.util.stream.Collectors.toList; import static java.util.stream.Collectors.toSet; import java.util.List; import java.util.Set; import java.util.function.Function; import com.google.common.collect.ImmutableList; import lombok.EqualsAndHashCode; import lombok.Getter; import scotch.symbol.Symbol; import scotch.util.Pair; @EqualsAndHashCode(callSuper = false) public class SumTypeDescriptor extends TypeDescriptor { @Getter private final Symbol symbol; @Getter private final List<TypeDescriptor> parameters; SumTypeDescriptor(Symbol symbol, List<? extends TypeDescriptor> parameters) { this.symbol = symbol; this.parameters = ImmutableList.copyOf(parameters); } @Override public <T> T accept(Visitor<T> visitor) { return visitor.visit(this); } @Override public Set<Symbol> getContext() { return parameters.stream() .map(TypeDescriptor::getContext) .flatMap(Set::stream) .collect(toSet()); } @Override public TypeDescriptor mapVariables(Function<TypeDescriptor, TypeDescriptor> function) { return new SumTypeDescriptor(symbol, parameters.stream() .map(parameter -> parameter.mapVariables(function)) .collect(toList())); } @Override protected Set<Pair<VariableTypeDescriptor, Symbol>> gatherContext_() { return parameters.stream() .flatMap(parameter -> parameter.gatherContext_().stream()) .collect(toSet()); } @Override protected String toParenthesizedString() { return toString_(); } @Override protected String toString_() { if (symbol.isTuple()) { return "(" + parameters.stream().map(TypeDescriptor::toString_).collect(joining(", ")) + ")"; } else if (symbol.isList()) { return "[" + parameters.stream().map(TypeDescriptor::toString_).collect(joining(", ")) + "]"; } else if (parameters.isEmpty()) { return symbol.getSimpleName(); } else { return symbol.getSimpleName() + " " + parameters.stream().map(TypeDescriptor::toString_).collect(joining(" ")); } } }