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 /sources/scalac/typechecker | |
parent | 32512b86096beda6858b566fd6a78141dddc227f (diff) | |
download | scala-999b43195544490b58ea222c0b17064dd6c41e49.tar.gz scala-999b43195544490b58ea222c0b17064dd6c41e49.tar.bz2 scala-999b43195544490b58ea222c0b17064dd6c41e49.zip |
*** empty log message ***
Diffstat (limited to 'sources/scalac/typechecker')
-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 |
3 files changed, 74 insertions, 20 deletions
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); } } |