package typing; import java.util.Set; import java.util.TreeSet; /** * Represents a type for tuples. * * @author Benedikt Meurer * @version $Id$ */ public final class TupleType extends MonoType { /** * Allocates a new <code>TupleType</code> with * the given monomorphic <code>types</code>. * * @param types a non-empty array of monomorphic * types for the items of a tuple. */ public TupleType(MonoType[] types) { // validate the types assert (types.length > 0); // apply the types this.types = types; } /** * {@inheritDoc} * * @see typing.MonoType#containsFreeTypeVariable(java.lang.String) */ @Override public boolean containsFreeTypeVariable(String name) { for (MonoType type : this.types) if (type.containsFreeTypeVariable(name)) return true; return false; } /** * {@inheritDoc} * * @see typing.MonoType#free() */ @Override public Set<String> free() { TreeSet<String> free = new TreeSet<String>(); for (MonoType type : this.types) free.addAll(type.free()); return free; } /** * {@inheritDoc} * * @see typing.MonoType#substitute(typing.Substitution) */ @Override MonoType substitute(Substitution s) { MonoType[] types = new MonoType[this.types.length]; for (int n = 0; n < types.length; ++n) types[n] = this.types[n].substitute(s); return new TupleType(types); } /** * Checks if the <code>obj</code> is a {@link TupleType} * which is equal to this tuple type. * * @param obj another object. * * @return <code>true</code> if equal. * * @see java.lang.Object#equals(java.lang.Object) */ @Override public boolean equals(Object obj) { if (obj instanceof TupleType) { TupleType tt = (TupleType)obj; if (tt.types.length == this.types.length) { for (int i = 0; i < tt.types.length; ++i) if (!tt.types[i].equals(this.types[i])) return false; return true; } } return false; } /** * Returns the string representation of the * tuple type. * * @return the string representation. * * @see java.lang.Object#toString() */ @Override public String toString() { StringBuilder builder = new StringBuilder(128); for (MonoType type : this.types) { if (builder.length() > 0) builder.append(" * "); if (type.getClass().equals(TypeVariable.class) || type.getClass().equals(PrimitiveType.class)) { builder.append(type); } else { builder.append("("); builder.append(type); builder.append(")"); } } return builder.toString(); } /** * Returns the arity of the tuple type. * * @return the arity of the tuple type. */ public int arity() { return this.types.length; } /** * Returns the types for the items of this tuple type. * * @return the types for the items of this tuple type. */ public MonoType[] getTypes() { return this.types; } // member attributes private MonoType[] types; }