summaryrefslogtreecommitdiff
path: root/sources/scalac
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2003-08-21 09:44:58 +0000
committerMartin Odersky <odersky@gmail.com>2003-08-21 09:44:58 +0000
commit8341c5c36e88000e24bfd26d62c98805fc96fdcf (patch)
treee79189602238f756f686bf7805d91289cbe22d2c /sources/scalac
parentda5c361c7af30fc25f542bad8e12f3fceefc144d (diff)
downloadscala-8341c5c36e88000e24bfd26d62c98805fc96fdcf.tar.gz
scala-8341c5c36e88000e24bfd26d62c98805fc96fdcf.tar.bz2
scala-8341c5c36e88000e24bfd26d62c98805fc96fdcf.zip
*** empty log message ***
Diffstat (limited to 'sources/scalac')
-rw-r--r--sources/scalac/ast/TreeInfo.java15
-rw-r--r--sources/scalac/ast/parser/Parser.java30
-rw-r--r--sources/scalac/symtab/Scope.java2
-rw-r--r--sources/scalac/symtab/Symbol.java8
-rw-r--r--sources/scalac/symtab/SymbolCloner.java5
-rw-r--r--sources/scalac/symtab/classfile/Pickle.java7
-rw-r--r--sources/scalac/symtab/classfile/UnPickle.java2
-rw-r--r--sources/scalac/transformer/AddInterfacesPhase.java2
-rw-r--r--sources/scalac/transformer/LambdaLift.java5
-rw-r--r--sources/scalac/typechecker/Analyzer.java43
-rw-r--r--sources/scalac/typechecker/Context.java4
11 files changed, 77 insertions, 46 deletions
diff --git a/sources/scalac/ast/TreeInfo.java b/sources/scalac/ast/TreeInfo.java
index fc12935250..19b2341f44 100644
--- a/sources/scalac/ast/TreeInfo.java
+++ b/sources/scalac/ast/TreeInfo.java
@@ -127,6 +127,21 @@ public class TreeInfo {
}
}
+ /** Is tree a self constructor call?
+ */
+ public static boolean isSelfConstrCall(Tree tree) {
+ switch (tree) {
+ case Ident(Name name):
+ return name == Names.CONSTRUCTOR;
+ case TypeApply(Tree constr, _):
+ return isSelfConstrCall(constr);
+ case Apply(Tree constr, _):
+ return isSelfConstrCall(constr);
+ default:
+ return false;
+ }
+ }
+
/** Is tree a variable pattern
*/
public static boolean isVarPattern(Tree pat) {
diff --git a/sources/scalac/ast/parser/Parser.java b/sources/scalac/ast/parser/Parser.java
index 3bcb1c4045..af165b22ea 100644
--- a/sources/scalac/ast/parser/Parser.java
+++ b/sources/scalac/ast/parser/Parser.java
@@ -284,20 +284,24 @@ public class Parser implements Tokens {
//where
Tree makeFor1(int pos, Name name, Tree pat, Tree rhs, Tree body) {
- Tree cont;
+ return make.Apply(
+ pos, make.Select(pos, rhs, name),
+ new Tree[]{makeForCont(pos, pat, body)});
+ }
+ Tree makeForCont(int pos, Tree pat, Tree body) {
switch (pat) {
case Ident(Name name1):
- cont = make.Function(pos,
- new Tree.ValDef[]{
- (ValDef)
- make.ValDef(pat.pos, Modifiers.PARAM, name1, Tree.Empty, Tree.Empty)},
- body);
- break;
- default:
- cont = make.Visitor(pos, new Tree.CaseDef[]{
- (CaseDef)make.CaseDef(pos, pat, Tree.Empty, body)});
+ if (name1.isVariable())
+ return make.Function(
+ pos,
+ new Tree.ValDef[]{
+ (ValDef) make.ValDef(
+ pat.pos, Modifiers.PARAM,
+ name1, Tree.Empty, Tree.Empty)},
+ body);
}
- return make.Apply(pos, make.Select(pos, rhs, name), new Tree[]{cont});
+ return make.Visitor(pos, new Tree.CaseDef[]{
+ (CaseDef)make.CaseDef(pos, pat, Tree.Empty, body)});
}
Tree makeTry(int pos, Tree body, Tree catcher, Tree finalizer) {
@@ -433,7 +437,7 @@ public class Parser implements Tokens {
switch (fn) {
case This(TypeNames.EMPTY):
return make.Apply(
- t.pos, make.Ident(t.pos, Names.this_.toTypeName()), args);
+ t.pos, make.Ident(t.pos, Names.CONSTRUCTOR), args);
}
}
return syntaxError(t.pos, "class constructor expected", false);
@@ -1729,7 +1733,7 @@ public class Parser implements Tokens {
ValDef[][] vparams = new ValDef[][]{paramClause()};
accept(EQUALS);
return make.DefDef(
- pos, mods, Names.this_.toTypeName(),
+ pos, mods, Names.CONSTRUCTOR,
Tree.AbsTypeDef_EMPTY_ARRAY, vparams, Tree.Empty,
convertToSelfConstr(expr()));
} else {
diff --git a/sources/scalac/symtab/Scope.java b/sources/scalac/symtab/Scope.java
index c9daf10c5a..d0a2bf5b9b 100644
--- a/sources/scalac/symtab/Scope.java
+++ b/sources/scalac/symtab/Scope.java
@@ -189,7 +189,7 @@ public class Scope {
/** enter a symbol
*/
public Scope enter(Symbol sym) {
- assert !sym.isConstructor();
+ // assert !sym.isConstructor();
return enter(new Entry(sym, this));
}
diff --git a/sources/scalac/symtab/Symbol.java b/sources/scalac/symtab/Symbol.java
index 00161b7745..a98e44844d 100644
--- a/sources/scalac/symtab/Symbol.java
+++ b/sources/scalac/symtab/Symbol.java
@@ -60,8 +60,6 @@ public abstract class Symbol implements Modifiers, Kinds {
/** Generic symbol constructor */
public Symbol(int kind, int pos, Name name, Symbol owner, int flags) {
- assert (!isTerm() || !name.isTypeName()) && (!isType() || name.isTypeName());
-
this.kind = kind;
this.pos = pos;
this.name = name;
@@ -1023,6 +1021,7 @@ public class TermSymbol extends Symbol {
/** Constructor */
public TermSymbol(int pos, Name name, Symbol owner, int flags) {
super(VAL, pos, name, owner, flags);
+ assert !name.isTypeName() : this;
}
public static TermSymbol define(
@@ -1039,7 +1038,7 @@ public class TermSymbol extends Symbol {
public static TermSymbol newConstructor(Symbol clazz, int flags) {
TermSymbol sym = new TermSymbol(
- clazz.pos, clazz.name, clazz.owner(), flags | FINAL);
+ clazz.pos, Names.CONSTRUCTOR, clazz.owner(), flags | FINAL);
sym.clazz = clazz;
return sym;
}
@@ -1098,7 +1097,7 @@ public class TermSymbol extends Symbol {
/** Is this symbol a constructor? */
public boolean isConstructor() {
- return name.isTypeName();
+ return name == Names.CONSTRUCTOR;
}
/** Return a fresh symbol with the same fields as this one.
@@ -1155,6 +1154,7 @@ public abstract class TypeSymbol extends Symbol {
/** Constructor */
public TypeSymbol(int kind, int pos, Name name, Symbol owner, int flags) {
super(kind, pos, name, owner, flags);
+ assert name.isTypeName() : this;
if (kind != TYPE)
this.constructor = TermSymbol.newConstructor(this, flags & ~MODUL);
}
diff --git a/sources/scalac/symtab/SymbolCloner.java b/sources/scalac/symtab/SymbolCloner.java
index c75958be40..8863cf24ff 100644
--- a/sources/scalac/symtab/SymbolCloner.java
+++ b/sources/scalac/symtab/SymbolCloner.java
@@ -85,7 +85,10 @@ public class SymbolCloner {
assert !clones.containsKey(symbol) :
Debug.show(symbol) + " -> " + Debug.show(clones.get(symbol));
Symbol clone = symbol.cloneSymbol(getOwnerFor(symbol));
- if (rename) clone.name = renamer.newName(symbol.name);
+ if (rename) {
+ assert !symbol.isConstructor(): symbol;
+ clone.name = renamer.newName(symbol.name);
+ }
clones.put(symbol, clone);
return clone;
}
diff --git a/sources/scalac/symtab/classfile/Pickle.java b/sources/scalac/symtab/classfile/Pickle.java
index 58b2888d79..8cf0efd2de 100644
--- a/sources/scalac/symtab/classfile/Pickle.java
+++ b/sources/scalac/symtab/classfile/Pickle.java
@@ -80,8 +80,10 @@ public class Pickle implements Kinds, Modifiers, EntryTags {
*/
private boolean isLocal(Symbol sym) {
return
- sym.name.toTermName() == rootname &&
- sym.owner() == rootowner ||
+ sym.name.toTermName() == rootname && sym.owner() == rootowner
+ ||
+ sym.isConstructor() && isLocal(sym.primaryConstructorClass())
+ ||
(sym.kind != NONE && isLocal(sym.owner()));
}
@@ -333,6 +335,7 @@ public class Pickle implements Kinds, Modifiers, EntryTags {
} else {
writeByte(EXTref);
writeByte(0); // space for length
+ assert !sym.isConstructor() : sym;
writeRef(sym.name);
}
if (sym.owner() != Global.instance.definitions.ROOT_CLASS)
diff --git a/sources/scalac/symtab/classfile/UnPickle.java b/sources/scalac/symtab/classfile/UnPickle.java
index 4e2eb566fb..2e333e5cd2 100644
--- a/sources/scalac/symtab/classfile/UnPickle.java
+++ b/sources/scalac/symtab/classfile/UnPickle.java
@@ -264,7 +264,7 @@ public class UnPickle implements Kinds, Modifiers, EntryTags {
case VALsym:
if (bp < end) {
Symbol tsym = readSymbolRef();
- if (name.isTypeName()) {
+ if (name == Names.CONSTRUCTOR) {
entries[n] = sym = tsym.primaryConstructor();
sym.flags = flags;
} else {
diff --git a/sources/scalac/transformer/AddInterfacesPhase.java b/sources/scalac/transformer/AddInterfacesPhase.java
index 4df6c4bac7..c012f403c9 100644
--- a/sources/scalac/transformer/AddInterfacesPhase.java
+++ b/sources/scalac/transformer/AddInterfacesPhase.java
@@ -209,7 +209,7 @@ public class AddInterfacesPhase extends Phase {
Symbol ifaceConstrSym = ifaceSym.primaryConstructor();
Symbol classConstrSym = classSym.primaryConstructor();
- classConstrSym.name = className(ifaceConstrSym.name);
+ // classConstrSym.name = className(ifaceConstrSym.name);
Scope ifaceOwnerMembers = ifaceSym.owner().members();
ifaceOwnerMembers.enter(classSym);
diff --git a/sources/scalac/transformer/LambdaLift.java b/sources/scalac/transformer/LambdaLift.java
index 8651abb0c7..9384055c77 100644
--- a/sources/scalac/transformer/LambdaLift.java
+++ b/sources/scalac/transformer/LambdaLift.java
@@ -171,10 +171,7 @@ public class LambdaLift extends OwnerTransformer
* If symbol is a class assign same name to its primary constructor.
*/
private void makeUnique(Symbol sym) {
- Name newname = global.freshNameCreator.newName(sym.name);
- sym.name = newname;
- if (sym.kind == CLASS)
- sym.primaryConstructor().name = newname.toTypeName();
+ sym.name = global.freshNameCreator.newName(sym.name);
}
private Type.Map traverseTypeMap = new Type.Map() {
diff --git a/sources/scalac/typechecker/Analyzer.java b/sources/scalac/typechecker/Analyzer.java
index 7aeed9432d..da68b474b7 100644
--- a/sources/scalac/typechecker/Analyzer.java
+++ b/sources/scalac/typechecker/Analyzer.java
@@ -6,16 +6,12 @@
// $Id$
-// todo: (0) propagate target type in cast.
// todo: eliminate Typed nodes.
// todo: use SELECTOR flag to avoid access methods for privates
// todo: use mangled name or drop.
// todo: emit warnings for unchecked.
// todo: synchronize on module instantiation.
-// todo: implement EQ
-// todo: for (Tuplen(...) <- ...)
// todo: empty package
-// todo: this for package?
package scalac.typechecker;
@@ -737,7 +733,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
case DefDef(int mods, Name name, _, _, _, _):
Symbol sym;
- if (name == Names.this_.toTypeName()) {
+ if (name == Names.CONSTRUCTOR) {
Symbol clazz = context.enclClass.owner;
if (!(context.tree instanceof Template) ||
clazz.isModuleClass() ||
@@ -746,7 +742,6 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
clazz.isPackage()) {
error(tree.pos, "constructor definition not allowed here");
}
- ((DefDef) tree).name = clazz.name;
sym = context.enclClass.owner.addConstructor();
} else {
sym = TermSymbol.define(tree.pos, name, owner, mods, context.scope);
@@ -987,7 +982,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
Symbol[] tparamSyms;
Symbol[][] vparamSyms;
Type restype;
- if (name.isTypeName()) {
+ if (name == Names.CONSTRUCTOR) {
Context prevContext = context;
Symbol clazz = context.enclClass.owner;
context = context.enclClass.outer.outer;
@@ -1804,8 +1799,8 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
case DefDef(_, Name name, Tree.AbsTypeDef[] tparams, Tree.ValDef[][] vparams, Tree tpe, Tree rhs):
Context prevContext = context;
- if (name.isTypeName()) {
- Symbol clazz = context.enclClass.owner;
+ Symbol enclClass = context.enclClass.owner;
+ if (name == Names.CONSTRUCTOR) {
context = context.enclClass.outer.outer;
}
pushContext(tree, sym, new Scope(context.scope));
@@ -1816,8 +1811,10 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
? gen.mkType(tree.pos, sym.type().resultType())
: transform(tpe, TYPEmode);
Tree rhs1 = rhs;
- if (name.isTypeName())
+ if (name == Names.CONSTRUCTOR) {
+ context.constructorClass = enclClass;
rhs1 = transform(rhs, CONSTRmode, tpe1.type);
+ }
else if (rhs != Tree.Empty)
rhs1 = transform(rhs, EXPRmode, tpe1.type);
context = prevContext;
@@ -2106,6 +2103,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
mode = mode & ~SEQUENCEmode;
Tree fn1;
int argMode;
+ boolean selfcc = false;
//todo: Should we pass in both cases a methodtype with
// AnyType's for args as a prototype?
if ((mode & EXPRmode) != 0) {
@@ -2128,8 +2126,8 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
case TypeRef(Type pre, Symbol c, Type[] argtypes):
if (c.kind == CLASS) {
c.initialize();
- Tree fn0 = fn1;
Symbol constr = c.allConstructors();
+ Tree fn0 = fn1;
fn1 = gen.mkRef(fn1.pos, pre, constr);
switch (fn1) {
case Select(Tree fn1qual, _):
@@ -2151,6 +2149,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
tsym.typeParams(), fn1.type);
}
//System.out.println(TreeInfo.methSymbol(fn1) + ":" + tp + " --> " + fn1.type + " of " + fn1);//DEBUG
+ selfcc = TreeInfo.isSelfConstrCall(fn0);
} else {
error(tree.pos,
tsym + " is not a class; cannot be instantiated");
@@ -2236,6 +2235,16 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
}
}
+ // check that self constructors go backwards.
+ if (selfcc) {
+ Symbol constr = TreeInfo.methSymbol(fn1);
+ if (constr != null && constr.kind == VAL &&
+ !(constr.type() instanceof Type.OverloadedType) &&
+ constr.pos > tree.pos)
+ error(tree.pos,
+ "illegal forward reference to self constructor");
+ }
+
switch (fn1.type) {
case PolyType(Symbol[] tparams, Type restp):
// if method is polymorphic,
@@ -2307,13 +2316,11 @@ public class Analyzer extends Transformer implements Modifiers, Kinds {
tree, adapt(qual1, qualmode, Type.AnyType), name);
case Ident(Name name):
- if (name == Names.this_.toTypeName()) {
- Tree tree1 = transform(make.Ident(tree.pos, pt.symbol().name));
- Symbol constr = tree1.symbol();
- if (constr != null && constr.kind == VAL && constr.pos > tree.pos)
- error(tree.pos,
- "illegal forward reference to self constructor");
- return tree1;
+ if (name == Names.CONSTRUCTOR) {
+ assert (mode & CONSTRmode) != 0 : tree;
+ return gen.Ident(tree.pos, context.constructorClass);
+ /*
+ */
} else if (((mode & (PATTERNmode | FUNmode)) == PATTERNmode) &&
name.isVariable()) {
diff --git a/sources/scalac/typechecker/Context.java b/sources/scalac/typechecker/Context.java
index 090f0e58fb..61bf0a8299 100644
--- a/sources/scalac/typechecker/Context.java
+++ b/sources/scalac/typechecker/Context.java
@@ -19,7 +19,8 @@ public class Context {
Context outer; // The next outer context
Context enclClass = this; // The next outer context whose tree
// is a class template
- int variance; // Variance relative to eclosing class.
+ int variance; // Variance relative to enclosing class.
+ Symbol constructorClass; // Class for auxiliary constructor
public Context() {}
@@ -36,6 +37,7 @@ public class Context {
tree instanceof Tree.CompoundType) this.enclClass = this;
else this.enclClass = outer.enclClass;
this.variance = outer.variance;
+ this.constructorClass = outer.constructorClass;
this.outer = outer;
}