From 364a11eaeec22c8385391114de81271613d58c82 Mon Sep 17 00:00:00 2001 From: paltherr Date: Mon, 26 Jan 2004 14:50:37 +0000 Subject: - Added automatic rebinding and unaliasing in T... - Added automatic rebinding and unaliasing in TypeRef creation --- .../scala/tools/scalac/typechecker/Analyzer.scala | 9 +- sources/scalac/symtab/Definitions.java | 2 +- sources/scalac/symtab/Symbol.java | 30 +++---- sources/scalac/symtab/Type.java | 100 ++++++++++++++------- .../scalac/symtab/classfile/CLRClassParser.java | 2 +- .../scalac/symtab/classfile/ClassfileParser.java | 2 +- sources/scalac/symtab/classfile/UnPickle.java | 2 +- sources/scalac/transformer/AddInterfacesPhase.java | 2 +- sources/scalac/transformer/ErasurePhase.java | 2 +- sources/scalac/transformer/ExpandMixinsPhase.java | 5 +- .../transformer/ExplicitOuterClassesPhase.java | 8 +- sources/scalac/transformer/LambdaLiftPhase.java | 4 +- sources/scalac/typechecker/Analyzer.java | 9 +- 13 files changed, 105 insertions(+), 72 deletions(-) diff --git a/sources/scala/tools/scalac/typechecker/Analyzer.scala b/sources/scala/tools/scalac/typechecker/Analyzer.scala index 6124aa20b7..49533273a5 100644 --- a/sources/scala/tools/scalac/typechecker/Analyzer.scala +++ b/sources/scala/tools/scalac/typechecker/Analyzer.scala @@ -994,7 +994,7 @@ class Analyzer(global: scalac_Global, descr: AnalyzerPhase) extends Transformer( val constrtype: Type = makeMethodType( tparamSyms, vparamSyms, - new Type$TypeRef(sym.owner().thisType(), sym, Symbol.getType(tparamSyms))); + Type.typeRef(sym.owner().thisType(), sym, Symbol.getType(tparamSyms))); //System.out.println("set info " + sym.constructor() + " to " + constrtype + " was " + sym.constructor().rawInfo());//DEBUG sym.primaryConstructor().setInfo(constrtype); // necessary so that we can access tparams @@ -1088,14 +1088,11 @@ class Analyzer(global: scalac_Global, descr: AnalyzerPhase) extends Transformer( var rhs = _rhs; pushContext(tree, sym.primaryConstructor(), new Scope(context.scope)); val tparamSyms = enterParams(tparams); - sym.primaryConstructor().setInfo( - new Type$PolyType(tparamSyms, sym.typeConstructor())); - // necessary so that we can access tparams - sym.primaryConstructor().flags = - sym.primaryConstructor().flags | INITIALIZED; rhs = transform(rhs, TYPEmode); (tree.asInstanceOf[Tree$AliasTypeDef]).rhs = rhs; owntype = rhs.getType(); + sym.primaryConstructor().setInfo( + new Type$PolyType(tparamSyms, owntype)); popContext(); case Tree$AbsTypeDef(mods, name, _rhs, _lobound) => diff --git a/sources/scalac/symtab/Definitions.java b/sources/scalac/symtab/Definitions.java index a1270d7c30..aaac2ee960 100644 --- a/sources/scalac/symtab/Definitions.java +++ b/sources/scalac/symtab/Definitions.java @@ -203,7 +203,7 @@ public class Definitions { Type type = ARRAY_TYPE.type().resultType(); switch (type) { case TypeRef(Type prefix, Symbol clasz, _): - return Type.TypeRef(prefix, clasz, new Type[]{element}); + return Type.typeRef(prefix, clasz, new Type[]{element}); case UnboxedArrayType(_): return Type.UnboxedArrayType(element); default: diff --git a/sources/scalac/symtab/Symbol.java b/sources/scalac/symtab/Symbol.java index a0b19bdf76..8264f448c1 100644 --- a/sources/scalac/symtab/Symbol.java +++ b/sources/scalac/symtab/Symbol.java @@ -1502,19 +1502,19 @@ public abstract class TypeSymbol extends Symbol { } protected final void copyConstructorInfo(TypeSymbol other) { - other.primaryConstructor().setInfo( - fixConstrType( - primaryConstructor().info().cloneType( - primaryConstructor(), other.primaryConstructor()), - other)); + { + Type info = primaryConstructor().info().cloneType( + primaryConstructor(), other.primaryConstructor()); + if (!isTypeAlias()) info = fixConstrType(info, other); + other.primaryConstructor().setInfo(info); + } Symbol[] alts = allConstructors().alternativeSymbols(); for (int i = 1; i < alts.length; i++) { Symbol constr = other.addConstructor(); constr.flags = other.flags; - constr.setInfo( - fixConstrType( - alts[i].info().cloneType(alts[i], constr), - other)); + Type info = alts[i].info().cloneType(alts[i], constr); + if (!isTypeAlias()) info = fixConstrType(info, other); + constr.setInfo(info); } } @@ -1530,7 +1530,7 @@ public abstract class TypeSymbol extends Symbol { if (sym != this && isTypeAlias() && owner().isCompoundSym()) return type; assert sym == this: Debug.show(sym) + " != " + Debug.show(this); - return new Type.TypeRef(pre, clone, args); + return Type.typeRef(pre, clone, args); case LazyType(): return type; default: @@ -1570,7 +1570,7 @@ public abstract class TypeSymbol extends Symbol { /** Get type constructor */ public final Type typeConstructor() { if (tycon == null) - tycon = Type.TypeRef(owner().thisType(), this, Type.EMPTY_ARRAY); + tycon = Type.typeRef(owner().thisType(), this, Type.EMPTY_ARRAY); return tycon; } @@ -1707,7 +1707,7 @@ public class AbsTypeSymbol extends TypeSymbol { /** Constructor */ public AbsTypeSymbol(int pos, Name name, Symbol owner, int flags) { super(TYPE, pos, name, owner, flags); - allConstructors().setFirstInfo(Type.MethodType(EMPTY_ARRAY, Type.TypeRef(owner.thisType(), this, Type.EMPTY_ARRAY))); + allConstructors().setFirstInfo(Type.MethodType(EMPTY_ARRAY, Type.typeRef(owner.thisType(), this, Type.EMPTY_ARRAY))); } public static AbsTypeSymbol define( @@ -1791,15 +1791,13 @@ public class ClassSymbol extends TypeSymbol { Symbol clasz = ClassSymbol.this; Symbol alias = rebindSym; Type prefix = clasz.owner().thisType(); - Type constrtype = Type.TypeRef(prefix, alias,Type.EMPTY_ARRAY); + Type constrtype = clasz.type(); // !!! constrtype = Type.MethodType(Symbol.EMPTY_ARRAY, constrtype); constrtype = Type.PolyType(clasz.typeParams(), constrtype); constrtype = constrtype.cloneType( clasz.primaryConstructor(), alias.primaryConstructor()); alias.primaryConstructor().setInfo(constrtype); - Symbol[] tparams = constrtype.typeParams(); - Type info = Type.TypeRef(prefix, clasz, Symbol.type(tparams)); - alias.setInfo(info); + alias.setInfo(constrtype.resultType()); } } diff --git a/sources/scalac/symtab/Type.java b/sources/scalac/symtab/Type.java index 3f4281239c..c0d7e3c043 100644 --- a/sources/scalac/symtab/Type.java +++ b/sources/scalac/symtab/Type.java @@ -64,8 +64,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; + assert this instanceof ExtTypeRef: this; } /** parts_1 with ... with parts_n { members } @@ -147,7 +146,21 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags { public static final Type[] EMPTY_ARRAY = new Type[0]; public static SingleType singleType(Type pre, Symbol sym) { - assert sym.isTerm(): pre + " -- " + Debug.show(sym); + assert sym.isTerm() && !sym.isNone(): pre + " -- " + Debug.show(sym); + rebind: + { + Symbol owner = sym.owner(); + if (!owner.isClass()) break rebind; + if (owner == pre.symbol()) break rebind; + // !!! add if (owner is sealed/final) break rebind ? + // !!! add if (owner is module class) break rebind ? + if (sym.isFinal() || sym.isPrivate()) break rebind; + Symbol rebind = pre.lookupNonPrivate(sym.name); + if (rebind.isNone()) break rebind; + if (rebind.isLocked()) throw new Type.Error( + "illegal cyclic reference involving " + rebind); + sym = rebind.rebindSym(); + } if (pre.isStable() || pre == ErrorType) { return new ExtSingleType(pre, sym); } else { @@ -198,16 +211,55 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags { } } - public static TypeRef appliedType(Type tycon, Type[] args) { + public static Type appliedType(Type tycon, Type[] args) { switch (tycon) { case TypeRef(Type pre, Symbol sym, Type[] args1): - if (args == args1) return (TypeRef)tycon; - else return TypeRef(pre, sym, args); + if (args == args1) return tycon; + else return Type.typeRef(pre, sym, args); default: - throw new ApplicationError(); + throw Debug.abort("illegal case", tycon); } } + public static Type typeRef(Type pre, Symbol sym, Type[] args) { + if (!pre.isLegalPrefix() && pre != ErrorType) + throw new Type.Malformed(pre, sym.nameString()); + rebind: + if (sym.isAbstractType()) { + Symbol owner = sym.owner(); + if (!owner.isClass()) break rebind; + if (owner == pre.symbol()) break rebind; + // !!! add if (owner is sealed/final) break rebind ? + // !!! add if (owner is module class) break rebind ? + if (sym.isFinal() || sym.isPrivate()) break rebind; + Symbol rebind = pre.lookupNonPrivate(sym.name); + if (rebind.isNone()) break rebind; + if (rebind.isLocked()) throw new Type.Error( + "illegal cyclic reference involving " + rebind); + sym = rebind.rebindSym(); + } + if (sym.isTypeAlias()) { + Symbol[] params = sym.typeParams(); + if (args.length == params.length) + return pre.memberInfo(sym).subst(params, args); + assert args.length == 0 || args.length == params.length: + Debug.show(pre, " - ", sym, " - ", args, " - ", params); + } + assert isLegalTypeRef(pre, sym, args): + Debug.show(pre, " - ", sym, " - ", args, " - ", sym.typeParams()); + return new ExtTypeRef(pre, sym, args); + } + private static boolean isLegalTypeRef(Type pre, Symbol sym, Type[] args) { + if (!pre.isLegalPrefix() && pre != ErrorType) return false; + if (!sym.isType() && !sym.isError()) return false; + // !!! return args.length == 0 || args.length == sym.typeParams().length; + return true; + } + + public static Type newTypeRefUnsafe(Type pre, Symbol sym, Type[] args) { + return new ExtTypeRef(pre, sym, args); + } + public static CompoundType compoundType(Type[] parts, Scope members, Symbol clazz) { ExtCompoundType res = new ExtCompoundType(parts, members); @@ -222,20 +274,10 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags { SYNTHETIC | ABSTRACT); res.tsym.setInfo(res); res.tsym.primaryConstructor().setInfo( - Type.MethodType(Symbol.EMPTY_ARRAY, Type.TypeRef(res.tsym.owner().thisType(), res.tsym, Type.EMPTY_ARRAY))); + Type.MethodType(Symbol.EMPTY_ARRAY, Type.typeRef(res.tsym.owner().thisType(), res.tsym, Type.EMPTY_ARRAY))); return res; } - public static Type typeRef(Type pre, Symbol sym, Type[] args) { - if (pre.isLegalPrefix() || pre == ErrorType) - return TypeRef(pre, sym, args); - else if (sym.kind == ALIAS && sym.typeParams().length == args.length) - return sym.info().subst(sym.typeParams(), args) - .asSeenFrom(pre, sym.owner()); - else - throw new Type.Malformed(pre, sym.nameString()); - } - static class ExtSingleType extends SingleType { Type tp = null; int definedId = -1; @@ -251,6 +293,12 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags { } } + static class ExtTypeRef extends TypeRef { + ExtTypeRef(Type pre, Symbol sym, Type[] args) { + super(pre, sym, args); + } + } + static class ExtCompoundType extends CompoundType { Symbol tsym; ExtCompoundType(Type[] parts, Scope members) { @@ -309,7 +357,7 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags { switch (this) { case TypeRef(Type pre, Symbol sym, Type[] args): if (args.length == 0 && sym.typeParams().length != 0) - return TypeRef(pre, sym, Symbol.type(sym.typeParams())); + return Type.typeRef(pre, sym, Symbol.type(sym.typeParams())); } return this; } @@ -1253,16 +1301,8 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags { /** Return overriding instance of `sym' in this type, * or `sym' itself if none exists. */ + // !!! remove ! public Symbol rebind(Symbol sym) { - if (sym.kind != CLASS && sym.owner().isClass() && (sym.flags & (PRIVATE | MODUL)) == 0) { - Symbol sym1 = lookupNonPrivate(sym.name); - if (sym1.kind != NONE) { - if ((sym1.flags & LOCKED) != 0) - throw new Type.Error("illegal cyclic reference involving " + sym1); - //System.out.println("rebinding " + sym + " to " + sym1);//DEBUG - return sym1.rebindSym(); - } - } return sym; } @@ -3220,11 +3260,11 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags { if (fullname == Names.java_lang_Object || fullname == Names.scala_All || fullname == Names.scala_AllRef) - return TypeRef(localThisType, Global.instance.definitions.ANY_CLASS, EMPTY_ARRAY); + return Type.typeRef(localThisType, Global.instance.definitions.ANY_CLASS, EMPTY_ARRAY); else { Type this1 = unbox(); if (this1 != this) return this1; - else return TypeRef(localThisType, sym, EMPTY_ARRAY); + else return Type.typeRef(localThisType, sym, EMPTY_ARRAY); } default: throw new ApplicationError(sym + " has wrong kind: " + sym.kind); diff --git a/sources/scalac/symtab/classfile/CLRClassParser.java b/sources/scalac/symtab/classfile/CLRClassParser.java index 8f6e792428..913484895e 100644 --- a/sources/scalac/symtab/classfile/CLRClassParser.java +++ b/sources/scalac/symtab/classfile/CLRClassParser.java @@ -66,7 +66,7 @@ public class CLRClassParser extends ClassParser { scalac.symtab.Type staticsInfo = scalac.symtab.Type.compoundType (scalac.symtab.Type.EMPTY_ARRAY, statics, staticsClass); staticsClass.setFirstInfo(staticsInfo); - clazz.module().setInfo(scalac.symtab.Type.TypeRef + clazz.module().setInfo(scalac.symtab.Type.typeRef (staticsClass.owner().thisType(), staticsClass, scalac.symtab.Type.EMPTY_ARRAY)); } diff --git a/sources/scalac/symtab/classfile/ClassfileParser.java b/sources/scalac/symtab/classfile/ClassfileParser.java index f595883fcd..fe51630f46 100644 --- a/sources/scalac/symtab/classfile/ClassfileParser.java +++ b/sources/scalac/symtab/classfile/ClassfileParser.java @@ -101,7 +101,7 @@ public class ClassfileParser implements ClassfileConstants { if (staticsClass.isModuleClass()) { Type staticsInfo = Type.compoundType(Type.EMPTY_ARRAY, statics, staticsClass); staticsClass.setFirstInfo(staticsInfo); - c.module().setInfo(Type.TypeRef(staticsClass.owner().thisType(), + c.module().setInfo(Type.typeRef(staticsClass.owner().thisType(), staticsClass, Type.EMPTY_ARRAY)); } basetpes[0] = supertpe; diff --git a/sources/scalac/symtab/classfile/UnPickle.java b/sources/scalac/symtab/classfile/UnPickle.java index 028c5a1ecd..9e2f687d5f 100644 --- a/sources/scalac/symtab/classfile/UnPickle.java +++ b/sources/scalac/symtab/classfile/UnPickle.java @@ -342,7 +342,7 @@ public class UnPickle implements Kinds, Modifiers, EntryTags, TypeTags { tpe = new Type.ConstantType(base, value); break; case TYPEREFtpe: - tpe = Type.TypeRef( + tpe = Type.newTypeRefUnsafe( // !!! readTypeRef(), readSymbolRef(), readTypeRefs(end)); break; case COMPOUNDtpe: diff --git a/sources/scalac/transformer/AddInterfacesPhase.java b/sources/scalac/transformer/AddInterfacesPhase.java index 5a3bc5b724..4df0e88744 100644 --- a/sources/scalac/transformer/AddInterfacesPhase.java +++ b/sources/scalac/transformer/AddInterfacesPhase.java @@ -110,7 +110,7 @@ public class AddInterfacesPhase extends Phase { case CompoundType(Type[] parents, Scope members): parents = Type.cloneArray(parents); parents[parents.length - 1] = sym.owner().nextType(); - return Type.compoundType(parents, members, tp.symbol()); + return Type.compoundTypeWithOwner(sym.owner(), parents, members); default: throw Debug.abort("illegal case", tp +" -- "+ Debug.show(sym)); } diff --git a/sources/scalac/transformer/ErasurePhase.java b/sources/scalac/transformer/ErasurePhase.java index 2175d48555..5fbd76f504 100644 --- a/sources/scalac/transformer/ErasurePhase.java +++ b/sources/scalac/transformer/ErasurePhase.java @@ -112,7 +112,7 @@ public class ErasurePhase extends Phase { case MethodType(Symbol[] params, Type result): return Type.MethodType(params, eraseBoxMethodType(result)); case TypeRef(Type prefix, Symbol clasz, Type[] args): - return Type.TypeRef(prefix, clasz, Type.EMPTY_ARRAY); + return Type.typeRef(prefix, clasz, Type.EMPTY_ARRAY); default: throw Debug.abort("illegal case", type); } diff --git a/sources/scalac/transformer/ExpandMixinsPhase.java b/sources/scalac/transformer/ExpandMixinsPhase.java index 575a01c959..83ec681a38 100644 --- a/sources/scalac/transformer/ExpandMixinsPhase.java +++ b/sources/scalac/transformer/ExpandMixinsPhase.java @@ -105,6 +105,7 @@ public class ExpandMixinsPhase extends Phase { if (symbol.isJava()) return type; if (symbol.isPackage()) return type; if (symbol.isInterface()) return type; + if (symbol.isCompoundSym()) return type; // !!! check if (symbol.isClass()) { // !!! System.out.println(Debug.show("!!! ", s, " -> ", symbol, " - ", getTypeExpander(symbol).clasz, " : " + type)); return getTypeExpander(symbol).apply(type); @@ -423,7 +424,7 @@ public class ExpandMixinsPhase extends Phase { symbol = prefix.rebind(symbol); } args = map(args); - return Type.TypeRef(prefix, symbol, args).unalias(); + return Type.typeRef(prefix, symbol, args).unalias(); case SingleType(Type prefix, Symbol symbol): // !!! prefix = apply(prefix); // !!! symbol = prefix.rebind(symbol); @@ -449,7 +450,7 @@ public class ExpandMixinsPhase extends Phase { parents = Type.cloneArray(parents); while (i < parents.length) { if (!parents[i].symbol().isInterface()) - parents[i] = Type.TypeRef(parents[i].prefix(), (Symbol)interfaces.get(parents[i].symbol()), parents[i].typeArgs()); + parents[i] = Type.typeRef(parents[i].prefix(), (Symbol)interfaces.get(parents[i].symbol()), parents[i].typeArgs()); i++; } return Type.compoundType(parents, members, clasz); diff --git a/sources/scalac/transformer/ExplicitOuterClassesPhase.java b/sources/scalac/transformer/ExplicitOuterClassesPhase.java index f9f4bfc651..e2a94dc86a 100644 --- a/sources/scalac/transformer/ExplicitOuterClassesPhase.java +++ b/sources/scalac/transformer/ExplicitOuterClassesPhase.java @@ -92,7 +92,7 @@ public class ExplicitOuterClassesPhase extends Phase { Type prefix = clasz.owner().thisType(); Type[] args = Symbol.type(tparams); // !!! use getNewTypeArgs ? - Type self = Type.TypeRef(prefix, clasz, args); + Type self = Type.typeRef(prefix, clasz, args); Type s = self; self = context.transformer.apply(self); tparams = Type.symbol(self.typeArgs()); @@ -305,14 +305,14 @@ public class ExplicitOuterClassesPhase extends Phase { if (symbol.isClass()) { args = map(getNewArgsOf(context, prefix, symbol, args)); prefix = Type.localThisType; - return Type.TypeRef(prefix, symbol, args); + return Type.typeRef(prefix, symbol, args); } if (symbol.isPackage()) { args = Type.EMPTY_ARRAY; prefix = Type.localThisType; - return Type.TypeRef(prefix, symbol, args); + return Type.typeRef(prefix, symbol, args); } - return Type.TypeRef(apply(prefix), symbol, map(args)); + return Type.typeRef(apply(prefix), symbol, map(args)); case SingleType(Type prefix, Symbol symbol): return Type.singleType(apply(prefix), symbol); case ThisType(Symbol clasz): diff --git a/sources/scalac/transformer/LambdaLiftPhase.java b/sources/scalac/transformer/LambdaLiftPhase.java index 6919c56364..65da6b928b 100644 --- a/sources/scalac/transformer/LambdaLiftPhase.java +++ b/sources/scalac/transformer/LambdaLiftPhase.java @@ -73,7 +73,7 @@ public class LambdaLiftPhase extends Phase implements Kinds, Modifiers { case ThisType(Symbol s): if (s == Symbol.NONE) { pre = sym.owner().enclClass().thisType(); - tp = Type.TypeRef(pre, sym, targs); + tp = Type.typeRef(pre, sym, targs); } } } @@ -95,7 +95,7 @@ public class LambdaLiftPhase extends Phase implements Kinds, Modifiers { targs1[i] = proxy(tparams[i], owner).type(); i++; } - return Type.TypeRef(pre, sym, targs1); + return Type.typeRef(pre, sym, targs1); } } else if (LambdaLift.isLocal(sym, owner)) { assert targs.length == 0; diff --git a/sources/scalac/typechecker/Analyzer.java b/sources/scalac/typechecker/Analyzer.java index 174dd6269f..9c7b5fbaf0 100644 --- a/sources/scalac/typechecker/Analyzer.java +++ b/sources/scalac/typechecker/Analyzer.java @@ -1004,7 +1004,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { Type constrtype = makeMethodType( tparamSyms, vparamSyms, - Type.TypeRef(sym.owner().thisType(), sym, Symbol.type(tparamSyms))); + Type.typeRef(sym.owner().thisType(), sym, Symbol.type(tparamSyms))); //System.out.println("set info " + sym.constructor() + " to " + constrtype + " was " + sym.constructor().rawInfo());//DEBUG sym.primaryConstructor().setInfo(constrtype); // necessary so that we can access tparams @@ -1089,13 +1089,10 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { case AliasTypeDef(int mods, Name name, AbsTypeDef[] tparams, Tree rhs): pushContext(tree, sym.primaryConstructor(), new Scope(context.scope)); Symbol[] tparamSyms = enterParams(tparams); - sym.primaryConstructor().setInfo( - Type.PolyType(tparamSyms, sym.typeConstructor())); - // necessary so that we can access tparams - sym.primaryConstructor().flags |= INITIALIZED; ((AliasTypeDef) tree).rhs = rhs = transform(rhs, TYPEmode); owntype = rhs.type; - + sym.primaryConstructor().setInfo( + Type.PolyType(tparamSyms, owntype)); popContext(); break; -- cgit v1.2.3