diff options
Diffstat (limited to 'sources/scalac/symtab/Type.java')
-rw-r--r-- | sources/scalac/symtab/Type.java | 145 |
1 files changed, 144 insertions, 1 deletions
diff --git a/sources/scalac/symtab/Type.java b/sources/scalac/symtab/Type.java index e574a35776..3635b51ca7 100644 --- a/sources/scalac/symtab/Type.java +++ b/sources/scalac/symtab/Type.java @@ -35,6 +35,17 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags { assert this instanceof ExtSingleType; } + /** Type for a numeric or string constant. + */ + public case ConstantType(Type base, Object value) { + if (base.symbol() == Global.instance.definitions.BYTE_CLASS) + assert value instanceof Byte; + if (base.symbol() == Global.instance.definitions.CHAR_CLASS) + assert value instanceof Character; + if (base.symbol() == Global.instance.definitions.SHORT_CLASS) + assert value instanceof Short; + } + /** pre.sym[args] * sym represents a type * for example: scala.List[java.lang.String] is coded as @@ -136,6 +147,28 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags { } } + public static ConstantType constantType(Object value) { + return new ConstantType(value2type(value), value); + } + + private static Type value2type(Object value) { + if (value instanceof Character) + return Global.instance.definitions.CHAR_TYPE(); + else if (value instanceof Integer) + return Global.instance.definitions.INT_TYPE(); + else if (value instanceof Long) + return Global.instance.definitions.LONG_TYPE(); + else if (value instanceof Float) + return Global.instance.definitions.FLOAT_TYPE(); + else if (value instanceof Double) + return Global.instance.definitions.DOUBLE_TYPE(); + else if (value instanceof String) + return Global.instance.definitions.JAVA_STRING_TYPE(); + else if (value instanceof Boolean) + return Global.instance.definitions.BOOLEAN_TYPE(); + else throw new ApplicationError(); + } + public static Type singleTypeMethod(Type pre, Symbol sym) { Global global = Global.instance; if (global.currentPhase.id <= global.PHASE.UNCURRY.id()) @@ -242,6 +275,8 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags { return sym; case SingleType(_, Symbol sym): return sym; + case ConstantType(Type base, _): + return base.symbol(); case TypeVar(Type origin, _): return origin.symbol(); case CompoundType(_, _): @@ -282,6 +317,7 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags { return this; case ThisType(_): case SingleType(_, _): + case ConstantType(_, _): return singleDeref().bound(); case TypeVar(Type origin, Constraint constr): if (constr.inst != NoType) return constr.inst.bound(); @@ -301,6 +337,8 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags { case SingleType(Type pre, Symbol sym): // overridden in ExtSingleType throw new ApplicationError(); + case ConstantType(Type base, _): + return base; case TypeVar(Type origin, Constraint constr): if (constr.inst != NoType) return constr.inst.singleDeref(); else return this; @@ -317,6 +355,7 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags { switch (tp) { case ThisType(_): case SingleType(_, _): + case ConstantType(_, _): return tp.widen(); default: return tp; @@ -347,6 +386,18 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags { } } + /** If this type is a constant type, its underlying basetype; + * otherwise the type itself + */ + public Type deconst() { + switch (this) { + case ConstantType(Type base, _): + return base; + default: + return this; + } + } + /** If this type is a parameterless method, its underlying resulttype; * otherwise the type itself */ @@ -459,6 +510,7 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags { switch (unalias()) { case ThisType(_): case SingleType(_, _): + case ConstantType(_, _): return singleDeref().parents(); case TypeRef(Type pre, Symbol sym, Type[] args): if (sym.kind == CLASS) { @@ -587,6 +639,62 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags { return this; } + /** Numeric values + */ + public int intValue() { + switch (this) { + case ConstantType(_, Object value): + return toNumber(value).intValue(); + default: + throw new ApplicationError(); + } + } + public long longValue() { + switch (this) { + case ConstantType(_, Object value): + return toNumber(value).longValue(); + default: + throw new ApplicationError(); + } + } + public float floatValue() { + switch (this) { + case ConstantType(_, Object value): + return toNumber(value).floatValue(); + default: + throw new ApplicationError(); + } + } + public double doubleValue() { + switch (this) { + case ConstantType(_, Object value): + return toNumber(value).doubleValue(); + default: + throw new ApplicationError(); + } + } + public boolean booleanValue() { + switch (this) { + case ConstantType(_, Object value): + return ((Boolean)value).booleanValue(); + default: + throw new ApplicationError(); + } + } + public String stringValue() { + switch (this) { + case ConstantType(_, Object value): + return (String)value; + default: + throw new ApplicationError(); + } + } + private static Number toNumber(Object value) { + return (value instanceof Character) + ? new Integer(((Character)value).charValue()) + : (Number)value; + } + // Tests -------------------------------------------------------------------- /** Is this type a this type or singleton type? @@ -595,6 +703,7 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags { switch (unalias()) { case ThisType(_): case SingleType(_, _): + case ConstantType(_, _): return true; default: return false; @@ -624,6 +733,7 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags { switch (unalias()) { case ThisType(_): case SingleType(_, _): + case ConstantType(_, _): case CompoundType(_, _): case TypeRef(_, _, _): return true; @@ -675,7 +785,8 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags { return new Scope(); case TypeRef(_, Symbol sym, _): return sym.info().members(); - case SingleType(_, Symbol sym): + case SingleType(_, _): + case ConstantType(_, _): return singleDeref().members(); case CompoundType(Type[] basetypes, Scope members): return members; @@ -693,6 +804,7 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags { return Symbol.ERROR; case ThisType(_): case SingleType(_, _): + case ConstantType(_, _): return singleDeref().lookup(name); case TypeRef(_, Symbol sym, _): return sym.info().lookup(name); @@ -722,6 +834,7 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags { return Symbol.ERROR; case ThisType(_): case SingleType(_, _): + case ConstantType(_, _): return singleDeref().lookupNonPrivate(name); case TypeRef(_, Symbol sym, _): return sym.info().lookupNonPrivate(name, start); @@ -860,6 +973,10 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags { Type pre1 = apply(pre); if (pre1 == pre) return tp; else return singleType(pre1, sym); + case ConstantType(Type base, Object value): + Type base1 = apply(base); + if (base1 == base) return tp; + else return new ConstantType(base1, value); case CompoundType(Type[] parts, Scope members): Type[] parts1 = map(parts); Scope members1 = map(members); @@ -1014,6 +1131,7 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags { case ThisType(_): case SingleType(_, _): + case ConstantType(_, _): return singleDeref().baseType(clazz); case TypeRef(Type pre, Symbol sym, Type[] args): @@ -1687,9 +1805,11 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags { case ThisType(_): case SingleType(_, _): + case ConstantType(_, _): switch (this) { case ThisType(_): case SingleType(_, _): + case ConstantType(_, _): return this.isSameAs(that); } break; @@ -1795,6 +1915,9 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags { case SingleType(_, _): if (this.singleDeref().isSubType(that)) return true; break; + case ConstantType(_, Object value): + if (this.singleDeref().isSubType(that)) return true; + break; case TypeVar(Type origin, Constraint constr): if (constr.inst != NoType) { return constr.inst.isSubType(that); @@ -1987,6 +2110,13 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags { } break; + case ConstantType(Type base, Object value): + switch (that) { + case ConstantType(Type base1, Object value1): + return base.isSameAs(base1) && value.equals(value1); + } + break; + case TypeRef(Type pre, Symbol sym, Type[] args): switch (that) { case TypeRef(Type pre1, Symbol sym1, Type[] args1): @@ -2560,6 +2690,7 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags { break; case ThisType(_): case SingleType(_, _): + case ConstantType(_, _): return Global.instance.definitions.ALL_TYPE(); } } @@ -2871,6 +3002,7 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags { switch (this) { case ThisType(_): case SingleType(_, _): + case ConstantType(_, _): return singleDeref().erasure(); case TypeRef(Type pre, Symbol sym, Type[] args): switch (sym.kind) { @@ -2958,6 +3090,10 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags { return SINGLEtpe ^ (pre.hashCode() * 41) ^ (sym.hashCode() * (41*41)); + case ConstantType(Type base, Object value): + return CONSTANTtpe + ^ (base.hashCode() * 41) + ^ (value.hashCode() * (41*41)); case CompoundType(Type[] parts, Scope members): return symbol().hashCode(); //return COMPOUNDtpe @@ -3026,6 +3162,12 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags { return pre.equals(pre1) && sym == sym1; default: return false; } + case ConstantType(Type base, Object value): + switch (that) { + case ConstantType(Type base1, Object value1): + return base.equals(base1) && value.equals(value1); + default: return false; + } case CompoundType(Type[] parts, Scope members): switch (that) { case CompoundType(Type[] parts1, Scope members1): @@ -3194,6 +3336,7 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags { case ThisType(Symbol sym): case TypeRef(Type pre, Symbol sym, Type[] args): case SingleType(Type pre, Symbol sym): + case ConstantType(Type base, Object value): case CompoundType(Type[] parts, Scope members): case MethodType(Symbol[] vparams, Type result): case PolyType(Symbol[] tparams, Type result): |