summaryrefslogtreecommitdiff
path: root/sources/scalac/typechecker
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2003-10-31 14:31:22 +0000
committerMartin Odersky <odersky@gmail.com>2003-10-31 14:31:22 +0000
commit999b43195544490b58ea222c0b17064dd6c41e49 (patch)
treef807e2e605dc65a2cd1dc65eec19444d9995cf22 /sources/scalac/typechecker
parent32512b86096beda6858b566fd6a78141dddc227f (diff)
downloadscala-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.java24
-rw-r--r--sources/scalac/typechecker/ConstantFolder.java68
-rw-r--r--sources/scalac/typechecker/RefCheck.java2
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);
}
}