From 03449ed20a3cca9e8d974c7efeff6b4e01ecb66d Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Thu, 31 Jul 2003 09:57:59 +0000 Subject: *** empty log message *** --- sources/scalac/symtab/Definitions.java | 6 +- sources/scalac/symtab/EntryTags.java | 76 ++++--- sources/scalac/symtab/Scope.java | 5 +- sources/scalac/symtab/Symbol.java | 222 +++++++++++++-------- sources/scalac/symtab/Type.java | 21 +- .../scalac/symtab/classfile/AttributeParser.java | 61 +++--- .../scalac/symtab/classfile/ClassfileParser.java | 36 ++-- sources/scalac/symtab/classfile/PackageParser.java | 12 +- sources/scalac/symtab/classfile/Pickle.java | 78 ++++---- sources/scalac/symtab/classfile/UnPickle.java | 106 +++++----- 10 files changed, 336 insertions(+), 287 deletions(-) (limited to 'sources/scalac/symtab') diff --git a/sources/scalac/symtab/Definitions.java b/sources/scalac/symtab/Definitions.java index 6760dbaa28..648e253380 100644 --- a/sources/scalac/symtab/Definitions.java +++ b/sources/scalac/symtab/Definitions.java @@ -205,7 +205,7 @@ public class Definitions { SCALA_CLASS.members().enter(ANY_CLASS); ANY_TYPE = ANY_CLASS.typeConstructor(); ANY_CLASS.setInfo(Type.compoundType(Type.EMPTY_ARRAY, new Scope(), ANY_CLASS)); - ANY_CLASS.constructor().setInfo( + ANY_CLASS.primaryConstructor().setInfo( Type.MethodType(Symbol.EMPTY_ARRAY, ANY_TYPE)); // the java.lang.OBJECT class @@ -238,7 +238,7 @@ public class Definitions { SCALA_CLASS.members().enter(ALL_CLASS); ALL_TYPE = ALL_CLASS.typeConstructor(); ALL_CLASS.setInfo(Type.compoundType(new Type[]{ANY_TYPE}, new Scope(), ALL_CLASS)); - ALL_CLASS.constructor().setInfo(Type.MethodType(Symbol.EMPTY_ARRAY, ALL_TYPE)); + ALL_CLASS.primaryConstructor().setInfo(Type.MethodType(Symbol.EMPTY_ARRAY, ALL_TYPE)); // the scala.ALLREF class ALLREF_CLASS = new ClassSymbol( @@ -246,7 +246,7 @@ public class Definitions { SCALA_CLASS.members().enter(ALLREF_CLASS); ALLREF_TYPE = ALLREF_CLASS.typeConstructor(); ALLREF_CLASS.setInfo(Type.compoundType(new Type[]{ANYREF_TYPE}, new Scope(), ALLREF_CLASS)); - ALLREF_CLASS.constructor().setInfo(Type.MethodType(Symbol.EMPTY_ARRAY, ALLREF_TYPE)); + ALLREF_CLASS.primaryConstructor().setInfo(Type.MethodType(Symbol.EMPTY_ARRAY, ALLREF_TYPE)); // the primitive types DOUBLE_CLASS = getClass(Names.scala_Double); diff --git a/sources/scalac/symtab/EntryTags.java b/sources/scalac/symtab/EntryTags.java index b8ae7c2d7a..ed1d089641 100644 --- a/sources/scalac/symtab/EntryTags.java +++ b/sources/scalac/symtab/EntryTags.java @@ -14,24 +14,23 @@ public interface EntryTags { * Symbol table attribute format: * Symtab = nentries_Nat {Entry} * Entry = 1 TERMNAME len_Nat NameInfo - * | 2 CONSTRNAME len_Nat NameInfo - * | 3 TYPENAME len_Nat NameInfo - * | 4 NONEsym len_Nat - * | 5 TYPEsym len_Nat SymbolInfo lobound_Ref - * | 6 ALIASsym len_Nat SymbolInfo - * | 7 CLASSsym len_Nat SymbolInfo thistype_Ref constrsym_Ref - * | 8 VALsym len_Nat SymbolInfo [classsym_Ref] - * | 9 EXTsym len_Nat name_Ref [owner_Ref] - * | 10 EXTMODCLASSsym len_Nat name_Ref [owner_Ref] - * | 11 NOtpe len_Nat - * | 12 THIStpe len_Nat sym_Ref - * | 13 SINGLEtpe len_Nat type_Ref sym_Ref - * | 14 TYPEREFtpe len_Nat type_Ref sym_Ref {targ_Ref} - * | 15 COMPOUNDtpe len_Nat classsym_Ref {tpe_Ref} - * | 16 METHODtpe len_Nat tpe_Ref {tpe_Ref} - * | 17 POLYTtpe len_Nat tpe_Ref {sym_Ref} - * | 18 OVERLOADEDtpe len_Nat {sym_Ref} {tpe_Ref} - * | 21 FLAGGEDtype len_Nat flags_Nat tpe_Ref + * | 2 TYPENAME len_Nat NameInfo + * | 3 NONEsym len_Nat + * | 4 TYPEsym len_Nat SymbolInfo lobound_Ref + * | 5 ALIASsym len_Nat SymbolInfo + * | 6 CLASSsym len_Nat SymbolInfo thistype_Ref constrsym_Ref + * | 7 VALsym len_Nat SymbolInfo [classsym_Ref] + * | 8 TERMref len_Nat name_Ref [owner_Ref] + * | 9 TYPEref len_Nat name_Ref [owner_Ref] + * | 10 NOtpe len_Nat + * | 11 THIStpe len_Nat sym_Ref + * | 12 SINGLEtpe len_Nat type_Ref sym_Ref + * | 13 TYPEREFtpe len_Nat type_Ref sym_Ref {targ_Ref} + * | 14 COMPOUNDtpe len_Nat classsym_Ref {tpe_Ref} + * | 15 METHODtpe len_Nat tpe_Ref {tpe_Ref} + * | 16 POLYTtpe len_Nat tpe_Ref {sym_Ref} + * | 17 OVERLOADEDtpe len_Nat {sym_Ref} {tpe_Ref} + * | 20 FLAGGEDtype len_Nat flags_Nat tpe_Ref * SymbolInfo = name_Ref owner_Ref flags_Nat info_Ref * NameInfo = * Ref = Nat @@ -40,27 +39,26 @@ public interface EntryTags { */ int TERMname = 1, - CONSTRname = 2, - TYPEname = 3, - NONEsym = 4, - TYPEsym = 5, - ALIASsym = 6, - CLASSsym = 7, - VALsym = 8, - EXTsym = 9, - EXTMODCLASSsym = 10, - NOtpe = 11, - THIStpe = 12, - SINGLEtpe = 13, - TYPEREFtpe = 14, - COMPOUNDtpe = 15, - METHODtpe = 16, - POLYtpe = 17, - OVERLOADEDtpe = 18, - UNBOXEDtpe = 19, - UNBOXEDARRAYtpe = 20, - FLAGGEDtpe = 21, - ERRORtpe = 22; + TYPEname = 2, + NONEsym = 3, + TYPEsym = 4, + ALIASsym = 5, + CLASSsym = 6, + VALsym = 7, + TERMref = 8, + TYPEref = 9, + NOtpe = 10, + THIStpe = 11, + SINGLEtpe = 12, + TYPEREFtpe = 13, + COMPOUNDtpe = 14, + METHODtpe = 15, + POLYtpe = 16, + OVERLOADEDtpe = 17, + UNBOXEDtpe = 18, + UNBOXEDARRAYtpe = 19, + FLAGGEDtpe = 20, + ERRORtpe = 21; int firstSymTag = NONEsym, lastSymTag = VALsym; int firstTypeTag = NOtpe, lastTypeTag = FLAGGEDtpe; diff --git a/sources/scalac/symtab/Scope.java b/sources/scalac/symtab/Scope.java index 477144cd3a..c9daf10c5a 100644 --- a/sources/scalac/symtab/Scope.java +++ b/sources/scalac/symtab/Scope.java @@ -79,7 +79,7 @@ public class Scope { */ public final Scope owner; - Entry(Symbol sym, Scope owner) { + public Entry(Symbol sym, Scope owner) { this.sym = sym; this.owner = owner; this.next = owner.elems; @@ -173,7 +173,7 @@ public class Scope { return s; } - private Scope enter(Entry e) { + public Scope enter(Entry e) { elems = e; elemsCache = null; if (hashtable != null) { @@ -189,6 +189,7 @@ public class Scope { /** enter a symbol */ public Scope enter(Symbol sym) { + assert !sym.isConstructor(); return enter(new Entry(sym, this)); } diff --git a/sources/scalac/symtab/Symbol.java b/sources/scalac/symtab/Symbol.java index 0044beeb2c..585bc5de95 100644 --- a/sources/scalac/symtab/Symbol.java +++ b/sources/scalac/symtab/Symbol.java @@ -119,7 +119,10 @@ public abstract class Symbol implements Modifiers, Kinds { assert symbol != Symbol.NONE; assert symbol != Symbol.ERROR; if (symbol.isModule()) setOwner(symbol.moduleClass(), owner); - if (symbol.isClass()) setOwner(symbol.constructor(), owner); + if (symbol.isClass()) { + Symbol[] alts = symbol.allConstructors().alternativeSymbols(); + for (int i = 0; i < alts.length; i++) setOwner(alts[i], owner); + } symbol.owner = owner; } @@ -132,19 +135,22 @@ public abstract class Symbol implements Modifiers, Kinds { public Symbol setInfo(Type info, int limit) { assert !isConstructor() || info instanceof Type.LazyType + || info == Type.NoType || info == Type.ErrorType || info instanceof Type.MethodType || info instanceof Type.OverloadedType || info instanceof Type.PolyType && ((Type.PolyType)info).result instanceof Type.MethodType : "illegal type for " + this + ": " + info; - if ((flags & (INITIALIZED | LOCKED)) != (INITIALIZED | LOCKED)) { + //if ((flags & (INITIALIZED | LOCKED)) != (INITIALIZED | LOCKED)) { if (infos == TypeIntervalList.EMPTY) { infos = new TypeIntervalList(TypeIntervalList.EMPTY); } infos.limit = limit; infos.info = info; - } + if (info instanceof Type.LazyType) flags &= ~INITIALIZED; + else flags |= INITIALIZED; + //} return this; } @@ -173,12 +179,14 @@ public abstract class Symbol implements Modifiers, Kinds { throw new ApplicationError("setLoBound inapplicable for " + this); } -// Symbol classification ---------------------------------------------------- - - public final boolean isDefined() { - return !(rawInfoAt(FIRST_ID) instanceof Type.LazyType); + /** Add an auxiliary constructor to class; return created symbol. + */ + public Symbol addConstructor() { + throw new ApplicationError("addConstructor inapplicable for " + this); } +// Symbol classification ---------------------------------------------------- + /** Does this symbol denote a type? */ public final boolean isType() { return kind == TYPE || kind == CLASS || kind == ALIAS; @@ -377,13 +385,13 @@ public abstract class Symbol implements Modifiers, Kinds { } /** Is this symbol a constructor? */ - public final boolean isConstructor() { - return name.isConstrName(); + public boolean isConstructor() { + return false; } /** Is this symbol the primary constructor of a type? */ public final boolean isPrimaryConstructor() { - return isConstructor() && this == primaryConstructorClass().constructor(); + return isConstructor() && this == primaryConstructorClass().primaryConstructor(); } public boolean isGenerated() { @@ -451,8 +459,13 @@ public abstract class Symbol implements Modifiers, Kinds { return EMPTY_ARRAY; } + /** Get all constructors of class */ + public Symbol allConstructors() { + return NONE; + } + /** Get primary constructor of class */ - public Symbol constructor() { + public Symbol primaryConstructor() { return NONE; } @@ -474,7 +487,7 @@ public abstract class Symbol implements Modifiers, Kinds { public Symbol classOwner() { Symbol owner = owner(); Symbol clazz = owner.primaryConstructorClass(); - if (clazz.constructor() == owner) return clazz; + if (clazz.primaryConstructor() == owner) return clazz; else return owner; } @@ -501,6 +514,19 @@ public abstract class Symbol implements Modifiers, Kinds { return this; } + /** Return first alternative if this has a (possibly lazy) + * overloaded type, otherwise symbol itself. + * Needed only in ClassSymbol.primaryConstructor() + */ + Symbol firstAlternative() { + if (infos.info instanceof Type.OverloadedType) + return infos.info.alternativeSymbols()[0]; + else if (infos.info instanceof LazyOverloadedType) + return ((LazyOverloadedType) infos.info).sym1.firstAlternative(); + else + return this; + } + /* If this is a module, return its class. * Otherwise return the symbol itself. */ @@ -508,6 +534,22 @@ public abstract class Symbol implements Modifiers, Kinds { return this; } + /** if type is a (possibly lazy) overloaded type, return its alternatves + * else return array consisting of symbol itself + */ + public Symbol[] alternativeSymbols() { + Symbol[] alts = type().alternativeSymbols(); + if (alts.length == 0) return new Symbol[]{this}; + else return alts; + } + + /** if type is a (possibly lazy) overloaded type, return its alternatves + * else return array consisting of type itself + */ + public Type[] alternativeTypes() { + return type().alternativeTypes(); + } + /** The symbol accessed by this accessor function. */ public Symbol accessed() { @@ -598,7 +640,7 @@ public abstract class Symbol implements Modifiers, Kinds { flags &= ~SNDTIME; } else { assert !(rawInfoAt(id) instanceof Type.LazyType) : this; - flags |= INITIALIZED; + //flags |= INITIALIZED; } //System.out.println("done: " + this.name);//DEBUG } @@ -624,8 +666,8 @@ public abstract class Symbol implements Modifiers, Kinds { /** get info at phase #id, without forcing lazy types. */ public Type rawInfoAt(int id) { - int nextid = infos.limit; assert infos != TypeIntervalList.EMPTY : this; + int nextid = infos.limit; if (nextid < id) { PhaseDescriptor curphase = Global.instance.currentPhase; do { @@ -868,59 +910,43 @@ public abstract class Symbol implements Modifiers, Kinds { /** A lazy type which, when forced computed the overloaded type * of symbols `sym1' and `sym2'. It also checks that this type is well-formed. */ - private static class LazyOverloadedType extends Type.LazyType { + public static class LazyOverloadedType extends Type.LazyType { Symbol sym1; Symbol sym2; LazyOverloadedType(Symbol sym1, Symbol sym2) { this.sym1 = sym1; this.sym2 = sym2; } - private Symbol[] alts(Symbol sym) { - if (sym == null) return Symbol.EMPTY_ARRAY; - switch (sym.type()) { - case OverloadedType(Symbol[] alts, _): return alts; - default: return new Symbol[]{sym}; - } - } - private Type[] alttypes(Symbol sym) { - if (sym == null) return Type.EMPTY_ARRAY; - switch (sym.type()) { - case OverloadedType(_, Type[] alttypes): return alttypes; - default: return new Type[]{sym.type()}; - } - } - public void complete(Symbol overloaded) { - if (sym1 != null) sym1.initialize(); - if (sym2 != null) sym2.initialize(); - Symbol[] alts1 = alts(sym1); - Symbol[] alts2 = alts(sym2); + public Symbol[] alternativeSymbols() { + Symbol[] alts1 = sym1.alternativeSymbols(); + Symbol[] alts2 = sym2.alternativeSymbols(); Symbol[] alts3 = new Symbol[alts1.length + alts2.length]; System.arraycopy(alts1, 0, alts3, 0, alts1.length); System.arraycopy(alts2, 0, alts3, alts1.length, alts2.length); + return alts3; + } + + public Type[] alternativeTypes() { + Type[] alts1 = sym1.alternativeTypes(); + Type[] alts2 = sym2.alternativeTypes(); + Type[] alts3 = new Type[alts1.length + alts2.length]; + System.arraycopy(alts1, 0, alts3, 0, alts1.length); + System.arraycopy(alts2, 0, alts3, alts1.length, alts2.length); + return alts3; + } - Type[] alttypes1 = alttypes(sym1); - Type[] alttypes2 = alttypes(sym2); - Type[] alttypes3 = new Type[alttypes1.length + alttypes2.length]; - System.arraycopy(alttypes1, 0, alttypes3, 0, alttypes1.length); - System.arraycopy(alttypes2, 0, alttypes3, alttypes1.length, alttypes2.length); - overloaded.setInfo(Type.OverloadedType(alts3, alttypes3)); + public void complete(Symbol overloaded) { + overloaded.setInfo( + Type.OverloadedType( + alternativeSymbols(), alternativeTypes())); } + public String toString() { return "LazyOverloadedType(" + sym1 + "," + sym2 + ")"; } } - /** All the alternatives of this symbol if it's overloaded, the - * symbol alone otherwise. - */ - public Symbol[] alternatives() { - switch (type()) { - case OverloadedType(Symbol[] alts, _): return alts; - default: return new Symbol[]{this}; - } - } - /** The symbol which is overridden by this symbol in base class `base' * `base' must be a superclass of this.owner(). */ @@ -985,8 +1011,7 @@ public class TermSymbol extends Symbol { public static TermSymbol newConstructor(Symbol clazz, int flags) { TermSymbol sym = new TermSymbol( - clazz.pos, clazz.name.toConstrName(), clazz.owner(), - flags | FINAL); + clazz.pos, clazz.name, clazz.owner(), flags | FINAL); sym.clazz = clazz; return sym; } @@ -1008,7 +1033,7 @@ public class TermSymbol extends Symbol { int flags) { ClassSymbol clazz = new ClassSymbol( pos, name.toTypeName(), owner, flags | MODUL | FINAL); - clazz.constructor().setInfo( + clazz.primaryConstructor().setInfo( Type.MethodType(Symbol.EMPTY_ARRAY, clazz.typeConstructor())); return newModule(pos, name, owner, flags, clazz); @@ -1044,6 +1069,11 @@ public class TermSymbol extends Symbol { else return super.fullName(); } + /** Is this symbol a constructor? */ + public boolean isConstructor() { + return name.isTypeName(); + } + /** Return a fresh symbol with the same fields as this one. */ public Symbol cloneSymbol(Symbol owner) { @@ -1129,6 +1159,16 @@ public class TypeSymbol extends Symbol { return type().unalias().typeParams(); } + /** Get all constructors of class */ + public Symbol allConstructors() { + return type().unalias().symbol().allConstructors(); + } + + /** Get primary constructor of class */ + public Symbol primaryConstructor() { + return type().unalias().symbol().primaryConstructor(); + } + public Type[] closure() { if (kind == ALIAS) return info().symbol().closure(); int id = currentPhaseId(); @@ -1257,6 +1297,16 @@ public class AbsTypeSymbol extends TypeSymbol { return Symbol.EMPTY_ARRAY; } + /** Get all constructors of class */ + public Symbol allConstructors() { + return Symbol.NONE; + } + + /** Get primary constructor of class */ + public Symbol primaryConstructor() { + return Symbol.NONE; + } + public Type loBound() { initialize(); return lobound == null ? Global.instance.definitions.ALL_TYPE : lobound; @@ -1279,7 +1329,7 @@ public class ClassSymbol extends TypeSymbol { private Type template; /** The primary constructor of this type */ - public final Symbol constructor; + private Symbol constructor; /** The module belonging to the class. This means: * For Java classes, its statics parts. @@ -1328,27 +1378,38 @@ public class ClassSymbol extends TypeSymbol { ClassSymbol other = new ClassSymbol(pos, name, owner, flags); other.module = module; other.setInfo(info()); - other.constructor.setInfo( - fixClonedConstrType( - constructor.info().cloneType(constructor, other.constructor), - other)); + other.primaryConstructor().setInfo( + fixConstrType( + primaryConstructor().info().cloneType( + primaryConstructor(), other.primaryConstructor()), + other)); + Symbol[] alts = allConstructors().alternativeSymbols(); + for (int i = 1; i < alts.length; i++) { + Symbol constr = other.addConstructor(); + constr.setInfo( + fixConstrType( + alts[i].info().cloneType(alts[i], constr), + other)); + } other.mangled = mangled; if (thisSym != this) other.setTypeOfThis(typeOfThis()); return other; } - private Type fixClonedConstrType(Type type, Symbol clone) { + private Type fixConstrType(Type type, Symbol clone) { switch (type) { case MethodType(Symbol[] vparams, Type result): - result = fixClonedConstrType(result, clone); + result = fixConstrType(result, clone); return new Type.MethodType(vparams, result); case PolyType(Symbol[] tparams, Type result): - result = fixClonedConstrType(result, clone); + result = fixConstrType(result, clone); return new Type.PolyType(tparams, result); case TypeRef(Type pre, Symbol sym, Type[] args): assert sym == this : Debug.show(sym) + " != " + Debug.show(this); return new Type.TypeRef(pre, clone, args); + case LazyType(): + return type; default: - throw Debug.abort("unexpected constructor type"); + throw Debug.abort("unexpected constructor type:" + clone + ":" + type); } } @@ -1356,6 +1417,9 @@ public class ClassSymbol extends TypeSymbol { */ public void copyTo(Symbol sym) { super.copyTo(sym); + Symbol symconstr = ((ClassSymbol) sym).constructor; + constructor.copyTo(symconstr); + symconstr.setInfo(fixConstrType(symconstr.rawInfo(), sym)); if (thisSym != this) sym.setTypeOfThis(typeOfThis()); } @@ -1404,21 +1468,11 @@ public class ClassSymbol extends TypeSymbol { /** Get type parameters */ public Symbol[] typeParams() { - // !!! For some Java classes, constructor() returns an - // Overloaded symbol. This is wrong as constructor() should - // return the primary constructor. Once this problem is - // solved, the following switch can be removed. - Type constrtype = constructor.info(); - switch (constrtype) { - case OverloadedType(_, _): - return Symbol.EMPTY_ARRAY; - default: - return constrtype.typeParams(); - } + return primaryConstructor().info().typeParams(); } public Symbol[] valueParams() { - return constructor.info().valueParams(); + return primaryConstructor().info().valueParams(); } /** Get type */ @@ -1453,9 +1507,22 @@ public class ClassSymbol extends TypeSymbol { return this; } + /** add a constructor + */ + public Symbol addConstructor() { + Symbol constr = TermSymbol.newConstructor(this, flags & ~MODUL); + constructor = constructor.overloadWith(constr); + return constr; + } + /** Get primary constructor */ - public Symbol constructor() { - return constructor; + public Symbol primaryConstructor() { + return constructor.firstAlternative(); + } + + /** Get all constructors */ + public Symbol allConstructors() { + return constructor; } /** Return the next enclosing class */ @@ -1479,7 +1546,6 @@ public class ClassSymbol extends TypeSymbol { public void reset(Type completer) { super.reset(completer); - constructor().reset(completer); module().reset(completer); template = null; thisSym = this; @@ -1520,7 +1586,7 @@ public final class ErrorSymbol extends Symbol { } /** Get primary constructor */ - public Symbol constructor() { + public Symbol primaryConstructor() { return TermSymbol.newConstructor(this, 0).setInfo(Type.ErrorType); } diff --git a/sources/scalac/symtab/Type.java b/sources/scalac/symtab/Type.java index 7dcf109456..7b27647e22 100644 --- a/sources/scalac/symtab/Type.java +++ b/sources/scalac/symtab/Type.java @@ -53,6 +53,7 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags { */ public case TypeRef(Type pre, Symbol sym, Type[] args) { assert pre.isLegalPrefix() || pre == ErrorType : pre + "#" + sym; + assert sym.kind == ERROR || sym.isType() : pre + "#" + sym; } /** parts_1 with ... with parts_n { members } @@ -159,7 +160,7 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags { Position.NOPOS, Names.COMPOUND_NAME.toTypeName(), Symbol.NONE, SYNTHETIC | ABSTRACTCLASS); res.tsym.setInfo(res); - res.tsym.constructor().setInfo( + res.tsym.primaryConstructor().setInfo( Type.MethodType(Symbol.EMPTY_ARRAY, Type.NoType)); return res; } @@ -419,7 +420,7 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags { if (sym.kind == ALIAS) return unalias().parents(); else if (sym.kind == CLASS) { - assert sym.typeParams().length == args.length : sym + " " + ArrayApply.toString(args);//debug + assert sym.typeParams().length == args.length : sym + " " + ArrayApply.toString(args) + " " + sym.primaryConstructor().info();//debug return subst(asSeenFrom(sym.info().parents(), pre, sym.owner()), sym.typeParams(), args); } else @@ -508,7 +509,7 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags { /** If this type is overloaded, its alternative types, * otherwise an array consisting of this type itself. */ - public Type[] alternatives() { + public Type[] alternativeTypes() { switch (this) { case OverloadedType(_, Type[] alttypes): return alttypes; @@ -517,6 +518,18 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags { } } + /** If this type is overloaded, its alternative symbols, + * otherwise an empty array. + */ + public Symbol[] alternativeSymbols() { + switch (this) { + case OverloadedType(Symbol[] alts, _): + return alts; + default: + return Symbol.EMPTY_ARRAY; + } + } + /** If type is a this type of a module class, transform to singletype of * module. */ @@ -2440,7 +2453,7 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags { else return sym.typeConstructor(); } - default: throw new ApplicationError(); + default: throw new ApplicationError(sym + " has wrong kind: " + sym.kind); } case CompoundType(Type[] parents, _): if (parents.length > 0) return parents[0].erasure(); diff --git a/sources/scalac/symtab/classfile/AttributeParser.java b/sources/scalac/symtab/classfile/AttributeParser.java index fe2264f594..4df2529b2d 100644 --- a/sources/scalac/symtab/classfile/AttributeParser.java +++ b/sources/scalac/symtab/classfile/AttributeParser.java @@ -150,7 +150,9 @@ public class AttributeParser implements ClassfileConstants { case META_ATTR: //System.out.println("parsing meta data for " + sym); String meta = pool.readPool(in.nextChar()).toString().trim(); - sym.setInfo(new MetaParser(meta, tvars, sym, type).parse(), parser.phaseId); + sym.setInfo( + new MetaParser(meta, tvars, sym, type).parse(), + Symbol.FIRST_ID); return; } throw new RuntimeException("unknown classfile attribute"); @@ -176,7 +178,7 @@ public class AttributeParser implements ClassfileConstants { } private Symbol getTVar(String name) { - return getTVar(name, parser.c.constructor()); + return getTVar(name, parser.c.primaryConstructor()); } private Symbol getTVar(String name, Symbol owner) { @@ -195,7 +197,7 @@ public class AttributeParser implements ClassfileConstants { Name.fromString(token).toTypeName(), owner, Modifiers.PARAM); - s.setInfo(parser.defs.ANY_TYPE, parser.phaseId); + s.setInfo(parser.defs.ANY_TYPE, Symbol.FIRST_ID); tvars.enter(s); return s; } else @@ -251,7 +253,7 @@ public class AttributeParser implements ClassfileConstants { //System.out.println("new var " + s + ", " + token);//DEBUG if (token.equals("<")) { nextToken(); - s.setInfo(parseType(), parser.phaseId); + s.setInfo(parseType(), Symbol.FIRST_ID); } syms.add(s); } while (token.equals(",")); @@ -259,36 +261,19 @@ public class AttributeParser implements ClassfileConstants { nextToken(); Symbol[] smbls = (Symbol[])syms.toArray(new Symbol[syms.size()]); //System.out.println("*** " + syms);//DEBUG - Type constrtype = Type.appliedType( - parser.ctype, Symbol.type(smbls)); - - if ((parser.c.flags & Modifiers.INTERFACE) != 0) { - parser.c.constructor().setInfo( - Type.PolyType( - smbls, Type.MethodType(Symbol.EMPTY_ARRAY, constrtype)), - parser.phaseId); - //System.out.println("info = " + parser.c.constructor().info());//DEBUG - } - Symbol[] constrs; - switch (parser.c.constructor().rawInfo()) { - case OverloadedType(Symbol[] alts, _): - constrs = alts; - break; - default: - constrs = new Symbol[]{parser.c.constructor()}; - } - for (int i = 0; i < constrs.length; i++) { - //System.out.println("info = " + e.sym.info()); - switch (constrs[i].rawInfo()) { - case MethodType(Symbol[] vparams, _): - constrs[i].setInfo( - Type.PolyType( - smbls, Type.MethodType(vparams, constrtype)), - parser.phaseId); - break; - } - //System.out.println("*** constructor " + e.sym + ": " + e.sym.info());//DEBUG - } + Type clazztype = Type.appliedType( + parser.ctype, Symbol.type(smbls)); + Symbol constr = parser.c.primaryConstructor(); + switch (constr.rawInfo()) { + case MethodType(Symbol[] vparams, _): + constr.setInfo( + Type.PolyType( + smbls, Type.MethodType(vparams, clazztype)), + Symbol.FIRST_ID); + break; + default: + throw new ApplicationError(constr.rawInfo()); + } } catch (NoSuchElementException e) { } } @@ -352,12 +337,12 @@ public class AttributeParser implements ClassfileConstants { Name.fromString(token).toTypeName(), owner, Modifiers.PARAM); - s.setInfo(parser.defs.ANY_TYPE, parser.phaseId); + s.setInfo(parser.defs.ANY_TYPE, Symbol.FIRST_ID); locals.enter(s); nextToken(); if (token.equals("<")) { nextToken(); - s.setInfo(parseType(), parser.phaseId); + s.setInfo(parseType(), Symbol.FIRST_ID); } syms.add(s); } while (token.equals(",")); @@ -381,7 +366,7 @@ public class AttributeParser implements ClassfileConstants { Position.NOPOS, Name.fromString("x" + (i++)), owner, - flags).setInfo(parseType(), parser.phaseId)); + flags).setInfo(parseType(), Symbol.FIRST_ID)); //System.out.println(" + " + token); } while (token.equals(",")); assert ")".equals(token); @@ -434,7 +419,7 @@ public class AttributeParser implements ClassfileConstants { Position.NOPOS, Name.fromString("x" + (i++)), owner, - Modifiers.PARAM).setInfo(parseType(), parser.phaseId)); + Modifiers.PARAM).setInfo(parseType(), Symbol.FIRST_ID)); //System.out.println(" + " + token); } while (token.equals(",")); assert ")".equals(token); diff --git a/sources/scalac/symtab/classfile/ClassfileParser.java b/sources/scalac/symtab/classfile/ClassfileParser.java index 2272b6dc21..098be96b06 100644 --- a/sources/scalac/symtab/classfile/ClassfileParser.java +++ b/sources/scalac/symtab/classfile/ClassfileParser.java @@ -41,7 +41,6 @@ public class ClassfileParser implements ClassfileConstants { protected Type ctype; protected Scope locals; protected Scope statics; - protected Scope constr; protected JavaTypeFactory make; protected Signatures sigs; protected ConstantPool pool; @@ -93,16 +92,16 @@ public class ClassfileParser implements ClassfileConstants { Type[] basetpes = new Type[in.nextChar() + 1]; this.locals = new Scope(); this.statics = new Scope(); - this.constr = new Scope(); // set type of class Type classType = Type.compoundType(basetpes, locals, c); - c.setInfo(classType, phaseId); + c.setInfo(classType, Symbol.FIRST_ID); // set type of statics Symbol staticsClass = c.module().moduleClass(); Type staticsInfo = Type.compoundType(Type.EMPTY_ARRAY, statics, staticsClass); - staticsClass.setInfo(staticsInfo, phaseId); + staticsClass.setInfo(staticsInfo, Symbol.FIRST_ID); c.module().setInfo(Type.TypeRef(staticsClass.owner().thisType(), staticsClass, Type.EMPTY_ARRAY)); + basetpes[0] = supertpe; for (int i = 1; i < basetpes.length; i++) basetpes[i] = readClassType(in.nextChar()); @@ -112,16 +111,14 @@ public class ClassfileParser implements ClassfileConstants { int methodCount = in.nextChar(); for (int i = 0; i < methodCount; i++) parseMethod(); - // set constructor type to the declared type - Symbol[] constrs = constr.elements(); - if (constrs.length != 0) { - assert constrs.length == 1; - c.constructor().setInfo(constrs[0].info(), phaseId); - } else { - Symbol[] cparams = ((c.flags & Modifiers.INTERFACE) != 0) ? Symbol.EMPTY_ARRAY - : new Symbol[]{Symbol.NONE}; - c.constructor().setInfo(Type.MethodType(cparams, ctype), phaseId); - } + + Symbol constr = c.primaryConstructor(); + if (!constr.isInitialized()) { + constr.setInfo( + Type.MethodType(Symbol.EMPTY_ARRAY, ctype), Symbol.FIRST_ID); + if ((c.flags & Modifiers.INTERFACE) == 0) + constr.flags |= Modifiers.PRIVATE; + } attrib.readAttributes(c, classType, CLASS_ATTR); //System.out.println("dynamic class: " + c); //System.out.println("statics class: " + staticsClass); @@ -188,7 +185,7 @@ public class ClassfileParser implements ClassfileConstants { if ((flags & 0x0008) != 0) owner = c.module().moduleClass(); Symbol s = new TermSymbol(Position.NOPOS, name, owner, mods); - s.setInfo(type, phaseId); + s.setInfo(type, Symbol.FIRST_ID); attrib.readAttributes(s, type, FIELD_ATTR); ((flags & 0x0008) != 0 ? statics : locals).enterOrOverload(s); } @@ -215,16 +212,19 @@ public class ClassfileParser implements ClassfileConstants { default: throw new ApplicationError(); } - s.setInfo(type, phaseId); + s.setInfo(type, Symbol.FIRST_ID); attrib.readAttributes(s, type, METH_ATTR); + Symbol constr = c.primaryConstructor(); + if (constr.isInitialized()) constr = c.addConstructor(); + s.copyTo(constr); + //System.out.println(c + " " + c.allConstructors() + ":" + c.allConstructors().info());//debug //System.out.println("-- enter " + s); - constr.enterOrOverload(s); } else { Symbol s = new TermSymbol( Position.NOPOS, name, ((flags & 0x0008) != 0) ? c.module().moduleClass() : c, transFlags(flags)); - s.setInfo(type, phaseId); + s.setInfo(type, Symbol.FIRST_ID); attrib.readAttributes(s, type, METH_ATTR); ((flags & 0x0008) != 0 ? statics : locals).enterOrOverload(s); } diff --git a/sources/scalac/symtab/classfile/PackageParser.java b/sources/scalac/symtab/classfile/PackageParser.java index 80191c79ba..e523bc4dbb 100644 --- a/sources/scalac/symtab/classfile/PackageParser.java +++ b/sources/scalac/symtab/classfile/PackageParser.java @@ -77,11 +77,11 @@ public class PackageParser extends Type.LazyType { .toTypeName(); if (locals.lookup(n) == Symbol.NONE) { ClassSymbol clazz = new ClassSymbol(n, p, classCompletion); - clazz.constructor().setInfo( + // todo: needed? + clazz.allConstructors().setInfo( classCompletion.staticsParser(clazz)); // enter class locals.enter(clazz); - locals.enter(clazz.constructor()); // enter module, except for scala.Object class // todo: why not there also?. if (!(n == Names.Object.toTypeName() && @@ -110,10 +110,10 @@ public class PackageParser extends Type.LazyType { sym.rawInfoAt(Symbol.FIRST_ID) instanceof ClassParser && !(sym.rawInfoAt(Symbol.FIRST_ID) instanceof SymblParser)) { ClassSymbol clazz = new ClassSymbol(n, p, symblCompletion); - clazz.constructor().setInfo(symblCompletion); + //todo: needed + clazz.allConstructors().setInfo(symblCompletion); clazz.module().setInfo(symblCompletion); locals.enter(clazz); - locals.enter(clazz.constructor()); locals.enter(clazz.module()); } } else if (inclClasses && fname.endsWith(".scala")) { @@ -126,11 +126,11 @@ public class PackageParser extends Type.LazyType { SourceCompleter completer = new SourceCompleter(global, dir.getPath() + File.separatorChar + fname); ClassSymbol clazz = new ClassSymbol(n, p, completer); - clazz.constructor().setInfo(completer); + //todo: needed? + clazz.allConstructors().setInfo(completer); clazz.module().setInfo(completer); // enter class locals.enter(clazz); - locals.enter(clazz.constructor()); locals.enter(clazz.module()); } } diff --git a/sources/scalac/symtab/classfile/Pickle.java b/sources/scalac/symtab/classfile/Pickle.java index 83d9851405..ded41362ea 100644 --- a/sources/scalac/symtab/classfile/Pickle.java +++ b/sources/scalac/symtab/classfile/Pickle.java @@ -143,45 +143,38 @@ public class Pickle implements Kinds, Modifiers, EntryTags { * another symbol. */ private void putSymbol(Symbol sym) { - switch (sym.info()) { - case OverloadedType(Symbol[] alts, _): - for (int i = 0; i < alts.length; i++) - putSymbol(alts[i]); - break; - default: - if (putEntry(sym)) { - //System.out.println("put sym " + sym);//DEBUG - if (isLocal(sym)) { - putEntry(sym.name); - putSymbol(sym.owner()); - putType(sym.info()); - switch (sym.kind) { - case TYPE: - putType(sym.loBound()); - break; - case ALIAS: - break; - case CLASS: - putType(sym.typeOfThis()); - putSymbol(sym.constructor()); - for (Scope.SymbolIterator it = sym.members().iterator(); - it.hasNext();) - putSymbol(it.next()); - break; - case VAL: - if (sym.isPrimaryConstructor()) - putSymbol(sym.primaryConstructorClass()); - else if (sym.isModule()) - putSymbol(sym.moduleClass()); - break; - default: - throw new ApplicationError(); - } - } else if (sym.kind != NONE) { - putEntry(sym.name); - if (sym.owner() != Global.instance.definitions.ROOT_CLASS) - putSymbol(sym.owner()); + if (putEntry(sym)) { + //System.out.println("put sym " + sym);//DEBUG + if (isLocal(sym)) { + putEntry(sym.name); + putSymbol(sym.owner()); + putType(sym.info()); + switch (sym.kind) { + case TYPE: + putType(sym.loBound()); + break; + case ALIAS: + break; + case CLASS: + putType(sym.typeOfThis()); + putSymbol(sym.allConstructors()); + for (Scope.SymbolIterator it = sym.members().iterator(); + it.hasNext();) + putSymbol(it.next()); + break; + case VAL: + if (sym.isPrimaryConstructor()) + putSymbol(sym.primaryConstructorClass()); + else if (sym.isModule()) + putSymbol(sym.moduleClass()); + break; + default: + throw new ApplicationError(); } + } else if (sym.kind != NONE) { + putEntry(sym.name); + if (sym.owner() != Global.instance.definitions.ROOT_CLASS) + putSymbol(sym.owner()); } } } @@ -229,7 +222,8 @@ public class Pickle implements Kinds, Modifiers, EntryTags { putSymbols(tparams); break; case OverloadedType(Symbol[] alts, Type[] alttypes): - assert false : tp; + for (int i = 0; i < alts.length; i++) + putSymbol(alts[i]); break; default: throw new ApplicationError(); @@ -308,7 +302,6 @@ public class Pickle implements Kinds, Modifiers, EntryTags { */ private void writeName(Name name) { if (name.isTermName()) writeByte(TERMname); - else if (name.isConstrName()) writeByte(CONSTRname); else writeByte(TYPEname); writeByte(0); // space for length while (bp + name.length() > bytes.length) resizeTo(bytes.length * 2); @@ -350,7 +343,7 @@ public class Pickle implements Kinds, Modifiers, EntryTags { break; case CLASS: writeRef(sym.typeOfThis()); - writeRef(sym.constructor()); + writeRef(sym.allConstructors()); break; case VAL: if (sym.isPrimaryConstructor()) @@ -363,8 +356,7 @@ public class Pickle implements Kinds, Modifiers, EntryTags { writeByte(NONEsym); writeByte(0); // space for length } else { - writeByte(((sym.flags & (MODUL | PACKAGE)) == MODUL) - ? EXTMODCLASSsym : EXTsym); + writeByte((sym.isTerm() || sym.isModuleClass()) ? TERMref : TYPEref); writeByte(0); // space for length 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 a0cc7eda31..ccc4fcf2fe 100644 --- a/sources/scalac/symtab/classfile/UnPickle.java +++ b/sources/scalac/symtab/classfile/UnPickle.java @@ -49,7 +49,7 @@ public class UnPickle implements Kinds, Modifiers, EntryTags { if (global.debug) global.log( "unpickle " + root + " " + classroot + " " + moduleroot + " " + - moduleroot.moduleClass() + moduleroot.moduleClass().constructor()); + moduleroot.moduleClass() + moduleroot.moduleClass().primaryConstructor()); this.bytes = data; this.bp = 0; this.sourceName = sourceName; @@ -69,7 +69,7 @@ public class UnPickle implements Kinds, Modifiers, EntryTags { System.out.print(tag + " "); int len = readNat(); System.out.print(len + " "); - if (tag == TERMname || tag == TYPEname || tag == CONSTRname) + if (tag == TERMname || tag == TYPEname) System.out.print( SourceRepresentation.ascii2string(bytes, bp, len)); else @@ -141,7 +141,6 @@ public class UnPickle implements Kinds, Modifiers, EntryTags { Name name = Name.fromAscii(bytes, bp, len); switch (tag) { case TERMname : entries[n] = name; break; - case CONSTRname: entries[n] = name.toConstrName(); break; case TYPEname : entries[n] = name.toTypeName(); break; default: throw new BadSignature(this); } @@ -156,25 +155,19 @@ public class UnPickle implements Kinds, Modifiers, EntryTags { String decode(Name name) { if (name.isTypeName()) return "type " + NameTransformer.decode(name); - else if (name.isConstrName()) return "constructor " + NameTransformer.decode(name); else return "value " + NameTransformer.decode(name); } - Symbol extRef(Symbol owner, Name name, boolean modclass) { - if (name.length() == 0 && owner == Symbol.NONE) { - return Global.instance.definitions.ROOT_CLASS; - } else if (modclass) { - assert name.isTypeName() : name; - Symbol module = extRef(owner, name.toTermName(), false); - switch (module.type()) { - case OverloadedType(Symbol[] alts, _): - for (int i = 0; i < alts.length; i++) - if (alts[i].isModule()) module = alts[i]; - } - assert module.isModule(); - return module.moduleClass(); + void enterSymbol(Symbol sym) { + Symbol owner = sym.owner(); + Scope scope = owner.info().members(); + Symbol other = scope.lookup(sym.name); + if (other == Symbol.NONE) { + if (global.debug) + global.log("entering " + sym + ":" + sym.type() + " in " + owner);//debug + scope.enter(sym); } else { - return owner.info().lookup(name); + assert sym.rawInfo() instanceof Type.OverloadedType : sym; } } @@ -190,8 +183,8 @@ public class UnPickle implements Kinds, Modifiers, EntryTags { case NONEsym: entries[n] = sym = Symbol.NONE; break; - case EXTsym: - case EXTMODCLASSsym: + case TERMref: + case TYPEref: Name name = readNameRef(); if (bp == end) { owner = Global.instance.definitions.ROOT_CLASS; @@ -199,7 +192,22 @@ public class UnPickle implements Kinds, Modifiers, EntryTags { assert bp < end; owner = readSymbolRef(); } - entries[n] = sym = extRef(owner, name, tag == EXTMODCLASSsym); + if (name.length() == 0 && owner == Symbol.NONE) { + sym = Global.instance.definitions.ROOT_CLASS; + } else if (tag == TERMref && name.isTypeName()) { + Symbol module = owner.info().lookup(name.toTermName()); + switch (module.type()) { + case OverloadedType(Symbol[] alts, _): + for (int i = 0; i < alts.length; i++) + if (alts[i].isModule()) module = alts[i]; + } + assert module.isModule(); + sym = module.moduleClass(); + } else { + assert (tag == TYPEref) == name.isTypeName(); + sym = owner.info().lookup(name); + } + entries[n] = sym; if (sym.kind == NONE) { if (global.debug) global.log(owner.info().members().toString());//debug @@ -243,30 +251,30 @@ public class UnPickle implements Kinds, Modifiers, EntryTags { } sym.setInfo(getType(inforef)); sym.setTypeOfThis(readTypeRef()); - Symbol constructor = readSymbolRef(); //will install itself! + Symbol constr = readSymbolRef(); + constr.copyTo(sym.allConstructors()); + if (sym.isCaseClass()) { + Symbol cf = new TermSymbol( + Position.NOPOS, name.toTermName(), + owner, flags | CASE); + cf.setInfo(setOwner(constr.type(), cf)); + if (name == classroot.name && owner == classroot.owner()) { + if (global.debug) + global.log("overwriting " + moduleroot);//debug + cf.copyTo(moduleroot); + cf = moduleroot; + } else { + enterSymbol(sym); + } + } break; case VALsym: - Symbol cf = Symbol.NONE; if (bp < end) { ClassSymbol clazz = (ClassSymbol) readSymbolRef(); - if (name.isConstrName()) { - entries[n] = sym = clazz.constructor(); - if (global.debug) - global.log("overwriting " + sym);//debug - TermSymbol.newConstructor(clazz, flags).copyTo(sym); - if (clazz.isCaseClass()) { - cf = new TermSymbol( - Position.NOPOS, name.toTermName(), owner, flags | CASE); - if (name.toTypeName() == classroot.name && owner == moduleroot.owner()) { - if (global.debug) - global.log("overwriting " + moduleroot);//debug - cf.copyTo(moduleroot); - cf = moduleroot; - } else { - owner.info().members().enterOrOverload(cf); - } - } + if (name.isTypeName()) { + entries[n] = sym = TermSymbol.newConstructor( + clazz, flags); } else { assert (flags & MODUL) != 0 : name; entries[n] = sym = TermSymbol.newModule( @@ -284,34 +292,20 @@ public class UnPickle implements Kinds, Modifiers, EntryTags { } Type tp = getType(inforef); sym.setInfo(setOwner(tp, sym)); - if (cf.kind != NONE) cf.setInfo(setOwner(tp, cf)); break; default: throw new BadSignature(this); } - if (owner.kind == CLASS && !noEnter(sym)) { - if (global.debug) - global.log("entering " + sym + ":" + sym.type() + " in " + owner);//debug - owner.info().members().enterOrOverload(sym); - } + if (owner.kind == CLASS) + enterSymbol(sym); } } bp = savedBp; } return (Symbol) entries[n]; } - //where - private boolean noEnter(Symbol sym) { - return - sym == classroot || - sym == moduleroot || - sym.isModuleClass() || - sym.isPrimaryConstructor() && noEnter(sym.primaryConstructorClass()); - } - - Symbol readSymbolRef() { return getSymbol(readNat()); -- cgit v1.2.3