diff options
Diffstat (limited to 'src')
10 files changed, 94 insertions, 25 deletions
diff --git a/src/compiler/scala/reflect/macros/contexts/Parsers.scala b/src/compiler/scala/reflect/macros/contexts/Parsers.scala index ae6488b5a8..88cfea8157 100644 --- a/src/compiler/scala/reflect/macros/contexts/Parsers.scala +++ b/src/compiler/scala/reflect/macros/contexts/Parsers.scala @@ -11,7 +11,7 @@ trait Parsers { val sreporter = new StoreReporter() val unit = new CompilationUnit(newSourceFile(code, "<macro>")) { override def reporter = sreporter } val parser = newUnitParser(unit) - val tree = gen.mkTreeOrBlock(parser.parseStats()) + val tree = gen.mkTreeOrBlock(parser.parseStatsOrPackages()) sreporter.infos.foreach { case sreporter.Info(pos, msg, sreporter.ERROR) => throw ParseException(pos, msg) } diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala index b1fcb67a9f..508453d5b2 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala @@ -346,9 +346,10 @@ self => */ def parse(): Tree = parseRule(_.parseStartRule()) - /** This is alternative entry point for repl, script runner, toolbox and quasiquotes. + /** These are alternative entry points for repl, script runner, toolbox and parsing in macros. */ def parseStats(): List[Tree] = parseRule(_.templateStats()) + def parseStatsOrPackages(): List[Tree] = parseRule(_.templateOrTopStatSeq()) /** This is the parse entry point for code which is not self-contained, e.g. * a script which is a series of template statements. They will be @@ -2743,10 +2744,9 @@ self => */ def packageObjectDef(start: Offset): PackageDef = { val defn = objectDef(in.offset, NoMods) - val module = copyModuleDef(defn)(name = nme.PACKAGEkw) - val pid = atPos(o2p(defn.pos.start))(Ident(defn.name)) - - makePackaging(start, pid, module :: Nil) + val pidPos = o2p(defn.pos.startOrPoint) + val pkgPos = r2p(start, pidPos.point) + gen.mkPackageObject(defn, pidPos, pkgPos) } def packageOrPackageObject(start: Offset): Tree = ( if (in.token == OBJECT) @@ -2989,6 +2989,8 @@ self => statement(InTemplate) :: Nil } + def templateOrTopStatSeq(): List[Tree] = statSeq(templateStat.orElse(topStat)) + /** {{{ * RefineStatSeq ::= RefineStat {semi RefineStat} * RefineStat ::= Dcl diff --git a/src/compiler/scala/tools/reflect/ToolBoxFactory.scala b/src/compiler/scala/tools/reflect/ToolBoxFactory.scala index fdc2613810..9e5a97270d 100644 --- a/src/compiler/scala/tools/reflect/ToolBoxFactory.scala +++ b/src/compiler/scala/tools/reflect/ToolBoxFactory.scala @@ -280,7 +280,7 @@ abstract class ToolBoxFactory[U <: JavaUniverse](val u: U) { factorySelf => def parse(code: String): Tree = { reporter.reset() - val tree = gen.mkTreeOrBlock(newUnitParser(code, "<toolbox>").parseStats()) + val tree = gen.mkTreeOrBlock(newUnitParser(code, "<toolbox>").parseStatsOrPackages()) throwIfErrors() tree } diff --git a/src/compiler/scala/tools/reflect/quasiquotes/Parsers.scala b/src/compiler/scala/tools/reflect/quasiquotes/Parsers.scala index 5a1a25cfa1..7abf8b9964 100644 --- a/src/compiler/scala/tools/reflect/quasiquotes/Parsers.scala +++ b/src/compiler/scala/tools/reflect/quasiquotes/Parsers.scala @@ -140,11 +140,18 @@ trait Parsers { self: Quasiquotes => case Ident(name) if isHole(name) => true case _ => false }) + + override def topStat = super.topStat.orElse { + case _ if isHole => + val stats = ValDef(NoMods, in.name, Ident(tpnme.QUASIQUOTE_PACKAGE_STAT), EmptyTree) :: Nil + in.nextToken() + stats + } } } object TermParser extends Parser { - def entryPoint = { parser => gen.mkTreeOrBlock(parser.templateStats()) } + def entryPoint = { parser => gen.mkTreeOrBlock(parser.templateOrTopStatSeq()) } } object TypeParser extends Parser { diff --git a/src/compiler/scala/tools/reflect/quasiquotes/Placeholders.scala b/src/compiler/scala/tools/reflect/quasiquotes/Placeholders.scala index c2b219ee31..d74350cad8 100644 --- a/src/compiler/scala/tools/reflect/quasiquotes/Placeholders.scala +++ b/src/compiler/scala/tools/reflect/quasiquotes/Placeholders.scala @@ -146,4 +146,11 @@ trait Placeholders { self: Quasiquotes => case _ => None } } + + object PackageStatPlaceholder { + def unapply(tree: Tree): Option[(Tree, Location, Cardinality)] = tree match { + case ValDef(NoMods, Placeholder(tree, location, card), Ident(tpnme.QUASIQUOTE_PACKAGE_STAT), EmptyTree) => Some((tree, location, card)) + case _ => None + } + } }
\ No newline at end of file diff --git a/src/compiler/scala/tools/reflect/quasiquotes/Reifiers.scala b/src/compiler/scala/tools/reflect/quasiquotes/Reifiers.scala index 18999e8267..6f5bf88549 100644 --- a/src/compiler/scala/tools/reflect/quasiquotes/Reifiers.scala +++ b/src/compiler/scala/tools/reflect/quasiquotes/Reifiers.scala @@ -7,10 +7,8 @@ import scala.reflect.internal.Flags._ trait Reifiers { self: Quasiquotes => import global._ - import global.build.{SyntacticClassDef, SyntacticTraitDef, SyntacticModuleDef, - SyntacticDefDef, SyntacticValDef, SyntacticVarDef, - SyntacticBlock, SyntacticApplied, SyntacticTypeApplied, - SyntacticFunction, SyntacticNew, SyntacticAssign} + import global.build.{Select => _, Ident => _, _} + import global.treeInfo._ import global.definitions._ import Cardinality._ import universeTypes._ @@ -51,6 +49,7 @@ trait Reifiers { self: Quasiquotes => case CasePlaceholder(tree, location, _) => reifyCase(tree, location) case RefineStatPlaceholder(tree, _, _) => reifyRefineStat(tree) case EarlyDefPlaceholder(tree, _, _) => reifyEarlyDef(tree) + case PackageStatPlaceholder(tree, _, _) => reifyPackageStat(tree) case _ => EmptyTree } @@ -60,8 +59,10 @@ trait Reifiers { self: Quasiquotes => case SyntacticClassDef(mods, name, tparams, constrmods, vparamss, earlyDefs, parents, selfdef, body) => reifyBuildCall(nme.SyntacticClassDef, mods, name, tparams, constrmods, vparamss, earlyDefs, parents, selfdef, body) - case SyntacticModuleDef(mods, name, earlyDefs, parents, selfdef, body) => - reifyBuildCall(nme.SyntacticModuleDef, mods, name, earlyDefs, parents, selfdef, body) + case SyntacticPackageObjectDef(name, earlyDefs, parents, selfdef, body) => + reifyBuildCall(nme.SyntacticPackageObjectDef, name, earlyDefs, parents, selfdef, body) + case SyntacticObjectDef(mods, name, earlyDefs, parents, selfdef, body) => + reifyBuildCall(nme.SyntacticObjectDef, mods, name, earlyDefs, parents, selfdef, body) case SyntacticNew(earlyDefs, parents, selfdef, body) => reifyBuildCall(nme.SyntacticNew, earlyDefs, parents, selfdef, body) case SyntacticDefDef(mods, name, tparams, vparamss, tpt, rhs) => @@ -131,6 +132,8 @@ trait Reifiers { self: Quasiquotes => def reifyAnnotation(tree: Tree) = tree + def reifyPackageStat(tree: Tree) = tree + /** Splits list into a list of groups where subsequent elements are considered * similar by the corresponding function. * @@ -185,6 +188,8 @@ trait Reifiers { self: Quasiquotes => case CasePlaceholder(tree, _, DotDot) => tree case RefineStatPlaceholder(tree, _, DotDot) => reifyRefineStat(tree) case EarlyDefPlaceholder(tree, _, DotDot) => reifyEarlyDef(tree) + case PackageStatPlaceholder(tree, _, DotDot) => reifyPackageStat(tree) + case List(Placeholder(tree, _, DotDotDot)) => tree } { reify(_) @@ -280,6 +285,8 @@ trait Reifiers { self: Quasiquotes => override def reifyEarlyDef(tree: Tree) = mirrorBuildCall(nme.mkEarlyDef, tree) override def reifyAnnotation(tree: Tree) = mirrorBuildCall(nme.mkAnnotation, tree) + + override def reifyPackageStat(tree: Tree) = mirrorBuildCall(nme.mkPackageStat, tree) } class UnapplyReifier extends Reifier { diff --git a/src/reflect/scala/reflect/api/BuildUtils.scala b/src/reflect/scala/reflect/api/BuildUtils.scala index 551c27bf9c..df126bed45 100644 --- a/src/reflect/scala/reflect/api/BuildUtils.scala +++ b/src/reflect/scala/reflect/api/BuildUtils.scala @@ -80,6 +80,10 @@ private[reflect] trait BuildUtils { self: Universe => def mkRefineStat(stats: List[Tree]): List[Tree] + def mkPackageStat(stat: Tree): Tree + + def mkPackageStat(stats: List[Tree]): List[Tree] + def mkEarlyDef(defn: Tree): Tree def mkEarlyDef(defns: List[Tree]): List[Tree] @@ -133,14 +137,22 @@ private[reflect] trait BuildUtils { self: Universe => List[Tree], List[Tree], ValDef, List[Tree])] } - val SyntacticModuleDef: SyntacticModuleDefExtractor + val SyntacticObjectDef: SyntacticObjectDefExtractor - trait SyntacticModuleDefExtractor { + trait SyntacticObjectDefExtractor { def apply(mods: Modifiers, name: TermName, earlyDefs: List[Tree], parents: List[Tree], selfdef: ValDef, body: List[Tree]): Tree def unapply(tree: Tree): Option[(Modifiers, TermName, List[Tree], List[Tree], ValDef, List[Tree])] } + val SyntacticPackageObjectDef: SyntacticPackageObjectDefExtractor + + trait SyntacticPackageObjectDefExtractor { + def apply(name: TermName, earlyDefs: List[Tree], + parents: List[Tree], selfdef: ValDef, body: List[Tree]): Tree + def unapply(tree: Tree): Option[(TermName, List[Tree], List[Tree], ValDef, List[Tree])] + } + val SyntacticTuple: SyntacticTupleExtractor val SyntacticTupleType: SyntacticTupleExtractor diff --git a/src/reflect/scala/reflect/internal/BuildUtils.scala b/src/reflect/scala/reflect/internal/BuildUtils.scala index 951efd90ed..a09715ec7c 100644 --- a/src/reflect/scala/reflect/internal/BuildUtils.scala +++ b/src/reflect/scala/reflect/internal/BuildUtils.scala @@ -98,6 +98,18 @@ trait BuildUtils { self: SymbolTable => def mkRefineStat(stats: List[Tree]): List[Tree] = stats.map(mkRefineStat) + def mkPackageStat(stat: Tree): Tree = { + stat match { + case cd: ClassDef => + case md: ModuleDef => + case pd: PackageDef => + case _ => throw new IllegalArgumentException(s"not legal package stat: $stat") + } + stat + } + + def mkPackageStat(stats: List[Tree]): List[Tree] = stats.map(mkPackageStat) + object ScalaDot extends ScalaDotExtractor { def apply(name: Name): Tree = gen.scalaDot(name) def unapply(tree: Tree): Option[Name] = tree match { @@ -110,7 +122,7 @@ trait BuildUtils { self: SymbolTable => case vdef @ ValDef(mods, _, _, _) if !mods.isDeferred => copyValDef(vdef)(mods = mods | PRESUPER) case tdef @ TypeDef(mods, _, _, _) => - copyTypeDef(tdef)(mods = mods | PRESUPER) + copyTypeDef(tdef)(mods = mods | PRESUPER) case _ => throw new IllegalArgumentException(s"not legal early def: $defn") } @@ -244,7 +256,7 @@ trait BuildUtils { self: SymbolTable => } } - object SyntacticModuleDef extends SyntacticModuleDefExtractor { + object SyntacticObjectDef extends SyntacticObjectDefExtractor { def apply(mods: Modifiers, name: TermName, earlyDefs: List[Tree], parents: List[Tree], selfdef: ValDef, body: List[Tree]) = ModuleDef(mods, name, gen.mkTemplate(parents, selfdef, NoMods, Nil, earlyDefs ::: body)) @@ -257,6 +269,19 @@ trait BuildUtils { self: SymbolTable => } } + object SyntacticPackageObjectDef extends SyntacticPackageObjectDefExtractor { + def apply(name: TermName, earlyDefs: List[Tree], + parents: List[Tree], selfdef: ValDef, body: List[Tree]): Tree = + gen.mkPackageObject(SyntacticObjectDef(NoMods, name, earlyDefs, parents, selfdef, body)) + + def unapply(tree: Tree): Option[(TermName, List[Tree], List[Tree], ValDef, List[Tree])] = tree match { + case PackageDef(Ident(name: TermName), List(SyntacticObjectDef(NoMods, nme.PACKAGEkw, earlyDefs, parents, selfdef, body))) => + Some((name, earlyDefs, parents, selfdef, body)) + case _ => + None + } + } + private trait ScalaMemberRef { val symbols: Seq[Symbol] def result(name: Name): Option[Symbol] = diff --git a/src/reflect/scala/reflect/internal/StdNames.scala b/src/reflect/scala/reflect/internal/StdNames.scala index af26253802..7cfe194fd1 100644 --- a/src/reflect/scala/reflect/internal/StdNames.scala +++ b/src/reflect/scala/reflect/internal/StdNames.scala @@ -247,11 +247,12 @@ trait StdNames { final val Quasiquote: NameType = "Quasiquote" // quasiquote-specific names - final val QUASIQUOTE_MODS: NameType = "$quasiquote$mods$" - final val QUASIQUOTE_TUPLE: NameType = "$quasiquote$tuple$" - final val QUASIQUOTE_FUNCTION: NameType = "$quasiquote$function$" - final val QUASIQUOTE_REFINE_STAT: NameType = "$quasiquote$refine$stat$" - final val QUASIQUOTE_EARLY_DEF: NameType = "$quasiquote$early$def$" + final val QUASIQUOTE_MODS: NameType = "$quasiquote$mods$" + final val QUASIQUOTE_TUPLE: NameType = "$quasiquote$tuple$" + final val QUASIQUOTE_FUNCTION: NameType = "$quasiquote$function$" + final val QUASIQUOTE_REFINE_STAT: NameType = "$quasiquote$refine$stat$" + final val QUASIQUOTE_EARLY_DEF: NameType = "$quasiquote$early$def$" + final val QUASIQUOTE_PACKAGE_STAT: NameType = "$quasiquote$package$stat$" // Annotation simple names, used in Namer final val BeanPropertyAnnot: NameType = "BeanProperty" @@ -587,8 +588,9 @@ trait StdNames { val SyntacticClassDef: NameType = "SyntacticClassDef" val SyntacticDefDef: NameType = "SyntacticDefDef" val SyntacticFunction: NameType = "SyntacticFunction" - val SyntacticFunctionType: NameType= "SyntacticFunctionType" - val SyntacticModuleDef: NameType = "SyntacticModuleDef" + val SyntacticFunctionType: NameType = "SyntacticFunctionType" + val SyntacticPackageObjectDef: NameType = "SyntacticPackageObjectDef" + val SyntacticObjectDef: NameType = "SyntacticObjectDef" val SyntacticNew: NameType = "SyntacticNew" val SyntacticTraitDef: NameType = "SyntacticTraitDef" val SyntacticTuple: NameType = "SyntacticTuple" @@ -683,6 +685,7 @@ trait StdNames { val mkAnnotation: NameType = "mkAnnotation" val mkRefineStat: NameType = "mkRefineStat" val mkEarlyDef: NameType = "mkEarlyDef" + val mkPackageStat: NameType = "mkPackageStat" val ne: NameType = "ne" val newArray: NameType = "newArray" val newFreeTerm: NameType = "newFreeTerm" diff --git a/src/reflect/scala/reflect/internal/TreeGen.scala b/src/reflect/scala/reflect/internal/TreeGen.scala index 720d8bfe4a..cf7c729a6a 100644 --- a/src/reflect/scala/reflect/internal/TreeGen.scala +++ b/src/reflect/scala/reflect/internal/TreeGen.scala @@ -448,4 +448,10 @@ abstract class TreeGen extends macros.TreeBuilder { case _ => Assign(lhs, rhs) } + + def mkPackageObject(defn: ModuleDef, pidPos: Position = NoPosition, pkgPos: Position = NoPosition) = { + val module = copyModuleDef(defn)(name = nme.PACKAGEkw) + val pid = atPos(pidPos)(Ident(defn.name)) + atPos(pkgPos)(PackageDef(pid, module :: Nil)) + } } |