diff options
Diffstat (limited to 'sources/scalac')
-rw-r--r-- | sources/scalac/symtab/Type.java | 9 | ||||
-rw-r--r-- | sources/scalac/transformer/AddInterfaces.java | 8 | ||||
-rw-r--r-- | sources/scalac/typechecker/Analyzer.java | 61 | ||||
-rw-r--r-- | sources/scalac/typechecker/Infer.java | 6 | ||||
-rw-r--r-- | sources/scalac/typechecker/RefCheck.java | 2 |
5 files changed, 61 insertions, 25 deletions
diff --git a/sources/scalac/symtab/Type.java b/sources/scalac/symtab/Type.java index 9af1ea5244..578aeb3451 100644 --- a/sources/scalac/symtab/Type.java +++ b/sources/scalac/symtab/Type.java @@ -1139,6 +1139,7 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags { } Type toPrefix(Symbol sym, Type pre, Symbol clazz) { + //System.out.println(this + ".toPrefix(" + sym + "," + pre + "," + clazz + ")");//DEBUG if (pre == NoType || clazz.kind != CLASS) return this; else if (sym.isSubClass(clazz) && @@ -1795,6 +1796,14 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags { if (alttypes[i].isSubType(that)) return true; } break; + + case CompoundType(Type[] parts, Scope members): + int i = 0; + while (i < parts.length) { + if (parts[i].isSubType(that)) return true; + i++; + } + break; } switch (that) { diff --git a/sources/scalac/transformer/AddInterfaces.java b/sources/scalac/transformer/AddInterfaces.java index 497b7a4feb..46650b7a2a 100644 --- a/sources/scalac/transformer/AddInterfaces.java +++ b/sources/scalac/transformer/AddInterfaces.java @@ -240,7 +240,13 @@ class AddInterfaces extends Transformer { case New(Template templ): { Tree.New newTree = (Tree.New)super.transform(tree); - Symbol ifaceSym = newTree.type.unalias().symbol(); + Type tp = newTree.type; + switch (tp) { + case CompoundType(Type[] parts, _): tp = parts[0]; + // gross hack to prevent crashing when selftypes are compound; + // should be fixed! + } + Symbol ifaceSym = tp.unalias().symbol(); if (phase.needInterface(ifaceSym)) { Map clsMap = new HashMap(); Symbol classSym = phase.getClassSymbol(ifaceSym); diff --git a/sources/scalac/typechecker/Analyzer.java b/sources/scalac/typechecker/Analyzer.java index 595f1e462c..9797825f8e 100644 --- a/sources/scalac/typechecker/Analyzer.java +++ b/sources/scalac/typechecker/Analyzer.java @@ -606,6 +606,14 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { else throw new ApplicationError(); } + private boolean isSetterMethod(Symbol sym) { + return sym != null && + !sym.isLocal() && + !sym.isStable() && + sym.type() instanceof Type.PolyType && + sym.typeParams().length == 0; + } + // Contexts ------------------------------------------------------------------- /** Push new context associated with given tree, owner, and scope on stack. @@ -661,11 +669,13 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { /** A lazy type for self types */ class LazySelfType extends LazyTreeType { - LazySelfType(Tree tree) { + Symbol clazz; + LazySelfType(Symbol clazz, Tree tree) { super(tree); + this.clazz = clazz; } public void complete(Symbol sym) { - defineSelfType(sym, tree, u, c); + defineSelfType(sym, clazz, tree, u, c); } } @@ -1004,7 +1014,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { sym.primaryConstructor().flags |= INITIALIZED; if (tpe != Tree.Empty) - sym.setTypeOfThis(new LazySelfType(tpe)); + sym.setTypeOfThis(new LazySelfType(sym, tpe)); defineTemplate(templ, sym, new Scope()); owntype = templ.type; @@ -1017,7 +1027,7 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { clazz.setInfo(templ.type); ((ModuleDef) tree).tpe = tpe = transform(tpe, TYPEmode); if (tpe != Tree.Empty) - clazz.setTypeOfThis(new LazySelfType(tpe)); + clazz.setTypeOfThis(new LazySelfType(sym, tpe)); owntype = (tpe == Tree.Empty) ? clazz.type() : tpe.type; break; @@ -1171,13 +1181,17 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { /** Define self type of class or module `sym' * associated with `tree' using given `unit' and `context'. */ - void defineSelfType(Symbol sym, Tree tree, Unit unit, Context curcontext) { + void defineSelfType(Symbol sym, Symbol clazz, Tree tree, Unit unit, Context curcontext) { Unit savedUnit = this.unit; this.unit = unit; Context savedContext = this.context; this.context = curcontext; - sym.setInfo(transform(tree, TYPEmode).type); + Type selftype = transform(tree, TYPEmode).type; + + sym.setInfo( + Type.compoundType( + new Type[]{selftype, clazz.type()}, Scope.EMPTY)); this.unit = savedUnit; this.context= savedContext; @@ -1352,18 +1366,20 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { owntype.isSubType(pt))) { switch (tree) { case Literal(Object value): - if (value instanceof Integer) { - int n = ((Integer) value).intValue(); - if (pt.symbol() == definitions.BYTE_CLASS && - -128 <= n && n <= 127) - return copy.Literal(tree, new Byte((byte) n)).setType(pt); - else if (pt.symbol() == definitions.SHORT_CLASS && - -32768 <= n && n <= 32767) - return copy.Literal(tree, new Short((short) n)).setType(pt); - else if (pt.symbol() == definitions.CHAR_CLASS && - 0 <= n && n <= 65535) - return copy.Literal(tree, new Character((char) n)).setType(pt); - } + int n = Integer.MAX_VALUE; + if (value instanceof Integer) + n = ((Integer) value).intValue(); + else if (value instanceof Character) + n = ((Character) value).charValue(); + if (pt.symbol() == definitions.BYTE_CLASS && + -128 <= n && n <= 127) + return copy.Literal(tree, new Byte((byte) n)).setType(pt); + else if (pt.symbol() == definitions.SHORT_CLASS && + -32768 <= n && n <= 32767) + return copy.Literal(tree, new Short((short) n)).setType(pt); + else if (pt.symbol() == definitions.CHAR_CLASS && + 0 <= n && n <= 65535) + return copy.Literal(tree, new Character((char) n)).setType(pt); } typeError(tree.pos, owntype, pt); Type.explainTypes(owntype, pt); @@ -2039,14 +2055,15 @@ public class Analyzer extends Transformer implements Modifiers, Kinds { case Assign(Tree lhs, Tree rhs): Tree lhs1 = transform(lhs, EXPRmode); Symbol varsym = lhs1.symbol(); - if (varsym != null && (varsym.flags & ACCESSOR) != 0) { + if (isSetterMethod(varsym)) { + // todo: change this to require setters in same template return transform(desugarize.Assign(tree.pos, lhs, rhs)); - } else if (varsym == null || (varsym.flags & MUTABLE) == 0) { - return error(tree.pos, "assignment to non-variable"); - } else { + } else if (varsym != null && (varsym.flags & MUTABLE) != 0) { Tree rhs1 = transform(rhs, EXPRmode, lhs1.type); return copy.Assign(tree, lhs1, rhs1) .setType(definitions.UNIT_TYPE); + } else { + return error(tree.pos, "assignment to non-variable"); } case If(Tree cond, Tree thenp, Tree elsep): diff --git a/sources/scalac/typechecker/Infer.java b/sources/scalac/typechecker/Infer.java index befd1d151c..b23890f0d0 100644 --- a/sources/scalac/typechecker/Infer.java +++ b/sources/scalac/typechecker/Infer.java @@ -958,7 +958,9 @@ public class Infer implements Modifiers, Kinds { * If several applicable alternatives exist, take the * most specialized one, or throw an error if no * most specialized applicable alternative exists. - * If no alternative matches, leave `tree' unchanged. + * If no alternative matches, leave `tree' unchanged, + * try to select method with pt = AnyType. + * If pt is AnyType, leave tree unchanged. */ public void methodAlternative(Tree tree, Symbol[] alts, Type[] alttypes, Type[] argtypes, Type pt) @@ -988,6 +990,8 @@ public class Infer implements Modifiers, Kinds { } } tree.setSymbol(alts[best]).setType(alttypes[best]); + } else if (pt != Type.AnyType) { + methodAlternative(tree, alts, alttypes, argtypes, Type.AnyType); } } diff --git a/sources/scalac/typechecker/RefCheck.java b/sources/scalac/typechecker/RefCheck.java index d6ff53bb84..1f4b75ed09 100644 --- a/sources/scalac/typechecker/RefCheck.java +++ b/sources/scalac/typechecker/RefCheck.java @@ -92,7 +92,7 @@ public class RefCheck extends Transformer implements Modifiers, Kinds { sym.overriddenSymbol(parents[0]).kind == NONE) { unit.error(sym.pos, sym + " does not override a superclass member in " + - parents[0]); + parents); } } } |