diff options
author | Martin Odersky <odersky@gmail.com> | 2003-08-21 09:44:58 +0000 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2003-08-21 09:44:58 +0000 |
commit | 8341c5c36e88000e24bfd26d62c98805fc96fdcf (patch) | |
tree | e79189602238f756f686bf7805d91289cbe22d2c /sources | |
parent | da5c361c7af30fc25f542bad8e12f3fceefc144d (diff) | |
download | scala-8341c5c36e88000e24bfd26d62c98805fc96fdcf.tar.gz scala-8341c5c36e88000e24bfd26d62c98805fc96fdcf.tar.bz2 scala-8341c5c36e88000e24bfd26d62c98805fc96fdcf.zip |
*** empty log message ***
Diffstat (limited to 'sources')
-rw-r--r-- | sources/scalac/ast/TreeInfo.java | 15 | ||||
-rw-r--r-- | sources/scalac/ast/parser/Parser.java | 30 | ||||
-rw-r--r-- | sources/scalac/symtab/Scope.java | 2 | ||||
-rw-r--r-- | sources/scalac/symtab/Symbol.java | 8 | ||||
-rw-r--r-- | sources/scalac/symtab/SymbolCloner.java | 5 | ||||
-rw-r--r-- | sources/scalac/symtab/classfile/Pickle.java | 7 | ||||
-rw-r--r-- | sources/scalac/symtab/classfile/UnPickle.java | 2 | ||||
-rw-r--r-- | sources/scalac/transformer/AddInterfacesPhase.java | 2 | ||||
-rw-r--r-- | sources/scalac/transformer/LambdaLift.java | 5 | ||||
-rw-r--r-- | sources/scalac/typechecker/Analyzer.java | 43 | ||||
-rw-r--r-- | sources/scalac/typechecker/Context.java | 4 |
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; } |