summaryrefslogtreecommitdiff
path: root/sources/scalac
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2003-09-25 10:11:17 +0000
committerMartin Odersky <odersky@gmail.com>2003-09-25 10:11:17 +0000
commitd564a5473c6d901f85a2bc82c4589da5b800011b (patch)
tree731e1a6684ac2748b6e2ecabb9109c6c39284657 /sources/scalac
parent423ecdde9b683f8b32624e5e08930c7f461dca4e (diff)
downloadscala-d564a5473c6d901f85a2bc82c4589da5b800011b.tar.gz
scala-d564a5473c6d901f85a2bc82c4589da5b800011b.tar.bz2
scala-d564a5473c6d901f85a2bc82c4589da5b800011b.zip
*** empty log message ***
Diffstat (limited to 'sources/scalac')
-rw-r--r--sources/scalac/ast/TreeGen.java60
-rw-r--r--sources/scalac/ast/TreeList.java2
-rw-r--r--sources/scalac/transformer/LambdaLift.java36
-rw-r--r--sources/scalac/transformer/LambdaLiftPhase.java2
-rw-r--r--sources/scalac/transformer/OwnerTransformer.java4
-rw-r--r--sources/scalac/transformer/matching/PatternMatcher.java12
6 files changed, 84 insertions, 32 deletions
diff --git a/sources/scalac/ast/TreeGen.java b/sources/scalac/ast/TreeGen.java
index dc40fa9b4a..b0977665d2 100644
--- a/sources/scalac/ast/TreeGen.java
+++ b/sources/scalac/ast/TreeGen.java
@@ -11,7 +11,9 @@ package scalac.ast;
import scalac.Global;
import scalac.ast.Tree.*;
import scalac.symtab.*;
+import scalac.typechecker.Infer;
import scalac.util.*;
+import scalac.ApplicationError;
/**
* This class provides method to build attributed trees.
@@ -33,8 +35,9 @@ public class TreeGen implements Kinds, Modifiers, TypeTags {
/** The tree factory */
private final TreeFactory make;
- //########################################################################
- // Public Constructors
+ /** the type inferencer
+ */
+ final Infer infer;
/** Initializes this instance. */
public TreeGen(Global global) {
@@ -46,6 +49,7 @@ public class TreeGen implements Kinds, Modifiers, TypeTags {
this.global = global;
this.definitions = global.definitions;
this.make = make;
+ this.infer = new Infer(global, this, make);
}
//########################################################################
@@ -398,17 +402,23 @@ public class TreeGen implements Kinds, Modifiers, TypeTags {
/** Builds a TypeApply node with given function and arguments. */
public TypeApply TypeApply(int pos, Tree fn, Tree[] targs) {
- switch (fn.type) {
- case PolyType(Symbol[] tparams, Type result):
- TypeApply tree = make.TypeApply(pos, fn, targs);
- assert tparams.length == targs.length: tree;
- global.nextPhase();
- tree.setType(result.subst(tparams, Tree.typeOf(targs)));
- global.prevPhase();
- return tree;
- default:
- throw Debug.abort("illegal case", fn.type);
- }
+ try {
+ switch (fn.type) {
+ case Type.OverloadedType(Symbol[] alts, Type[] alttypes):
+ global.nextPhase();
+ infer.polyAlternative(fn, alts, alttypes, targs.length);
+ global.prevPhase();
+ }
+ switch (fn.type) {
+ case Type.PolyType(Symbol[] tparams, Type restpe):
+ global.nextPhase();
+ restpe = restpe.subst(tparams, Tree.typeOf(targs));
+ global.prevPhase();
+ return (TypeApply)make.TypeApply(pos, fn, targs).setType(restpe);
+ }
+ } catch (Type.Error ex) {
+ }
+ throw new ApplicationError("poly type required", fn.type);
}
public TypeApply TypeApply(Tree fn, Tree[] targs) {
return TypeApply(fn.pos, fn, targs);
@@ -416,15 +426,21 @@ public class TreeGen implements Kinds, Modifiers, TypeTags {
/** Builds an Apply node with given function and arguments. */
public Apply Apply(int pos, Tree fn, Tree[] vargs) {
- switch (fn.type) {
- case Type.MethodType(Symbol[] vparams, Type result):
- Apply tree = make.Apply(pos, fn, vargs);
- // !!! assert vparams.length == vargs.length: tree + " --- " + Debug.show(vparams) + " --- " + Debug.show(vargs);
- tree.setType(result);
- return tree;
- default:
- throw Debug.abort("illegal case", fn);
- }
+ try {
+ switch (fn.type) {
+ case Type.OverloadedType(Symbol[] alts, Type[] alttypes):
+ global.nextPhase();
+ infer.methodAlternative(fn, alts, alttypes,
+ Tree.typeOf(vargs), Type.AnyType);
+ global.prevPhase();
+ }
+ switch (fn.type) {
+ case Type.MethodType(Symbol[] vparams, Type restpe):
+ return (Apply)make.Apply(pos, fn, vargs).setType(restpe);
+ }
+ } catch (Type.Error ex) {
+ }
+ throw new ApplicationError("method type required", fn.type);
}
public Apply Apply(Tree fn, Tree[] vargs) {
return Apply(fn.pos, fn, vargs);
diff --git a/sources/scalac/ast/TreeList.java b/sources/scalac/ast/TreeList.java
index 876b711cc9..3557c20e9c 100644
--- a/sources/scalac/ast/TreeList.java
+++ b/sources/scalac/ast/TreeList.java
@@ -28,7 +28,7 @@ public final class TreeList {
public void append(Tree tree) {
if (len == trees.length) {
- Tree[] ts = new Tree[len * 2];
+ Tree[] ts = new Tree[len == 0 ? 4 : len * 2];
System.arraycopy(trees, 0, ts, 0, len);
trees = ts;
}
diff --git a/sources/scalac/transformer/LambdaLift.java b/sources/scalac/transformer/LambdaLift.java
index c12b7c8a79..209be84626 100644
--- a/sources/scalac/transformer/LambdaLift.java
+++ b/sources/scalac/transformer/LambdaLift.java
@@ -63,7 +63,30 @@ public class LambdaLift extends OwnerTransformer
return sym.kind == CLASS ? sym.primaryConstructor() : sym;
}
- /** `asFunction' applied to the next enclosing function or class owner.
+ /** Is symbol local relative to owner?
+ * Primary constructor parameters are local iff owner (contained in)
+ * the primary constructor.
+ */
+ static boolean isLocal(Symbol sym, Symbol owner) {
+ if ((sym.flags & PARAM) != 0 &&
+ sym.owner().isPrimaryConstructor() &&
+ sym.owner().constructorClass().kind == CLASS &&
+ !((owner.flags & PARAM) != 0 && owner.owner() == sym)) {
+ Symbol encl = sym.owner().owner();
+ Symbol clazz = sym.owner().constructorClass();
+ //System.out.println("isLocal " + sym + " " + encl + " " + clazz + " " + owner);//DEBUG
+ while (owner != encl &&
+ owner.kind != NONE &&
+ owner != clazz) {
+ owner = owner.owner();
+ //System.out.println(":" + owner);//DEBUG
+ }
+ return owner != clazz;
+ }
+ return sym.isLocal();
+ }
+
+ /** Propagate free fariables from all called functions. /** `asFunction' applied to the next enclosing function or class owner.
*/
static Symbol enclFun(Symbol owner) {
Symbol sym = owner;
@@ -178,9 +201,12 @@ public class LambdaLift extends OwnerTransformer
private Type.Map traverseTypeMap = new Type.Map() {
public Type apply(Type tp) {
+ if (global.debug) global.log("traverse " + tp);//debug
switch (tp) {
case TypeRef(ThisType(_), Symbol sym, Type[] targs):
- if (sym.isLocal() && sym.kind == TYPE && !excluded.contains(sym))
+ if (isLocal(sym, currentOwner) &&
+ sym.kind == TYPE &&
+ !excluded.contains(sym))
markFree(sym, currentOwner);
break;
case PolyType(Symbol[] tparams, Type restp):
@@ -196,7 +222,7 @@ public class LambdaLift extends OwnerTransformer
};
public Tree transform(Tree tree) {
- //if (global.debug) global.debugPrinter.print("free ").print(tree).println().end();//DEBUG
+ if (global.debug) global.log("free " + tree);//debug
assert tree.type != null : tree;
traverseTypeMap.apply(tree.type.widen());
Symbol sym = tree.symbol();
@@ -227,7 +253,7 @@ public class LambdaLift extends OwnerTransformer
transform(rhs, currentOwner));
case Ident(_):
- if (sym.isLocal()) {
+ if (isLocal(sym, currentOwner)) {
if (sym.isMethod()) {
Symbol f = enclFun(currentOwner);
if (f.name.length() > 0) // it is not a template function {
@@ -435,7 +461,7 @@ public class LambdaLift extends OwnerTransformer
case Ident(Name name):
Symbol sym = tree.symbol();
- if (sym.isLocal() &&
+ if (isLocal(sym, currentOwner) &&
(sym.kind == TYPE || (sym.kind == VAL && !sym.isMethod()))) {
sym = descr.proxy(sym, currentOwner);
}
diff --git a/sources/scalac/transformer/LambdaLiftPhase.java b/sources/scalac/transformer/LambdaLiftPhase.java
index efe623a727..eb3bb40d04 100644
--- a/sources/scalac/transformer/LambdaLiftPhase.java
+++ b/sources/scalac/transformer/LambdaLiftPhase.java
@@ -96,7 +96,7 @@ public class LambdaLiftPhase extends Phase implements Kinds, Modifiers {
}
return Type.TypeRef(pre, sym, targs1);
}
- } else if (sym.isLocal()) {
+ } else if (LambdaLift.isLocal(sym, owner)) {
assert targs.length == 0;
return proxy(sym, owner).type();
}
diff --git a/sources/scalac/transformer/OwnerTransformer.java b/sources/scalac/transformer/OwnerTransformer.java
index bb7ab098c7..7a6663f613 100644
--- a/sources/scalac/transformer/OwnerTransformer.java
+++ b/sources/scalac/transformer/OwnerTransformer.java
@@ -101,14 +101,14 @@ public class OwnerTransformer extends Transformer {
tree, symbol,
transform(tparams, symbol.primaryConstructor()),
transform(vparams, symbol.primaryConstructor()),
- transform(tpe),
+ transform(tpe, symbol),
transform(impl, symbol));
case ModuleDef(_, _, Tree tpe, Template impl):
Symbol symbol = tree.symbol();
return copy.ModuleDef(
tree, symbol,
- transform(tpe),
+ transform(tpe, symbol),
transform(impl, symbol.moduleClass()));
case DefDef(_, _, AbsTypeDef[] tparams, ValDef[][] vparams, Tree tpe, Tree rhs):
diff --git a/sources/scalac/transformer/matching/PatternMatcher.java b/sources/scalac/transformer/matching/PatternMatcher.java
index 2d644ab11b..ecdcc938cf 100644
--- a/sources/scalac/transformer/matching/PatternMatcher.java
+++ b/sources/scalac/transformer/matching/PatternMatcher.java
@@ -441,7 +441,16 @@ public class PatternMatcher extends PatternTool {
if (curHeader == null) {
assert index >= 0 : casted;
if (casted.pos == Position.FIRSTPOS) {
- Symbol atSym = casted.type().lookup(APPLY_N);
+ //Symbol atSym = casted.type().lookup(APPLY_N);
+ Tree t =
+ gen.Apply(
+ gen.Select(
+ gen.Ident(pat.pos, casted),
+ casted.lookup(APPLY_N)),
+ new Tree[]{gen.mkIntLit(pat.pos, index)});
+ Type seqType = t.type;
+/*
+ atSym);
Type seqType = casted.type().baseType(defs.SEQ_CLASS).typeArgs()[0];
Tree t = make.Select(
pat.pos,
@@ -468,6 +477,7 @@ public class PatternMatcher extends PatternTool {
.setType(defs.INT_TYPE)
}).setType(seqType);
}
+*/
target.and = curHeader = mk.Header(pat.pos, seqType, t);
} else {
Symbol ts = ((ClassSymbol) casted.type().symbol())