diff options
author | Jason Zaugg <jzaugg@gmail.com> | 2013-09-16 03:06:34 -0700 |
---|---|---|
committer | Jason Zaugg <jzaugg@gmail.com> | 2013-09-16 03:06:34 -0700 |
commit | 9dbc321504ad5550638d6d7c2b3cd2f98273cf74 (patch) | |
tree | 7459704f5c9f0d471e63ec56b4f15c2803f10a59 /src/compiler | |
parent | 8c68723acd738d94d049ac996d5e0ea22659c4ba (diff) | |
parent | 8a7b5666b6f10728f7c3ae9ca1bc2a8b82f6b965 (diff) | |
download | scala-9dbc321504ad5550638d6d7c2b3cd2f98273cf74.tar.gz scala-9dbc321504ad5550638d6d7c2b3cd2f98273cf74.tar.bz2 scala-9dbc321504ad5550638d6d7c2b3cd2f98273cf74.zip |
Merge pull request #2935 from densh/topic/si-7304-6489-6701
SI-6701, SI-7304, SI-6489, variable arity definitions refactoring
Diffstat (limited to 'src/compiler')
10 files changed, 70 insertions, 55 deletions
diff --git a/src/compiler/scala/reflect/macros/contexts/Parsers.scala b/src/compiler/scala/reflect/macros/contexts/Parsers.scala index 3dab02beba..ae6488b5a8 100644 --- a/src/compiler/scala/reflect/macros/contexts/Parsers.scala +++ b/src/compiler/scala/reflect/macros/contexts/Parsers.scala @@ -1,24 +1,20 @@ package scala.reflect.macros package contexts -import scala.language.existentials -import scala.tools.reflect.ToolBox -import scala.tools.reflect.ToolBoxError +import scala.tools.nsc.reporters.StoreReporter trait Parsers { self: Context => + import global._ - def parse(code: String): Tree = - // todo. provide decent implementation - // see `Typers.typedUseCase` for details - try { - import scala.reflect.runtime.{universe => ru} - val parsed = ru.rootMirror.mkToolBox().parse(code) - val importer = universe.mkImporter(ru) - importer.importTree(parsed) - } catch { - case ToolBoxError(msg, cause) => - // todo. provide a position - throw new ParseException(universe.NoPosition, msg) + def parse(code: String) = { + 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()) + sreporter.infos.foreach { + case sreporter.Info(pos, msg, sreporter.ERROR) => throw ParseException(pos, msg) } -} + tree + } +}
\ No newline at end of file diff --git a/src/compiler/scala/tools/nsc/CompilationUnits.scala b/src/compiler/scala/tools/nsc/CompilationUnits.scala index f7437e4e6c..1de5c1f626 100644 --- a/src/compiler/scala/tools/nsc/CompilationUnits.scala +++ b/src/compiler/scala/tools/nsc/CompilationUnits.scala @@ -9,8 +9,9 @@ import util.FreshNameCreator import scala.reflect.internal.util.{ SourceFile, NoSourceFile } import scala.collection.mutable import scala.collection.mutable.{ LinkedHashSet, ListBuffer } +import scala.tools.nsc.reporters.Reporter -trait CompilationUnits { self: Global => +trait CompilationUnits { global: Global => /** An object representing a missing compilation unit. */ @@ -119,6 +120,8 @@ trait CompilationUnits { self: Global => */ val icode: LinkedHashSet[icodes.IClass] = new LinkedHashSet + def reporter = global.reporter + def echo(pos: Position, msg: String) = reporter.echo(pos, msg) diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala index 19fb2a9289..f3a2d49697 100644 --- a/src/compiler/scala/tools/nsc/Global.scala +++ b/src/compiler/scala/tools/nsc/Global.scala @@ -110,7 +110,10 @@ class Global(var currentSettings: Settings, var reporter: Reporter) } /** A spare instance of TreeBuilder left for backwards compatibility. */ - lazy val treeBuilder: TreeBuilder { val global: Global.this.type } = new syntaxAnalyzer.ParserTreeBuilder + lazy val treeBuilder: TreeBuilder { val global: Global.this.type } = new UnitTreeBuilder { + val global: Global.this.type = Global.this; + val unit = currentUnit + } /** Fold constants */ object constfold extends { @@ -1159,11 +1162,20 @@ class Global(var currentSettings: Settings, var reporter: Reporter) warning("there were %d %s warning(s); re-run with %s for details".format(warnings.size, what, option.name)) } - def newCompilationUnit(code: String) = new CompilationUnit(newSourceFile(code)) - def newSourceFile(code: String) = new BatchSourceFile("<console>", code) - def newUnitScanner(unit: CompilationUnit): UnitScanner = new UnitScanner(unit) - def newUnitParser(unit: CompilationUnit): UnitParser = new UnitParser(unit) - def newUnitParser(code: String): UnitParser = newUnitParser(newCompilationUnit(code)) + def newSourceFile(code: String, filename: String = "<console>") = + new BatchSourceFile(filename, code) + + def newCompilationUnit(code: String, filename: String = "<console>") = + new CompilationUnit(newSourceFile(code, filename)) + + def newUnitScanner(unit: CompilationUnit): UnitScanner = + new UnitScanner(unit) + + def newUnitParser(unit: CompilationUnit): UnitParser = + new UnitParser(unit) + + def newUnitParser(code: String, filename: String = "<console>"): UnitParser = + newUnitParser(newCompilationUnit(code, filename)) /** A Run is a single execution of the compiler on a set of units. */ diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala index a974352169..07e24900e9 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala @@ -28,20 +28,14 @@ import util.FreshNameCreator */ trait ParsersCommon extends ScannersCommon { self => val global : Global - import global._ + // the use of currentUnit in the parser should be avoided as it might + // cause unexpected behaviour when you work with two units at the + // same time; use Parser.unit instead + import global.{currentUnit => _, _} def newLiteral(const: Any) = Literal(Constant(const)) def literalUnit = newLiteral(()) - class ParserTreeBuilder extends TreeBuilder { - val global: self.global.type = self.global - def freshName(prefix: String): Name = freshTermName(prefix) - def freshTermName(prefix: String): TermName = currentUnit.freshTermName(prefix) - def freshTypeName(prefix: String): TypeName = currentUnit.freshTypeName(prefix) - def o2p(offset: Int): Position = new OffsetPosition(currentUnit.source, offset) - def r2p(start: Int, mid: Int, end: Int): Position = rangePos(currentUnit.source, start, mid, end) - } - /** This is now an abstract class, only to work around the optimizer: * methods in traits are never inlined. */ @@ -172,6 +166,7 @@ self => private val globalFresh = new FreshNameCreator.Default + def unit = global.currentUnit def freshName(prefix: String): Name = freshTermName(prefix) def freshTermName(prefix: String): TermName = newTermName(globalFresh.newName(prefix)) def freshTypeName(prefix: String): TypeName = newTypeName(globalFresh.newName(prefix)) @@ -196,7 +191,7 @@ self => * that we don't have the xml library on the compilation classpath. */ private[this] lazy val xmlp = { - currentUnit.encounteredXml(o2p(in.offset)) + unit.encounteredXml(o2p(in.offset)) new MarkupParser(this, preserveWS = true) } @@ -225,7 +220,7 @@ self => override def templateBody(isPre: Boolean) = skipBraces((emptyValDef, EmptyTree.asList)) } - class UnitParser(val unit: global.CompilationUnit, patches: List[BracePatch]) extends SourceFileParser(unit.source) { + class UnitParser(override val unit: global.CompilationUnit, patches: List[BracePatch]) extends SourceFileParser(unit.source) { uself => def this(unit: global.CompilationUnit) = this(unit, Nil) override def newScanner() = new UnitScanner(unit, patches) @@ -298,9 +293,10 @@ self => import nme.raw - abstract class Parser extends ParserCommon { + abstract class Parser extends ParserCommon { parser => val in: Scanner + def unit: CompilationUnit def freshName(prefix: String): Name def freshTermName(prefix: String): TermName def freshTypeName(prefix: String): TypeName @@ -310,8 +306,12 @@ self => /** whether a non-continuable syntax error has been seen */ private var lastErrorOffset : Int = -1 + class ParserTreeBuilder extends UnitTreeBuilder { + val global: self.global.type = self.global + def unit = parser.unit + } val treeBuilder = new ParserTreeBuilder - import treeBuilder.{global => _, _} + import treeBuilder.{global => _, unit => _, _} /** The types of the context bounds of type parameters of the surrounding class */ diff --git a/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala b/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala index 8ea0ceddbb..91ff530e05 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala @@ -8,6 +8,7 @@ package ast.parser import symtab.Flags._ import scala.collection.mutable.ListBuffer +import scala.reflect.internal.util.OffsetPosition /** Methods for building trees, used in the parser. All the trees * returned by this class must be untyped. @@ -529,3 +530,13 @@ abstract class TreeBuilder { } } } + +abstract class UnitTreeBuilder extends TreeBuilder { + import global._ + def unit: CompilationUnit + def freshName(prefix: String): Name = freshTermName(prefix) + def freshTermName(prefix: String): TermName = unit.freshTermName(prefix) + def freshTypeName(prefix: String): TypeName = unit.freshTypeName(prefix) + def o2p(offset: Int): Position = new OffsetPosition(unit.source, offset) + def r2p(start: Int, mid: Int, end: Int): Position = rangePos(unit.source, start, mid, end) +} diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala index edb1c55224..8d025b5451 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala @@ -1479,7 +1479,7 @@ abstract class GenASM extends SubComponent with BytecodeWriters with GenJVMASM { sym.owner.isSynthetic && sym.owner.tpe.parents.exists { t => val TypeRef(_, sym, _) = t - FunctionClass contains sym + FunctionClass.seq contains sym } } diff --git a/src/compiler/scala/tools/nsc/reporters/StoreReporter.scala b/src/compiler/scala/tools/nsc/reporters/StoreReporter.scala index 34e2a8a96a..04c5bdf824 100644 --- a/src/compiler/scala/tools/nsc/reporters/StoreReporter.scala +++ b/src/compiler/scala/tools/nsc/reporters/StoreReporter.scala @@ -14,7 +14,7 @@ import scala.reflect.internal.util.Position * console. */ class StoreReporter extends Reporter { - class Info(val pos: Position, val msg: String, val severity: Severity) { + case class Info(pos: Position, msg: String, severity: Severity) { override def toString() = "pos: " + pos + " " + msg + " " + severity } val infos = new mutable.LinkedHashSet[Info] diff --git a/src/compiler/scala/tools/reflect/ToolBoxFactory.scala b/src/compiler/scala/tools/reflect/ToolBoxFactory.scala index 57ebe1b30d..b77a536caf 100644 --- a/src/compiler/scala/tools/reflect/ToolBoxFactory.scala +++ b/src/compiler/scala/tools/reflect/ToolBoxFactory.scala @@ -273,15 +273,9 @@ abstract class ToolBoxFactory[U <: JavaUniverse](val u: U) { factorySelf => def parse(code: String): Tree = { reporter.reset() - val file = new BatchSourceFile("<toolbox>", code) - val unit = new CompilationUnit(file) - val parsed = newUnitParser(unit).parseStats() + val tree = gen.mkTreeOrBlock(newUnitParser(code, "<toolbox>").parseStats()) throwIfErrors() - parsed match { - case Nil => EmptyTree - case expr :: Nil => expr - case stats :+ expr => Block(stats, expr) - } + tree } def showAttributed(artifact: Any, printTypes: Boolean = true, printIds: Boolean = true, printKinds: Boolean = false): String = { @@ -355,7 +349,8 @@ abstract class ToolBoxFactory[U <: JavaUniverse](val u: U) { factorySelf => } def inferImplicitView(tree: u.Tree, from: u.Type, to: u.Type, silent: Boolean = true, withMacrosDisabled: Boolean = false, pos: u.Position = u.NoPosition): u.Tree = { - val viewTpe = u.appliedType(u.definitions.FunctionClass(1).toTypeConstructor, List(from, to)) + val functionTypeCtor = u.definitions.FunctionClass(1).asClass.toTypeConstructor + val viewTpe = u.appliedType(functionTypeCtor, List(from, to)) inferImplicit(tree, viewTpe, isView = true, silent = silent, withMacrosDisabled = withMacrosDisabled, pos = pos) } diff --git a/src/compiler/scala/tools/reflect/quasiquotes/Parsers.scala b/src/compiler/scala/tools/reflect/quasiquotes/Parsers.scala index 19888fa8d2..5a1a25cfa1 100644 --- a/src/compiler/scala/tools/reflect/quasiquotes/Parsers.scala +++ b/src/compiler/scala/tools/reflect/quasiquotes/Parsers.scala @@ -49,7 +49,7 @@ trait Parsers { self: Quasiquotes => def entryPoint: QuasiquoteParser => Tree - class QuasiquoteParser(source0: SourceFile) extends SourceFileParser(source0) { + class QuasiquoteParser(source0: SourceFile) extends SourceFileParser(source0) { parser => def isHole: Boolean = isIdent && isHole(in.name) def isHole(name: Name): Boolean = holeMap.contains(name) @@ -73,7 +73,7 @@ trait Parsers { self: Quasiquotes => override def makeFunctionTypeTree(argtpes: List[Tree], restpe: Tree): Tree = AppliedTypeTree(Ident(tpnme.QUASIQUOTE_FUNCTION), argtpes :+ restpe) } - import treeBuilder.{global => _, _} + import treeBuilder.{global => _, unit => _, _} // q"def foo($x)" override def allowTypelessParams = true @@ -144,11 +144,7 @@ trait Parsers { self: Quasiquotes => } object TermParser extends Parser { - def entryPoint = _.templateStats() match { - case Nil => EmptyTree - case tree :: Nil => tree - case stats :+ tree => Block(stats, tree) - } + def entryPoint = { parser => gen.mkTreeOrBlock(parser.templateStats()) } } object TypeParser extends Parser { diff --git a/src/compiler/scala/tools/reflect/quasiquotes/Reifiers.scala b/src/compiler/scala/tools/reflect/quasiquotes/Reifiers.scala index af4e34536c..c2d8bcdcd6 100644 --- a/src/compiler/scala/tools/reflect/quasiquotes/Reifiers.scala +++ b/src/compiler/scala/tools/reflect/quasiquotes/Reifiers.scala @@ -228,6 +228,8 @@ trait Reifiers { self: Quasiquotes => override def reifyTreeSyntactically(tree: Tree): Tree = tree match { case RefTree(qual, SymbolPlaceholder(tree)) => mirrorBuildCall(nme.RefTree, reify(qual), tree) + case This(SymbolPlaceholder(tree)) => + mirrorCall(nme.This, tree) case _ => super.reifyTreeSyntactically(tree) } |