/* * This file is part of the X10 project (http://x10-lang.org). * * This file is licensed to You under the Eclipse Public License (EPL); * You may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.opensource.org/licenses/eclipse-1.0.php * * This file was originally derived from the Polyglot extensible compiler framework. * * (C) Copyright 2000-2007 Polyglot project group, Cornell University * (C) Copyright IBM Corporation 2007-2012. */ package polyglot.types; import java.util.List; import polyglot.util.CodeWriter; import polyglot.util.Position; import polyglot.util.TypedList; import x10.types.X10ClassType; /** * Abstract implementation of a <code>Type</code>. This implements most of * the "isa" and "cast" methods of the type and methods which just dispatch to * the type system. */ public abstract class Type_c extends TypeObject_c implements Type { private static final long serialVersionUID = -876728129439491724L; List<Type> annotations; /** Used for deserializing types. */ protected Type_c() { } /** Creates a new type in the given a TypeSystem. */ public Type_c(TypeSystem ts) { this(ts, null, null); } /** Creates a new type in the given a TypeSystem at a given position. */ public Type_c(TypeSystem ts, Position pos, Position errorPos) { super(ts, pos, errorPos); } public List<Type> annotations() { return annotations; } public Type annotations(List<Type> annotations) { Type_c result = (Type_c) copy(); result.annotations= TypedList.copyAndCheck(annotations, Type.class, true); return result; } /** * Return a string into which to translate the type. * @param c A resolver in which to lookup this type to determine if * the type is unique in the given resolver. */ public abstract String translate(Resolver c); public boolean isType() { return true; } public boolean isPackage() { return false; } public Type toType() { return this; } public Package toPackage() { return null; } /* To be filled in by subtypes. */ public boolean isJavaPrimitive() { return false; } public boolean isReference() { return false; } public boolean isNull() { return false; } public boolean isClass() { return false; } public boolean isArray() { return false; } public final boolean isAny() { return ts.isAny(this); } public final boolean isParameterType() { return ts.isParameterType(this); } public final boolean isString() { return ts.isString(this); } public final boolean isIndexedMemoryChunk() { return ts.isIndexedMemoryChunk(this); } public final boolean isRuntime() { return ts.isRuntime(this); } public final boolean isNumeric() { return ts.isNumeric(this); } public final boolean isSignedNumeric() { return ts.isSignedNumeric(this); } public final boolean isUnsignedNumeric() { return ts.isUnsignedNumeric(this); } public final boolean isIntOrLess() { return ts.isIntOrLess(this); } public final boolean isLongOrLess() { return ts.isLongOrLess(this); } public final boolean isVoid() { return ts.isVoid(this); } public final boolean isBoolean() { return ts.isBoolean(this); } public final boolean isChar() { return ts.isChar(this); } public final boolean isByte() { return ts.isByte(this); } public final boolean isShort() { return ts.isShort(this); } public final boolean isInt() { return ts.isInt(this); } public final boolean isLong() { return ts.isLong(this); } public final boolean isFloat() { return ts.isFloat(this); } public final boolean isDouble() { return ts.isDouble(this); } public final boolean isUByte() { return ts.isUByte(this); } public final boolean isUShort() { return ts.isUShort(this); } public final boolean isUInt() { return ts.isUInt(this); } public final boolean isULong() { return ts.isULong(this); } public Name name() { return null; } public QName fullName() { Name n = name(); if (n == null) return null; return QName.make(null, n); } public boolean isGloballyAccessible() { return true; } /** * Return true if a subclass of Throwable. */ public final boolean isThrowable() { return ts.isThrowable(this); } /** * Return true if an unchecked exception. */ public final boolean isUncheckedException() { return ts.isUncheckedException(this); } /** Returns a non-null iff isClass() returns true. */ public X10ClassType toClass() { return null; } /** Returns a non-null iff isNull() returns true. */ public NullType toNull() { return null; } /** Returns a non-null iff isReference() returns true. */ public ObjectType toReference() { return null; } /** Returns a non-null iff isPrimitive() returns true. */ public JavaPrimitiveType toPrimitive() { return null; } /** Returns a non-null iff isArray() returns true. */ public JavaArrayType toArray() { return null; } /** * Return a <code>dims</code>-array of this type. */ public Type arrayOf(int dims) { return ts.arrayOf(this, dims); } /** * Return an array of this type. */ public Type arrayOf() { return ts.arrayOf(this); } public final boolean typeEquals(Type t, Context context) { return ts.typeEquals(this, t, context); } public final void typeEqualsImpl(Type t) { } public final void isSubtypeImpl(Type t) { } public final void descendsFromImpl(Type t) { } public final void isCastValidImpl(Type t) { } public final void isImplicitCastValidImpl(Type t) { } public final void numericConversionValidImpl(long t) { } public final void numericConversionValidImpl(Object t) { } /** * Return true if this type is a subtype of <code>ancestor</code>. */ public final boolean isSubtype(Type t, Context context) { return ts.isSubtype(this, t, context); } /** * Return true if this type can be cast to <code>toType</code>. */ public final boolean isCastValid(Type toType, Context context) { return ts.isCastValid(this, toType, context); } /** * Return true if a value of this type can be assigned to a variable of * type <code>toType</code>. */ public final boolean isImplicitCastValid(Type toType, Context context) { return ts.isImplicitCastValid(this, toType, context); } /** * Return true a literal <code>value</code> can be converted to this type. * This method should be removed. It is kept for backward compatibility. */ public final boolean numericConversionValid(long value, Context context) { return ts.numericConversionValid(this, value, context); } /** * Return true a literal <code>value</code> can be converted to this type. */ public final boolean numericConversionValid(Object value, Context context) { return ts.numericConversionValid(this, value, context); } /** * Return true if the types can be compared; that is, if they have * the same type system. */ public boolean isComparable(Type t) { return t.typeSystem() == ts; } /** * Yields a string representing this type. The string is that obtained * by calling typeToString(), with the annotations (if any) appended. * * <p> Subclasses should implement typeToString() to provide a representation * of the underlying type. * */ public final String toString() { if (annotations != null) { StringBuilder sb = new StringBuilder(); sb.append(typeToString()); for (Type ct : annotations) { sb.append("@"); sb.append(ct); sb.append(" "); } return sb.toString(); } return typeToString(); } /** * Yields a string representing this type. The string * should be consistent with equality. That is, * if this.equals(anotherType), then it should be * that this.toString().equals(anotherType.toString()). * * The string does not have to be a legal Java identifier. * It is suggested, but not required, that it be an * easily human readable representation, and thus useful * in error messages and generated output. * */ abstract public String typeToString(); public void print(CodeWriter w) { w.write(toString()); } }