diff options
-rw-r--r-- | doc/reference/ReferencePart.tex | 5 | ||||
-rw-r--r-- | sources/scala/tools/scalac/ast/parser/Parser.scala | 2 | ||||
-rw-r--r-- | sources/scala/tools/scalac/typechecker/Analyzer.scala | 108 | ||||
-rw-r--r-- | sources/scala/tools/scalac/typechecker/Infer.scala | 4 | ||||
-rw-r--r-- | sources/scalac/symtab/Type.java | 1 | ||||
-rw-r--r-- | sources/scalac/symtab/classfile/UnPickle.java | 5 | ||||
-rw-r--r-- | sources/scalac/typechecker/RefCheck.java | 2 |
7 files changed, 68 insertions, 59 deletions
diff --git a/doc/reference/ReferencePart.tex b/doc/reference/ReferencePart.tex index 13f3f90c82..eb665d0167 100644 --- a/doc/reference/ReferencePart.tex +++ b/doc/reference/ReferencePart.tex @@ -279,8 +279,9 @@ A {\em stable identifier} is a path which ends in an identifier. \end{lstlisting} A singleton type is of the form \lstinline@$p$.type@, where $p$ is a -path. The type denotes the set of values consisting of -exactly the value denoted by $p$. +path pointing to a value expected to conform to +\lstinline@scala.AnyRef@. The type denotes the set of values +consisting of the value denoted by $p$ and \lstinline@null@. \subsection{Type Projection} \label{sec:type-project} diff --git a/sources/scala/tools/scalac/ast/parser/Parser.scala b/sources/scala/tools/scalac/ast/parser/Parser.scala index 05665e4a5e..753b82181d 100644 --- a/sources/scala/tools/scalac/ast/parser/Parser.scala +++ b/sources/scala/tools/scalac/ast/parser/Parser.scala @@ -1998,8 +1998,6 @@ class Parser(unit: Unit) { isModifier()) { stats.append(joinComment(clsDef(modifiers()))); } else if (s.token != SEMI) { - System.out.println(s.token); - System.out.println(s.name); syntaxError("illegal start of class or object definition", true); } if (s.token != RBRACE && s.token != EOF) accept(SEMI); diff --git a/sources/scala/tools/scalac/typechecker/Analyzer.scala b/sources/scala/tools/scalac/typechecker/Analyzer.scala index 68594cbb81..81c5755987 100644 --- a/sources/scala/tools/scalac/typechecker/Analyzer.scala +++ b/sources/scala/tools/scalac/typechecker/Analyzer.scala @@ -1095,10 +1095,6 @@ class Analyzer(global: scalac_Global, descr: AnalyzerPhase) extends Transformer( var rhs = _rhs; var restype: Type = null; pushContext(tree, sym, new Scope(context.scope)); - if (name == Names.CONSTRUCTOR) { - context.enclClass.owner.flags = - context.enclClass.owner.flags | INCONSTRUCTOR; - } val tparamSyms = enterParams(tparams); val vparamSyms = enterParams(vparams); if (tpe != Tree.Empty) { @@ -1110,8 +1106,6 @@ class Analyzer(global: scalac_Global, descr: AnalyzerPhase) extends Transformer( error(tree.pos, "secondary constructors for parameterized classes not yet implemented"); restype = context.enclClass.owner.getType();/*.subst( context.enclClass.owner.typeParams(), tparamSyms)*/; - context.enclClass.owner.flags = - context.enclClass.owner.flags & ~INCONSTRUCTOR; } else { rhs = transform(rhs, EXPRmode); (tree.asInstanceOf[Tree$DefDef]).rhs = rhs; @@ -1323,6 +1317,32 @@ class Analyzer(global: scalac_Global, descr: AnalyzerPhase) extends Transformer( tree } + /** The qualifying class of a this or super + */ + def qualifyingClass(tree: Tree, name: Name): Symbol = { + if (name == TypeNames.EMPTY) { + val clazz: Symbol = context.enclClass.owner; + if (clazz != null) + clazz + else { + error(tree.pos, "" + tree + + " can be used only in a class, object, or template"); + Symbol.NONE + } + } else { + var i: Context = context; + while (i != Context.NONE && + !(i.owner.kind == CLASS && i.owner.name == name)) + i = i.outer; + if (i != Context.NONE) + i.owner + else { + error(tree.pos, "" + name + " is not an enclosing class"); + Symbol.NONE + } + } + } + /** Adapt tree to given mode and given prototype */ def adapt(tree: Tree, mode: int, pt: Type): Tree = { @@ -1616,10 +1636,10 @@ class Analyzer(global: scalac_Global, descr: AnalyzerPhase) extends Transformer( var symtype: Type = (if (sym.isType()) sym.typeConstructor() else sym.getType()) .asSeenFrom(pre, sym.owner()); - if (qual != Tree.Empty) - symtype = infer.checkAccessible(tree.pos, sym, symtype, qual, qual.getType()); - else if (sym.owner().isPackageClass()) - symtype = infer.checkAccessible(tree.pos, sym, symtype, qual, sym.owner().getType()); + symtype = infer.checkAccessible( + tree.pos, sym, symtype, qual, + if (qual == Tree.Empty && sym.owner().isPackageClass()) sym.owner().getType() + else qual.getType()); if (symtype == Type.NoType) { error(tree.pos, "not found: " + decode(name)); return errorTree(tree); @@ -2041,16 +2061,6 @@ class Analyzer(global: scalac_Global, descr: AnalyzerPhase) extends Transformer( if (sym != null && !sym.isInitialized()) sym.initialize(); if (global.debug && TreeInfo.isDefinition(tree)) global.log("transforming definition of " + sym); try { - transform0(tree, sym); - } catch { - case ex: Type$Error => - reportTypeError(tree.pos, ex); - errorTree(tree) - } - } - - // extracted from transform to avoid overflows in GenJVM - private def transform0(tree: Tree, sym: Symbol): Tree = { tree match { case Tree.Empty => tree.setType(Type.NoType) @@ -2105,8 +2115,13 @@ class Analyzer(global: scalac_Global, descr: AnalyzerPhase) extends Transformer( case Tree$DefDef(_, name, tparams, vparams, tpe, rhs) => pushContext(tree, sym, new Scope(context.scope)); reenterParams(tparams, vparams, sym.getType()); - if (name == Names.CONSTRUCTOR) - context.enclClass.owner.flags = context.enclClass.owner.flags | INCONSTRUCTOR; + if (name == Names.CONSTRUCTOR) { + val enclClass = context.enclClass.owner; + enclClass.flags = + enclClass.flags | INCONSTRUCTOR; + enclClass.primaryConstructor().flags = + enclClass.primaryConstructor().flags | INCONSTRUCTOR; + } val tparams1 = transform(tparams); val vparams1 = transform(vparams); checkNoEscapeParams(vparams1); @@ -2120,7 +2135,13 @@ class Analyzer(global: scalac_Global, descr: AnalyzerPhase) extends Transformer( if (name == Names.CONSTRUCTOR) CONSTRmode else EXPRmode, if (name == Names.CONSTRUCTOR) definitions.UNIT_TYPE() else tpe1.getType()); popContext(); - context.enclClass.owner.flags = context.enclClass.owner.flags & ~INCONSTRUCTOR; + if (name == Names.CONSTRUCTOR) { + val enclClass = context.enclClass.owner; + enclClass.flags = + enclClass.flags & ~ INCONSTRUCTOR; + enclClass.primaryConstructor().flags = + enclClass.primaryConstructor().flags & ~ INCONSTRUCTOR; + } sym.flags = sym.flags | LOCKED; checkNonCyclic(tree.pos, tpe1.getType()); sym.flags = sym.flags & ~LOCKED; @@ -2166,6 +2187,7 @@ class Analyzer(global: scalac_Global, descr: AnalyzerPhase) extends Transformer( case Tree$Import(expr, selectors) => context.imports = new ImportList(tree, context.scope, context.imports); Tree.Empty +/* case _ => transform1(tree, sym) @@ -2175,31 +2197,8 @@ class Analyzer(global: scalac_Global, descr: AnalyzerPhase) extends Transformer( // extracted from transform0 to avoid overflows in GenJVM private def transform1(tree: Tree, sym: Symbol): Tree = { - def qualifyingClass(tree: Tree, name: Name): Symbol = { - if (name == TypeNames.EMPTY) { - val clazz: Symbol = context.enclClass.owner; - if (clazz != null) - clazz - else { - error(tree.pos, "" + tree + - " can be used only in a class, object, or template"); - Symbol.NONE - } - } else { - var i: Context = context; - while (i != Context.NONE && - !(i.owner.kind == CLASS && i.owner.name == name)) - i = i.outer; - if (i != Context.NONE) - i.owner - else { - error(tree.pos, "" + name + " is not an enclosing class"); - Symbol.NONE - } - } - } - tree match { +*/ case Tree$Block(stats, value) => pushContext(tree, context.owner, new Scope(context.scope)); val stats1 = desugarize.Statements(unit, stats, true); @@ -2366,6 +2365,7 @@ class Analyzer(global: scalac_Global, descr: AnalyzerPhase) extends Transformer( val sym1: Symbol = it.next(); val basesym1: Symbol = base.lookupNonPrivate(sym1.name); if (!basesym1.isNone() && + sym1.kind != VAL && // todo: remove once refinements work! !base.symbol().thisType().memberType(basesym1) .isSameAs(sym1.getType())) refinement.enter(sym1); @@ -2804,9 +2804,10 @@ class Analyzer(global: scalac_Global, descr: AnalyzerPhase) extends Transformer( tree case Tree$SingletonType(ref) => - val ref1: Tree = transform(ref, EXPRmode | QUALmode, Type.AnyType); + val ref1: Tree = checkStable( + transform(ref, EXPRmode | QUALmode, definitions.ANYREF_TYPE())); copy.SingletonType(tree, ref1) - .setType(checkObjectType(tree.pos, ref1.getType().resultType())); + .setType(ref1.getType().resultType()); case Tree$SelectFromType(qual, name) => val qual1: Tree = transform(qual, TYPEmode); @@ -2823,7 +2824,9 @@ class Analyzer(global: scalac_Global, descr: AnalyzerPhase) extends Transformer( i = i + 1 }} val members: Scope = new Scope(); - val self: Type = Type.compoundTypeWithOwner(context.enclClass.owner, ptypes, members); + val cowner = if (context.owner.isPrimaryConstructor()) context.owner.constructorClass() + else context.enclClass.owner; + val self: Type = Type.compoundTypeWithOwner(cowner, ptypes, members); val clazz: Symbol = self.symbol(); pushContext(tree, clazz, members); { var i = 0; while (i < refinements.length) { @@ -2859,6 +2862,11 @@ class Analyzer(global: scalac_Global, descr: AnalyzerPhase) extends Transformer( case _ => throw new ApplicationError("illegal tree: " + tree) } + } catch { + case ex: Type$Error => + reportTypeError(tree.pos, ex); + errorTree(tree) + } } } } diff --git a/sources/scala/tools/scalac/typechecker/Infer.scala b/sources/scala/tools/scalac/typechecker/Infer.scala index 59f2a042ac..2b7b8812ed 100644 --- a/sources/scala/tools/scalac/typechecker/Infer.scala +++ b/sources/scala/tools/scalac/typechecker/Infer.scala @@ -180,7 +180,7 @@ class Infer(global: scalac_Global, gen: TreeGen, make: TreeFactory) extends scal //System.out.println("check acc " + sym);//DEBUG if ((sym.owner().flags & INCONSTRUCTOR) != 0 && !(sym.kind == TYPE && sym.isParameter()) && - site.isInstanceOf[Tree$This]) { + (site == Tree.Empty || site.isInstanceOf[Tree$This])) { error(pos, "" + sym + " cannot be accessed from constructor"); Type.ErrorType; } else { @@ -244,6 +244,8 @@ class Infer(global: scalac_Global, gen: TreeGen, make: TreeFactory) extends scal c != Context.NONE; } + site == Tree.Empty + || (sym.flags & (PRIVATE | PROTECTED)) == 0 || {val owner = if (sym.isConstructor()) sym.constructorClass() diff --git a/sources/scalac/symtab/Type.java b/sources/scalac/symtab/Type.java index 4bff125e53..7d23ab99e3 100644 --- a/sources/scalac/symtab/Type.java +++ b/sources/scalac/symtab/Type.java @@ -270,6 +270,7 @@ public class Type implements Modifiers, Kinds, TypeTags, EntryTags { public ExtCompoundType(Symbol owner, Type[] parts, Scope members) { super(parts, members); this.clasz = owner.newCompoundClass(this); + assert !owner.isPackageClass() : ArrayApply.toString(parts); } public ExtCompoundType(Type[] parts, Scope members, Symbol clasz) { super(parts, members); diff --git a/sources/scalac/symtab/classfile/UnPickle.java b/sources/scalac/symtab/classfile/UnPickle.java index 9579458394..a6d84b8e3c 100644 --- a/sources/scalac/symtab/classfile/UnPickle.java +++ b/sources/scalac/symtab/classfile/UnPickle.java @@ -387,10 +387,9 @@ public class UnPickle implements Kinds, Modifiers, EntryTags, TypeTags { readTypeRef(owner), readSymbolRef(), readTypeRefs(end, owner)); break; case COMPOUNDtpe: - Symbol[] clazzs = readSymbolRefs(end); - assert clazzs.length == 1; + Symbol clazz = readSymbolRef(); Type[] parents = readTypeRefs(end, owner); - tpe = Type.compoundType(parents, new Scope(), clazzs[0]); + tpe = Type.compoundType(parents, new Scope(), clazz); break; case METHODtpe: Type restype = readTypeRef(owner); diff --git a/sources/scalac/typechecker/RefCheck.java b/sources/scalac/typechecker/RefCheck.java index f7649a9792..c57361a670 100644 --- a/sources/scalac/typechecker/RefCheck.java +++ b/sources/scalac/typechecker/RefCheck.java @@ -158,7 +158,7 @@ public class RefCheck extends Transformer implements Modifiers, Kinds { : "\n(Note that variables need to be initialized to be defined)")); } else if (member.isAbstractOverride()) { Type superclazz = clazz.parents()[0]; - Symbol sup = member.overriddenSymbol(superclazz); + Symbol sup = member.overriddenSymbol(superclazz, clazz); if (clazz.kind == CLASS && (clazz.flags & ABSTRACT) == 0 && isIncomplete(sup)) { abstractClassError( |