diff options
author | Martin Odersky <odersky@gmail.com> | 2003-10-31 14:31:22 +0000 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2003-10-31 14:31:22 +0000 |
commit | 999b43195544490b58ea222c0b17064dd6c41e49 (patch) | |
tree | f807e2e605dc65a2cd1dc65eec19444d9995cf22 | |
parent | 32512b86096beda6858b566fd6a78141dddc227f (diff) | |
download | scala-999b43195544490b58ea222c0b17064dd6c41e49.tar.gz scala-999b43195544490b58ea222c0b17064dd6c41e49.tar.bz2 scala-999b43195544490b58ea222c0b17064dd6c41e49.zip |
*** empty log message ***
-rw-r--r-- | sources/scala/tools/scaladoc/SymbolTablePrinter.java | 10 | ||||
-rw-r--r-- | sources/scalac/symtab/Type.java | 2 | ||||
-rw-r--r-- | sources/scalac/transformer/UnCurry.java | 21 | ||||
-rw-r--r-- | sources/scalac/typechecker/Analyzer.java | 24 | ||||
-rw-r--r-- | sources/scalac/typechecker/ConstantFolder.java | 68 | ||||
-rw-r--r-- | sources/scalac/typechecker/RefCheck.java | 2 | ||||
-rw-r--r-- | sources/scalac/util/Debug.java | 8 |
7 files changed, 108 insertions, 27 deletions
diff --git a/sources/scala/tools/scaladoc/SymbolTablePrinter.java b/sources/scala/tools/scaladoc/SymbolTablePrinter.java index b7c7621148..e8b4090e0a 100644 --- a/sources/scala/tools/scaladoc/SymbolTablePrinter.java +++ b/sources/scala/tools/scaladoc/SymbolTablePrinter.java @@ -489,6 +489,14 @@ public class SymbolTablePrinter extends scalac.symtab.SymbolTablePrinter { printUsedSymbolName(sym, user); return this; + case ConstantType(Type base, Object value): + System.out.println("CONSTANT" + type); + print("("); + printType(base); + print(value.toString()); + print(")"); + return this; + case CompoundType(Type[] parts, Scope members): printTypes(parts," with ", user); space(); @@ -569,7 +577,7 @@ public class SymbolTablePrinter extends scalac.symtab.SymbolTablePrinter { * * @param prefix */ - public Type getTypeToPrintForPrefix0(Type prefix) { + public Type getTypeToPrintForPrefix0(Ty*pe prefix) { if (!global.debug) { if (prefix.symbol().kind == Kinds.NONE) return null; if (prefix.symbol().isRoot()) return null; diff --git a/sources/scalac/symtab/Type.java b/sources/scalac/symtab/Type.java index 3635b51ca7..fe99837158 100644 --- a/sources/scalac/symtab/Type.java +++ b/sources/scalac/symtab/Type.java @@ -684,7 +684,7 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags { public String stringValue() { switch (this) { case ConstantType(_, Object value): - return (String)value; + return value.toString(); default: throw new ApplicationError(); } diff --git a/sources/scalac/transformer/UnCurry.java b/sources/scalac/transformer/UnCurry.java index 32389d9841..2293e5e8f2 100644 --- a/sources/scalac/transformer/UnCurry.java +++ b/sources/scalac/transformer/UnCurry.java @@ -124,14 +124,25 @@ public class UnCurry extends OwnerTransformer transform(impl, tree.symbol())); case DefDef(_, _, AbsTypeDef[] tparams, ValDef[][] vparams, Tree tpe, Tree rhs): - Tree rhs1 = transform(rhs, tree.symbol()); + Symbol sym = tree.symbol(); + if ((sym.flags & ACCESSED) == 0) { + switch (sym.type()) { + case PolyType(Symbol[] tparams1, ConstantType(_, _)): + if (tparams1.length == 0) return gen.mkUnitLit(tree.pos); + } + } + Tree rhs1 = transform(rhs, sym); return copy.DefDef( - tree, tree.symbol(), tparams, - uncurry(transform(vparams, tree.symbol())), - tpe, rhs1); + tree, sym, tparams, uncurry(transform(vparams, sym)), tpe, rhs1); case ValDef(_, _, Tree tpe, Tree rhs): - if (tree.symbol().isDefParameter()) { + Symbol sym = tree.symbol(); + if ((sym.flags & ACCESSED) == 0) { + switch (sym.type()) { + case ConstantType(_, _): return gen.mkUnitLit(tree.pos); + } + } + if (sym.isDefParameter()) { Type newtype = global.definitions.FUNCTION_TYPE(Type.EMPTY_ARRAY, tpe.type); Tree tpe1 = gen.mkType(tpe.pos, newtype); return copy.ValDef(tree, tpe1, rhs).setType(newtype); diff --git a/sources/scalac/typechecker/Analyzer.java b/sources/scalac/typechecker/Analyzer.java index 4b9e4c0f19..209b4af278 100644 --- a/sources/scalac/typechecker/Analyzer.java +++ b/sources/scalac/typechecker/Analyzer.java @@ -1206,8 +1206,15 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { */ Tree mkStable(Tree tree, Type pre, int mode, Type pt) { switch (tree.type) { - case ConstantType(Type base, Object value): + case ConstantType(_, Object value): return make.Literal(tree.pos, value).setType(tree.type); + case PolyType(Symbol[] tparams, Type restp): + if (tparams.length == 0) { + switch (restp) { + case ConstantType(_, Object value): + return make.Literal(tree.pos, value).setType(tree.type); + } + } } if ((pt != null && pt.isStable() || (mode & QUALmode) != 0) && pre.isStable()) { @@ -2259,8 +2266,9 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { } } } - return copy.TypeApply(tree, fn1, args1) - .setType(restp.subst(tparams, argtypes)); + return constfold.tryToFold( + copy.TypeApply(tree, fn1, args1) + .setType(restp.subst(tparams, argtypes))); } break; case ErrorType: @@ -2436,16 +2444,18 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { for (int i = 0; i < args.length; i++) { args[i] = adapt(args[i], argMode, formals[i]); } - return copy.Apply(tree, fn1, args) - .setType(restp1); + return constfold.tryToFold( + copy.Apply(tree, fn1, args) + .setType(restp1)); } break; case MethodType(Symbol[] params, Type restp): // if method is monomorphic, // check that it can be applied to arguments. if (infer.isApplicable(fn1.type, argtypes, Type.AnyType)) { - return copy.Apply(tree, fn1, args) - .setType(restp); + return constfold.tryToFold( + copy.Apply(tree, fn1, args) + .setType(restp)); } } diff --git a/sources/scalac/typechecker/ConstantFolder.java b/sources/scalac/typechecker/ConstantFolder.java index e246711e76..9131609c7d 100644 --- a/sources/scalac/typechecker/ConstantFolder.java +++ b/sources/scalac/typechecker/ConstantFolder.java @@ -13,6 +13,7 @@ package scalac.typechecker; import scalac.util.*; +import scalac.ast.*; import scalac.symtab.*; import scalac.symtab.Type.*; @@ -26,11 +27,17 @@ class ConstantFolder implements /*imports*/ TypeTags { /** fold binary operation. */ - Type foldBinary(int pos, ConstantType left, ConstantType right, - Name op, Type restype) { + Type foldBinary(int pos, ConstantType left, ConstantType right, Name op) { try { + Type optype = left.deconst(); + if (optype.symbol() == ana.definitions.BYTE_CLASS || + optype.symbol() == ana.definitions.CHAR_CLASS || + optype.symbol() == ana.definitions.SHORT_CLASS) + optype = ana.definitions.INT_TYPE(); + if (optype.isSubType(right.deconst())) + optype = right.deconst(); Object value = null; - switch (restype.unbox()) { + switch (optype.unbox()) { case UnboxedType(INT): if (op == Names.ADD) value = new Integer(left.intValue() + right.intValue()); @@ -164,12 +171,11 @@ class ConstantFolder implements /*imports*/ TypeTags { value = new Boolean(left.booleanValue() ^ right.booleanValue()); break; default: - if (restype.symbol() == ana.definitions.JAVA_STRING_CLASS && + if (optype.symbol() == ana.definitions.JAVA_STRING_CLASS && op == Names.ADD) value = left.stringValue() + right.stringValue(); } - return (value != null) ? new ConstantType(restype, value) - : Type.NoType; + return (value != null) ? Type.constantType(value) : Type.NoType; } catch (ArithmeticException e) { ana.unit.error(pos, e.toString()); return Type.NoType; @@ -178,10 +184,10 @@ class ConstantFolder implements /*imports*/ TypeTags { /** fold unary operation. */ - Type foldUnary(int pos, ConstantType od, Name op, Type restype) { + Type foldUnary(int pos, ConstantType od, Name op) { try { Object value = null; - switch (restype.unbox()) { + switch (od.deconst().unbox()) { case UnboxedType(INT): if (op == Names.ADD) value = new Integer(od.intValue()); @@ -215,8 +221,7 @@ class ConstantFolder implements /*imports*/ TypeTags { value = new Boolean(!od.booleanValue()); break; } - return (value != null) ? new ConstantType(restype, value) - : Type.NoType; + return (value != null) ? Type.constantType(value) : Type.NoType; } catch (ArithmeticException e) { ana.unit.error(pos, e.toString()); return Type.NoType; @@ -225,10 +230,10 @@ class ConstantFolder implements /*imports*/ TypeTags { /** fold cast operation */ - Type foldAsInstanceOf(int pos, ConstantType od, Type restype) { + Type foldAsInstanceOf(int pos, ConstantType od, Type argtype) { try { Object value = null; - switch (restype.unbox()) { + switch (argtype.unbox()) { case UnboxedType(BYTE): value = new Byte((byte)od.intValue()); break; @@ -254,13 +259,50 @@ class ConstantFolder implements /*imports*/ TypeTags { value = new Boolean(od.booleanValue()); break; } - return (value != null) ? new ConstantType(restype, value) + return (value != null) ? new ConstantType(argtype, value) : Type.NoType; } catch (ClassCastException e) { ana.unit.error(pos, e.toString()); return Type.NoType; } } + + /** attempt to constant fold tree. + */ + Tree tryToFold(Tree tree) { + Type ctp = Type.NoType; + switch (tree) { + case Apply(Select(Tree qual, Name op), Tree[] args): + if (qual.type instanceof ConstantType) { + if (args.length == 0) + ctp = foldUnary( + tree.pos, (ConstantType)qual.type, op); + else if (args.length == 1 && + args[0].type instanceof ConstantType) + ctp = foldBinary( + tree.pos, + (ConstantType)qual.type, + (ConstantType)(args[0].type), + op); + } + break; + case TypeApply(Select(Tree qual, Name op), Tree[] targs): + if (qual.type instanceof Type.ConstantType && + op == Names.asInstanceOf) + ctp = foldAsInstanceOf( + tree.pos, + (ConstantType)qual.type, + targs[0].type); + break; + } + switch (ctp) { + case ConstantType(Type base, Object value): + return ana.make.Literal(tree.pos, value).setType(ctp); + default: + return tree; + } + } + } diff --git a/sources/scalac/typechecker/RefCheck.java b/sources/scalac/typechecker/RefCheck.java index 6bf3e9b0a5..2aee3a04c4 100644 --- a/sources/scalac/typechecker/RefCheck.java +++ b/sources/scalac/typechecker/RefCheck.java @@ -33,6 +33,7 @@ import Tree.*; * they are defined in the class or a baseclass different from java.lang.Object * - Calls to case factory methods are replaced by new's. * - Type nodes are replaced by TypeTerm nodes. + * - Eliminate constant definitions */ public class RefCheck extends Transformer implements Modifiers, Kinds { @@ -134,6 +135,7 @@ public class RefCheck extends Transformer implements Modifiers, Kinds { } } if (member != other) { + member.flags |= ACCESSED; checkOverride(pos, clazz, member, other); } } diff --git a/sources/scalac/util/Debug.java b/sources/scalac/util/Debug.java index d0be664884..1b0c976048 100644 --- a/sources/scalac/util/Debug.java +++ b/sources/scalac/util/Debug.java @@ -522,6 +522,14 @@ public class DebugType extends DebugAbstractHandler { buffer.append(')'); return; + case ConstantType(Type prefix, Object value): + buffer.append("ConstantType("); + Debug.append(buffer, prefix); + buffer.append(','); + Debug.append(buffer, value); + buffer.append(')'); + return; + case CompoundType(Type[] basetypes, Scope members): buffer.append("CompoundType("); Debug.append(buffer, basetypes); |