From 91d92ec83bdfdebc2e97eda5b34fdc4b10cdfecc Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Mon, 12 Jan 2009 12:59:26 +0000 Subject: parses syntax for package objects --- .../scala/tools/nsc/ast/parser/Parsers.scala | 43 +++++++++++++--------- .../scala/tools/nsc/transform/Flatten.scala | 2 + .../scala/tools/nsc/typechecker/IdeSupport.scala | 4 +- .../scala/tools/nsc/typechecker/Namers.scala | 3 +- .../scala/tools/nsc/typechecker/Typers.scala | 22 +++++------ .../generic/mutable/VectorTemplate.scala | 2 +- 6 files changed, 43 insertions(+), 33 deletions(-) (limited to 'src') diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala index 83dd4e3145..6a41a36005 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala @@ -2336,9 +2336,7 @@ trait Parsers extends NewScanners with MarkupParsers { /** Packaging ::= package QualId [nl] `{' TopStatSeq `}' */ - def packaging(): Tree = { - - val pkgPos = accept(PACKAGE) + def packaging(pkgPos: Int): Tree = { val pkg = qualId() val pos = if (pkg.pos != NoPosition) pkg.pos else i2p(pkgPos) atPos(pos) { @@ -2353,6 +2351,7 @@ trait Parsers extends NewScanners with MarkupParsers { /** TopStatSeq ::= TopStat {semi TopStat} * TopStat ::= Annotations Modifiers TmplDef * | Packaging + * | package object objectDef * | Import * | */ @@ -2360,7 +2359,9 @@ trait Parsers extends NewScanners with MarkupParsers { val stats = new ListBuffer[Tree] while (inToken != RBRACE && inToken != EOF) { if (inToken == PACKAGE) { - stats += packaging() + val pkgPos = accept(PACKAGE) + stats += (if (inToken == OBJECT) objectDef(Modifiers(Flags.PACKAGE)) + else packaging(pkgPos)) } else if (inToken == IMPORT) { stats ++= importClause() // XXX: IDE hook this all. @@ -2516,19 +2517,27 @@ trait Parsers extends NewScanners with MarkupParsers { while (inToken == SEMI) inNextToken if (inToken == PACKAGE) { inNextToken - val pkg = qualId() - newLineOptWhenFollowedBy(LBRACE) - if (inToken == EOF) { - ts += makePackaging(pkg, List()) - } else if (isStatSep) { - inNextToken - ts += makePackaging(pkg, topStatSeq()) - } else { - accept(LBRACE) - ts += makePackaging(pkg, topStatSeq()) - accept(RBRACE) - ts ++= topStatSeq() - } + if (in.token == OBJECT) { + ts += objectDef(Modifiers(Flags.PACKAGE)) + if (inToken != EOF) { + acceptStatSep() + ts ++= topStatSeq() + } + } else { + val pkg = qualId() + newLineOptWhenFollowedBy(LBRACE) + if (inToken == EOF) { + ts += makePackaging(pkg, List()) + } else if (isStatSep) { + inNextToken + ts += makePackaging(pkg, topStatSeq()) + } else { + accept(LBRACE) + ts += makePackaging(pkg, topStatSeq()) + accept(RBRACE) + ts ++= topStatSeq() + } + } } else { ts ++= topStatSeq() } diff --git a/src/compiler/scala/tools/nsc/transform/Flatten.scala b/src/compiler/scala/tools/nsc/transform/Flatten.scala index ae695f587f..d4caa9790a 100644 --- a/src/compiler/scala/tools/nsc/transform/Flatten.scala +++ b/src/compiler/scala/tools/nsc/transform/Flatten.scala @@ -78,6 +78,8 @@ abstract class Flatten extends InfoTransform { tree match { case PackageDef(_, _) => liftedDefs(tree.symbol.moduleClass) = new ListBuffer + case Template(_, _, _) if (tree.symbol.owner.hasFlag(PACKAGE)) => + liftedDefs(tree.symbol.owner) = new ListBuffer case _ => } postTransform(super.transform(tree)) diff --git a/src/compiler/scala/tools/nsc/typechecker/IdeSupport.scala b/src/compiler/scala/tools/nsc/typechecker/IdeSupport.scala index c436ea8670..08bba9f6e1 100644 --- a/src/compiler/scala/tools/nsc/typechecker/IdeSupport.scala +++ b/src/compiler/scala/tools/nsc/typechecker/IdeSupport.scala @@ -99,8 +99,8 @@ trait IdeSupport extends Analyzer { } override def newTyper(txt : Context) : Typer = new Typer(txt) class Typer(context : Context) extends super.Typer(context) { - override def qualifyingClassContext(tree: Tree, qual: Name): Context = { - if (qual.isEmpty) super.qualifyingClassContext(tree, qual) + override def qualifyingClassContext(tree: Tree, qual: Name, packageOK: Boolean): Context = { + if (qual.isEmpty) super.qualifyingClassContext(tree, qual, packageOK) else { var c = context.enclClass val client = currentClient diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala index c79cdfc65f..adab0faebf 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala @@ -55,11 +55,10 @@ trait Namers { self: Analyzer => def setPrivateWithin[Sym <: Symbol](tree: Tree, sym: Sym, mods: Modifiers): Sym = { if (!mods.privateWithin.isEmpty) - sym.privateWithin = typer.qualifyingClassContext(tree, mods.privateWithin).owner + sym.privateWithin = typer.qualifyingClassContext(tree, mods.privateWithin, true).owner sym } - def inConstructorFlag: Long = if (context.owner.isConstructor && !context.inConstructorSuffix || context.owner.isEarly) INCONSTRUCTOR else 0l diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index c6bda776ff..2c399b60d9 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -484,17 +484,17 @@ trait Typers { self: Analyzer => * @param qual ... * @return ... */ - def qualifyingClassContext(tree: Tree, qual: Name): Context = { - if (qual.isEmpty) { - if (context.enclClass.owner.isPackageClass) - error(tree.pos, tree+" can be used only in a class, object, or template") - context.enclClass - } else { - var c = context.enclClass + def qualifyingClassContext(tree: Tree, qual: Name, packageOK: Boolean): Context = { + var c = context.enclClass + if (!qual.isEmpty) { while (c != NoContext && c.owner.name != qual) c = c.outer.enclClass - if (c == NoContext) error(tree.pos, qual+" is not an enclosing class") - c } + if (c == NoContext || !(packageOK || c.enclClass.tree.isInstanceOf[Template])) + error( + tree.pos, + if (qual.isEmpty) tree+" can be used only in a class, object, or template" + else qual+" is not an enclosing class") + c } /** The typer for an expression, depending on where we are. If we are before a superclass @@ -2739,7 +2739,7 @@ trait Typers { self: Analyzer => if (tree.symbol != NoSymbol) { (tree.symbol, tree.symbol.thisType) } else { - val clazzContext = qualifyingClassContext(tree, qual) + val clazzContext = qualifyingClassContext(tree, qual, false) (clazzContext.owner, clazzContext.prefix) } if (clazz == NoSymbol) setError(tree) @@ -2781,7 +2781,7 @@ trait Typers { self: Analyzer => if (tree.symbol != NoSymbol) { (tree.symbol, tree.symbol.thisType) } else { - val clazzContext = qualifyingClassContext(tree, qual) + val clazzContext = qualifyingClassContext(tree, qual, false) (clazzContext.owner, clazzContext.prefix) } if (clazz == NoSymbol) setError(tree) diff --git a/src/library/scalax/collection/generic/mutable/VectorTemplate.scala b/src/library/scalax/collection/generic/mutable/VectorTemplate.scala index 3d25f29363..b99600948a 100644 --- a/src/library/scalax/collection/generic/mutable/VectorTemplate.scala +++ b/src/library/scalax/collection/generic/mutable/VectorTemplate.scala @@ -18,7 +18,7 @@ import collection.mutable.Vector._ * @author Martin Odersky * @version 2.8 */ -trait VectorTemplate[+CC[B] <: VectorTemplate[CC, B] with Vector[B], A] extends nonvariant.VectorTemplate[CC, A] { +trait VectorTemplate[+CC[B] <: VectorTemplate[CC, B] with Vector[B], A] extends generic.VectorTemplate[CC, A] { self => def update(idx: Int, elem: A) -- cgit v1.2.3