diff options
author | Den Shabalin <den.shabalin@gmail.com> | 2013-09-20 13:32:38 +0200 |
---|---|---|
committer | Den Shabalin <den.shabalin@gmail.com> | 2013-10-14 13:30:49 +0200 |
commit | 3a148cd0cd404751095cd1c5aca09ad8923c51ab (patch) | |
tree | 2ad3cbc115fe0ca270d476171b41519c483ba201 /src/compiler | |
parent | d7aae49f8ff7ccc6c1a588fc116e8c37fdb9e849 (diff) | |
download | scala-3a148cd0cd404751095cd1c5aca09ad8923c51ab.tar.gz scala-3a148cd0cd404751095cd1c5aca09ad8923c51ab.tar.bz2 scala-3a148cd0cd404751095cd1c5aca09ad8923c51ab.zip |
SI-6841 SI-6657 add support for packages into quasiquotes and toolbox
In order to implement this a new parser entry point
`parseStatsOrPackages` that augments current parseStats with ability
to parse "package name { ... }" syntax.
Diffstat (limited to 'src/compiler')
6 files changed, 37 insertions, 14 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 { |