diff options
Diffstat (limited to 'sources/scalac/symtab')
-rw-r--r-- | sources/scalac/symtab/Definitions.java | 61 | ||||
-rw-r--r-- | sources/scalac/symtab/Scope.java | 17 | ||||
-rw-r--r-- | sources/scalac/symtab/Symbol.java | 132 | ||||
-rw-r--r-- | sources/scalac/symtab/Type.java | 58 | ||||
-rw-r--r-- | sources/scalac/symtab/classfile/AttributeParser.java | 2 | ||||
-rw-r--r-- | sources/scalac/symtab/classfile/ClassfileParser.java | 2 |
6 files changed, 184 insertions, 88 deletions
diff --git a/sources/scalac/symtab/Definitions.java b/sources/scalac/symtab/Definitions.java index f9e5a6f0ec..a842885d31 100644 --- a/sources/scalac/symtab/Definitions.java +++ b/sources/scalac/symtab/Definitions.java @@ -45,6 +45,10 @@ public class Definitions { public final Symbol SCALARUNTIME_CLASS; public final Type SCALARUNTIME_TYPE; + /** the partial function class + */ + public final Symbol PARTIALFUNCTION_CLASS; + /** the null value */ public final Symbol NULL; @@ -191,61 +195,61 @@ public class Definitions { ANY_CLASS = new ClassSymbol( Position.NOPOS, Names.Any.toTypeName(), SCALA_CLASS, Modifiers.JAVA); SCALA_CLASS.members().enter(ANY_CLASS); - ANY_TYPE = monoType(ANY_CLASS); + ANY_TYPE = ANY_CLASS.typeConstructor(); ANY_CLASS.setInfo(Type.compoundType(Type.EMPTY_ARRAY, new Scope(), ANY_CLASS)); ANY_CLASS.constructor().setInfo( Type.PolyType(Symbol.EMPTY_ARRAY, ANY_TYPE)); // the java.lang.OBJECT class JAVA_OBJECT_CLASS = getClass(Names.java_lang_Object); - JAVA_OBJECT_TYPE = monoType(JAVA_OBJECT_CLASS); + JAVA_OBJECT_TYPE = JAVA_OBJECT_CLASS.typeConstructor(); JAVA_OBJECT_CLASS.setInfo(pparser.classCompletion); + // the scala.PartialFunction class + PARTIALFUNCTION_CLASS = getClass(Names.scala_PartialFunction); + // the scala.ANYREF class ANYREF_CLASS = new TypeSymbol( Kinds.ALIAS, Position.NOPOS, Names.AnyRef.toTypeName(), SCALA_CLASS, Modifiers.JAVA) .setInfo(JAVA_OBJECT_TYPE); - ANYREF_CLASS.constructor().setInfo( - Type.PolyType(Symbol.EMPTY_ARRAY, Type.NoType)); - - ANYREF_TYPE = monoType(ANYREF_CLASS); + ANYREF_TYPE = ANYREF_CLASS.typeConstructor(); SCALA.members().enter(ANYREF_CLASS); // the scala.OBJECT class OBJECT_CLASS = getClass(Names.scala_Object); - OBJECT_TYPE = monoType(OBJECT_CLASS); + OBJECT_TYPE = OBJECT_CLASS.typeConstructor(); // the scala.ANYVAL class ANYVAL_CLASS = getClass(Names.scala_AnyVal); - ANYVAL_TYPE = monoType(ANYVAL_CLASS); + ANYVAL_TYPE = ANYVAL_CLASS.typeConstructor(); // the primitive types DOUBLE_CLASS = getClass(Names.scala_Double); - DOUBLE_TYPE = monoType(DOUBLE_CLASS); + DOUBLE_TYPE = DOUBLE_CLASS.typeConstructor(); FLOAT_CLASS = getClass(Names.scala_Float); - FLOAT_TYPE = monoType(FLOAT_CLASS); + FLOAT_TYPE = FLOAT_CLASS.typeConstructor(); LONG_CLASS = getClass(Names.scala_Long); - LONG_TYPE = monoType(LONG_CLASS); + LONG_TYPE = LONG_CLASS.typeConstructor(); INT_CLASS = getClass(Names.scala_Int); - INT_TYPE = monoType(INT_CLASS); + INT_TYPE = INT_CLASS.typeConstructor(); CHAR_CLASS = getClass(Names.scala_Char); - CHAR_TYPE = monoType(CHAR_CLASS); + CHAR_TYPE = CHAR_CLASS.typeConstructor(); SHORT_CLASS = getClass(Names.scala_Short); - SHORT_TYPE = monoType(SHORT_CLASS); + SHORT_TYPE = SHORT_CLASS.typeConstructor(); BYTE_CLASS = getClass(Names.scala_Byte); - BYTE_TYPE = monoType(BYTE_CLASS); + BYTE_TYPE = BYTE_CLASS.typeConstructor(); BOOLEAN_CLASS = getClass(Names.scala_Boolean); - BOOLEAN_TYPE = monoType(BOOLEAN_CLASS); + BOOLEAN_TYPE = BOOLEAN_CLASS.typeConstructor(); UNIT_CLASS = getClass(Names.scala_Unit); - UNIT_TYPE = monoType(UNIT_CLASS); + UNIT_TYPE = UNIT_CLASS.typeConstructor(); // the array class ARRAY_CLASS = getClass(Names.scala_Array); // add members to java.lang.Throwable JAVA_THROWABLE_CLASS = getClass(Names.java_lang_Throwable); - JAVA_THROWABLE_TYPE = monoType(JAVA_THROWABLE_CLASS); + JAVA_THROWABLE_TYPE = JAVA_THROWABLE_CLASS.typeConstructor(); THROW = new TermSymbol( Position.NOPOS, Names.throw_, JAVA_THROWABLE_CLASS, Modifiers.FINAL); Symbol tvar = newTypeParameter(THROW, ANY_TYPE); @@ -254,13 +258,11 @@ public class Definitions { // add the java.lang.String class to the scala package JAVA_STRING_CLASS = getClass(Names.java_lang_String); - JAVA_STRING_TYPE = monoType(JAVA_STRING_CLASS); + JAVA_STRING_TYPE = JAVA_STRING_CLASS.typeConstructor(); STRING_CLASS = new TypeSymbol( Kinds.ALIAS, Position.NOPOS, Names.String.toTypeName(), SCALA_CLASS, 0) .setInfo(JAVA_STRING_TYPE); - STRING_CLASS.constructor().setInfo( - Type.PolyType(Symbol.EMPTY_ARRAY, Type.NoType)); - STRING_TYPE = monoType(STRING_CLASS); + STRING_TYPE = STRING_CLASS.typeConstructor(); SCALA.members().enter(STRING_CLASS); SEQ_CLASS = getClass(Names.scala_Seq); @@ -384,12 +386,8 @@ public class Definitions { return getClass(fullname).type(); } - public Type monoType(Symbol c) { - return Type.TypeRef(c.owner().thisType(), c, Type.EMPTY_ARRAY); - } - public Type getJavaType(Name fullname) { - return monoType(getClass(fullname)); + return getClass(fullname).typeConstructor(); } private void loadBooleanMembers() { @@ -402,7 +400,7 @@ public class Definitions { } public Type arrayType(Type elemtpe) { - return Type.appliedType(monoType(ARRAY_CLASS), new Type[]{elemtpe}); + return Type.appliedType(ARRAY_CLASS.typeConstructor(), new Type[]{elemtpe}); } public Type functionType(Type[] argtps, Type restp) { @@ -414,6 +412,13 @@ public class Definitions { argtps1); } + public Type partialFunctionType(Type argtpe, Type restpe) { + Type[] argtps1 = new Type[2]; + argtps1[0] = argtpe; + argtps1[1] = Type.covarType(restpe); + return Type.appliedType(PARTIALFUNCTION_CLASS.typeConstructor(), argtps1); + } + public Type seqType(Type argtpe) { return Type.appliedType(getType(Names.scala_Seq), new Type[]{argtpe}); } diff --git a/sources/scalac/symtab/Scope.java b/sources/scalac/symtab/Scope.java index 3bd22f51ed..f1fa915c55 100644 --- a/sources/scalac/symtab/Scope.java +++ b/sources/scalac/symtab/Scope.java @@ -210,19 +210,22 @@ public class Scope { /** remove entry */ public void unlink(Entry e) { - Entry e1 = hashtable[e.sym.name.index & HASHMASK]; - if (e1 == e) { - hashtable[e.sym.name.index & HASHMASK] = e.tail; - } else { - while (e1.tail != e) e1 = e1.tail; - } if (elems == e) { elems = e.next; } else { - e1 = elems; + Entry e1 = elems; while (e1.next != e) e1 = e1.next; e1.next = e.next; } + if (hashtable != null) { + Entry e1 = hashtable[e.sym.name.index & HASHMASK]; + if (e1 == e) { + hashtable[e.sym.name.index & HASHMASK] = e.tail; + } else { + while (e1.tail != e) e1 = e1.tail; + e1.tail = e.tail; + } + } elemsCache = null; } diff --git a/sources/scalac/symtab/Symbol.java b/sources/scalac/symtab/Symbol.java index b8e1821daa..20ab5b3366 100644 --- a/sources/scalac/symtab/Symbol.java +++ b/sources/scalac/symtab/Symbol.java @@ -113,9 +113,16 @@ public abstract class Symbol implements Modifiers, Kinds { return this; } - /** Set type -- this is an alias for setInfo(Type info) */ + /** Set type -- this is an alias for setInfo(Type info) + */ public Symbol setType(Type info) { return setInfo(info); } + /** Set type of `this' in current class + */ + public Symbol setTypeOfThis(Type tp) { + throw new ApplicationError(this + ".setTypeOfThis"); + } + public Symbol updateInfo(Type info) { // Global.instance.currentPhase.setInfo(this, info); if (infos.limit <= Global.instance.currentPhase.id) { @@ -481,9 +488,11 @@ public abstract class Symbol implements Modifiers, Kinds { int nextid = infos.limit; assert infos != TypeIntervalList.EMPTY : this; if (nextid < id) { + PhaseDescriptor curphase = Global.instance.currentPhase; do { + Global.instance.currentPhase = Global.instance.phases[nextid]; Type newInfo = - Global.instance.phases[nextid].transformInfo(this, infos.info); + Global.instance.currentPhase.transformInfo(this, infos.info); if (newInfo != infos.info) { infos = new TypeIntervalList(infos); infos.info = newInfo; @@ -491,6 +500,7 @@ public abstract class Symbol implements Modifiers, Kinds { nextid++; infos.limit = nextid; } while (nextid < id); + Global.instance.currentPhase = curphase; return infos.info; } else { TypeIntervalList infos1 = infos; @@ -528,14 +538,25 @@ public abstract class Symbol implements Modifiers, Kinds { return tps; } + /** The type constructor of a symbol is: + * For a type symbol, the type corresponding to the symbol itself, excluding + * parameters. + * Not applicable for term symbols. + */ + public Type typeConstructor() { + throw new ApplicationError("typeConstructor inapplicable for " + this); + } + /** Get this.type corresponding to this symbol */ public Type thisType() { return Type.localThisType; } + /** Get type of `this' in current class. + */ public Type typeOfThis() { - return Type.localThisType; + return type(); } /** A total ordering between symbols that refines the class @@ -857,10 +878,10 @@ public class TermSymbol extends Symbol { TermSymbol sym = new TermSymbol(pos, name, owner, flags | MODUL | FINAL); Symbol clazz = new ClassSymbol( pos, name.toTypeName(), owner, flags | MODUL | FINAL, sym); - Type clazztype = Type.TypeRef(owner.thisType(), clazz, Type.EMPTY_ARRAY); - clazz.constructor().setInfo(Type.MethodType(Symbol.EMPTY_ARRAY, clazztype)); + clazz.constructor().setInfo( + Type.MethodType(Symbol.EMPTY_ARRAY, clazz.typeConstructor())); sym.clazz = clazz; - sym.setInfo(clazztype); + sym.setInfo(clazz.typeConstructor()); return sym; } @@ -910,6 +931,10 @@ public class TermSymbol extends Symbol { return other; } + public Symbol[] typeParams() { + return type().typeParams(); + } + public Symbol primaryConstructorClass() { return isConstructor() && clazz != null ? clazz : this; } @@ -927,56 +952,42 @@ public class TypeSymbol extends Symbol { */ private ClosureIntervalList closures = ClosureIntervalList.EMPTY; - /** The symbol's type template */ - private Type template; - - /** The primary constructor of this type */ - public final Symbol constructor; + /** A cache for type constructors + */ + private Type tycon = null; /** Constructor */ public TypeSymbol(int kind, int pos, Name name, Symbol owner, int flags) { super(kind, pos, name, owner, flags); - this.constructor = TermSymbol.newConstructor(this, flags); - if (kind == TYPE) { // provide a constructor type - this.constructor().setInfo( - Type.PolyType(Symbol.EMPTY_ARRAY, Type.NoType)); - } } + /** Return a fresh symbol with the same fields as this one. */ public Symbol cloneSymbol() { if (Global.instance.debug) System.out.println("cloning " + this + this.locationString()); TypeSymbol other = new TypeSymbol(kind, pos, name, owner(), flags); other.setInfo(info()); - other.constructor.setInfo(constructor.info()); return other; } - /** Get self type */ + /** Get type constructor */ + public Type typeConstructor() { + if (tycon == null) + tycon = Type.TypeRef(owner().thisType(), this, Type.EMPTY_ARRAY); + return tycon; + } + + /** Get type */ public Type type() { - if (template == null || template.typeArgs().length != typeParams().length) { - template = Type.TypeRef( - owner().thisType(), this, type(typeParams())); - } - return template; + return typeConstructor(); } - //todo: needed? + /** Get type at phase id */ public Type typeAt(int id) { return type(); } - /** Get type parameters */ - public Symbol[] typeParams() { - return constructor.info().typeParams(); - } - - /** Get primary constructor */ - public Symbol constructor() { - return constructor; - } - public Type[] closure() { if (kind == ALIAS) return info().symbol().closure(); int id = Global.instance.currentPhase.id; @@ -1069,6 +1080,12 @@ public class ClassSymbol extends TypeSymbol { /** The mangled class name */ private Name mangled; + /** The symbol's type template */ + private Type template; + + /** The primary constructor of this type */ + public final Symbol constructor; + /** The module belonging to the class. This means: * For Java classes, its statics parts. * For module classes, the corresponding module. @@ -1076,10 +1093,19 @@ public class ClassSymbol extends TypeSymbol { */ private Symbol module = NONE; + /** The given type of self, or NoType, if no explicit type was given. + */ + private Symbol thisSym = this; + + /** A cache for this.thisType() + */ + private Type thistp = Type.ThisType(this); + /** Principal Constructor for module classes and classes with static members. */ public ClassSymbol(int pos, Name name, Symbol owner, int flags) { super(CLASS, pos, name, owner, flags); + this.constructor = TermSymbol.newConstructor(this, flags); this.mangled = name; } @@ -1103,6 +1129,7 @@ public class ClassSymbol extends TypeSymbol { */ public ClassSymbol(Name name, Symbol owner, ClassParser parser) { super(CLASS, Position.NOPOS, name, owner, JAVA); + this.constructor = TermSymbol.newConstructor(this, flags); this.module = TermSymbol.newCompanionModule(this, JAVA, parser.staticsParser(this)); this.mangled = name; this.setInfo(parser); @@ -1116,9 +1143,17 @@ public class ClassSymbol extends TypeSymbol { other.constructor.setInfo(constructor.info()); other.mangled = mangled; other.module = module; + other.thisSym = thisSym; return other; } + /** copy all fields to `sym' + */ + public void copyTo(Symbol sym) { + super.copyTo(sym); + if (thisSym != this) sym.setTypeOfThis(typeOfThis()); + } + /** Get module */ public Symbol module() { return module; @@ -1153,12 +1188,39 @@ public class ClassSymbol extends TypeSymbol { } } - private Type thistp = Type.ThisType(this); + /** Get type parameters */ + public Symbol[] typeParams() { + return constructor.info().typeParams(); + } + + /** Get type */ + public Type type() { + if (template == null || template.typeArgs().length != typeParams().length) { + template = Type.TypeRef( + owner().thisType(), this, type(typeParams())); + } + return template; + } public Type thisType() { return thistp; } + public Type typeOfThis() { + return thisSym.type(); + } + + public Symbol setTypeOfThis(Type tp) { + thisSym = new TermSymbol(this.pos, Names.this_, this, SYNTHETIC); + thisSym.setInfo(tp); + return this; + } + + /** Get primary constructor */ + public Symbol constructor() { + return constructor; + } + /** Return the next enclosing class */ public Symbol enclClass() { return this; diff --git a/sources/scalac/symtab/Type.java b/sources/scalac/symtab/Type.java index 7e94662d9a..3a95a2805d 100644 --- a/sources/scalac/symtab/Type.java +++ b/sources/scalac/symtab/Type.java @@ -186,7 +186,7 @@ public class Type implements Modifiers, Kinds, TypeTags { public Type widen() { switch (this) { case ThisType(Symbol sym): - return sym.type(); + return sym.typeOfThis(); case SingleType(Type pre, Symbol sym): // overridden in ExtSingleType throw new ApplicationError(); @@ -249,6 +249,30 @@ public class Type implements Modifiers, Kinds, TypeTags { } } + /** Get type of `this' symbol corresponding to this type, extend + * homomorphically to function types and method types. + */ + public Type instanceType() { + switch (unalias()) { + case TypeRef(Type pre, Symbol sym, Type[] args): + Type tp1 = sym.typeOfThis(); + if (tp1 != sym.type()) + return tp1.asSeenFrom(pre, sym.owner()).subst(sym.typeParams(), args); + break; + case MethodType(Symbol[] params, Type restp): + Type restp1 = restp.instanceType(); + if (restp1 != restp) + return MethodType(params, restp1); + break; + case PolyType(Symbol[] tparams, Type restp): + Type restp1 = restp.instanceType(); + if (restp1 != restp) + return PolyType(tparams, restp1); + break; + } + return this; + } + /** Remove all aliases */ public Type unalias() { @@ -261,9 +285,7 @@ public class Type implements Modifiers, Kinds, TypeTags { if (n == 20) throw new Type.Error("recursive type alias: " + this); switch (this) { case TypeRef(Type pre, Symbol sym, Type[] args): - if (sym.kind == ALIAS) { - return pre.memberInfo(sym).subst(sym.typeParams(), args).unalias(n + 1); - } + if (sym.kind == ALIAS) return pre.memberInfo(sym).unalias(n + 1); break; case TypeVar(Type origin, Constraint constr): if (constr.inst != NoType) return constr.inst.unalias(n + 1); @@ -303,8 +325,8 @@ public class Type implements Modifiers, Kinds, TypeTags { case PolyType(Symbol[] tparams, _): return tparams; case TypeRef(_, Symbol sym, _): - if (sym.kind == CLASS || sym.kind == ALIAS) return sym.typeParams(); - break; + if (sym.kind == CLASS) return sym.typeParams(); + else return sym.info().typeParams(); } return Symbol.EMPTY_ARRAY; } @@ -433,7 +455,7 @@ public class Type implements Modifiers, Kinds, TypeTags { public boolean isFunctionType() { switch (this) { case TypeRef(Type pre, Symbol sym, Type[] args): - if (sym.fullName().startsWith(Names.Function)) { + if (sym.fullName().startsWith(Names.scala_Function)) { for (int i = 0; i < args.length - 1; i++) if (args[i].isCovarType()) return false; return args.length > 0 && args[args.length - 1].isCovarType(); @@ -693,11 +715,8 @@ public class Type implements Modifiers, Kinds, TypeTags { case TypeRef(Type pre, Symbol sym, Type[] args): if (sym == clazz) return this; - else if (sym.kind == TYPE) + else if (sym.kind == TYPE || sym.kind == ALIAS) return pre.memberInfo(sym).baseType(clazz); - else if (sym.kind == ALIAS) - return pre.memberInfo(sym).baseType(clazz) - .subst(sym.typeParams(), args); else if (clazz.isCompoundSym()) return NoType; else @@ -811,14 +830,15 @@ public class Type implements Modifiers, Kinds, TypeTags { switch (pre.baseType(ownclass)) { case TypeRef(_, Symbol basesym, Type[] baseargs): Symbol[] baseparams = basesym.typeParams(); - for (int i = 0; i < baseparams.length; i++) - if (sym == baseparams[i]) return baseargs[i];//??? + for (int i = 0; i < baseparams.length; i++) { + if (sym == baseparams[i]) return baseargs[i]; + } break; case ErrorType: return ErrorType; } throw new ApplicationError( - this + " cannot be instantiated from " + pre); + this + " in " + ownclass + " cannot be instantiated from " + pre); } else { return toInstance( pre.baseType(clazz).prefix(), clazz.owner()); @@ -1115,8 +1135,8 @@ public class Type implements Modifiers, Kinds, TypeTags { */ public boolean containsSome(Symbol[] syms) { for (int i = 0; i < syms.length; i++) - if (contains(syms[i])) return false; - return true; + if (contains(syms[i])) return true; + return false; } // Comparisons ------------------------------------------------------------------ @@ -1789,6 +1809,7 @@ public class Type implements Modifiers, Kinds, TypeTags { e = e.next) { Name name = e.sym.name; if ((e.sym.flags & PRIVATE) == 0 && lubType.lookup(name) == e.sym) { + //todo: not memberType? Type symType = lubThisType.memberInfo(e.sym); int j = 0; while (j < tps.length) { @@ -2025,6 +2046,11 @@ public class Type implements Modifiers, Kinds, TypeTags { System.arraycopy(args, 0, params, 0, params.length); return ArrayApply.toString(params, "(", ",", ") => ") + args[params.length].dropVariance(); + } else if (sym.isAnonymousClass()) { + return "<template: " + + ArrayApply.toString( + pre.memberInfo(sym).parents(), "", "", " with ") + + "{...}>"; } } Type pre1 = (Global.instance.debug) ? pre : pre.expandModuleThis(); diff --git a/sources/scalac/symtab/classfile/AttributeParser.java b/sources/scalac/symtab/classfile/AttributeParser.java index 0ed09b44d0..a9e0790889 100644 --- a/sources/scalac/symtab/classfile/AttributeParser.java +++ b/sources/scalac/symtab/classfile/AttributeParser.java @@ -322,7 +322,7 @@ public class AttributeParser implements ClassfileConstants { types.toArray(args); return Type.TypeRef(clazz.owner().thisType(), clazz, args); } else { - return parser.defs.monoType(clazz); + return clazz.typeConstructor(); } } diff --git a/sources/scalac/symtab/classfile/ClassfileParser.java b/sources/scalac/symtab/classfile/ClassfileParser.java index 686b832459..61b7c88691 100644 --- a/sources/scalac/symtab/classfile/ClassfileParser.java +++ b/sources/scalac/symtab/classfile/ClassfileParser.java @@ -53,7 +53,7 @@ public class ClassfileParser implements ClassfileConstants { this.global = global; this.in = in; this.c = c; - this.ctype = Type.TypeRef(c.owner().thisType(), c, Type.EMPTY_ARRAY); + this.ctype = c.typeConstructor(); this.make = new JavaTypeCreator(global); this.sigs = new Signatures(global, make); this.pool = new ConstantPool(in, sigs); |