Skip to content

Commit

Permalink
SI-7331 tb.parse returns unpositioned trees
Browse files Browse the repository at this point in the history
This commit gets rid off code wrapping that was previously used by
toolbox to get into correct parsing mode. Instead combination of
templateStats/accept(EOF) is used. This is the same solution as the one
used in repl and built-in scriptRunner

This pull request doesn't attempt to generalize this approach in any
way and re-use it all over the place due to the caution of possible
accidental compatibility breakage. I plan to do it separately against
master.

Additionally there are a few more changes that make importers be aware
of positions and a test for that (via @jedesah).
  • Loading branch information
densh committed Aug 8, 2013
1 parent e9ccb41 commit 36524c2
Show file tree
Hide file tree
Showing 8 changed files with 51 additions and 6 deletions.
10 changes: 5 additions & 5 deletions src/compiler/scala/tools/reflect/ToolBoxFactory.scala
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import scala.tools.nsc.typechecker.Modes
import scala.tools.nsc.io.VirtualDirectory
import scala.tools.nsc.interpreter.AbstractFileClassLoader
import scala.tools.nsc.util.FreshNameCreator
import scala.tools.nsc.ast.parser.Tokens.EOF
import scala.reflect.internal.Flags._
import scala.reflect.internal.util.{BatchSourceFile, NoSourceFile, NoFile}
import java.lang.{Class => jClass}
Expand Down Expand Up @@ -273,14 +274,13 @@ abstract class ToolBoxFactory[U <: JavaUniverse](val u: U) { factorySelf =>
def parse(code: String): Tree = {
val run = new Run
reporter.reset()
val wrappedCode = "object wrapper {" + EOL + code + EOL + "}"
val file = new BatchSourceFile("<toolbox>", wrappedCode)
val file = new BatchSourceFile("<toolbox>", code)
val unit = new CompilationUnit(file)
phase = run.parserPhase
val parser = new syntaxAnalyzer.UnitParser(unit)
val wrappedTree = parser.parse()
val parsed = parser.templateStats()
parser.accept(EOF)
throwIfErrors()
val PackageDef(_, List(ModuleDef(_, _, Template(_, _, _ :: parsed)))) = wrappedTree
parsed match {
case expr :: Nil => expr
case stats :+ expr => Block(stats, expr)
Expand Down Expand Up @@ -402,7 +402,7 @@ abstract class ToolBoxFactory[U <: JavaUniverse](val u: U) { factorySelf =>

def compile(tree: u.Tree): () => Any = {
if (compiler.settings.verbose.value) println("importing "+tree)
var ctree: compiler.Tree = importer.importTree(tree)
val ctree: compiler.Tree = importer.importTree(tree)

if (compiler.settings.verbose.value) println("compiling "+ctree)
compiler.compile(ctree)
Expand Down
7 changes: 6 additions & 1 deletion src/reflect/scala/reflect/internal/Importers.scala
Original file line number Diff line number Diff line change
Expand Up @@ -443,7 +443,12 @@ trait Importers extends api.Importers { self: SymbolTable =>
}
})
tryFixup()
mytree
// we have to be careful with position import as some shared trees
// like EmptyTree, emptyValDef don't support position assignment
if (tree.pos != NoPosition)
mytree.setPos(importPosition(tree.pos))
else
mytree
}

def importValDef(tree: from.ValDef): ValDef = importTree(tree).asInstanceOf[ValDef]
Expand Down
2 changes: 2 additions & 0 deletions test/files/run/t7331a.check
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
source-<toolbox>,line-1,offset=0
2
10 changes: 10 additions & 0 deletions test/files/run/t7331a.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import scala.reflect.runtime.universe._
import scala.reflect.runtime.{currentMirror => cm}
import scala.tools.reflect.ToolBox

object Test extends App {
val tb = cm.mkToolBox()
val tree = tb.parse("x")
println(tree.pos)
println(tree.pos.source.content.length)
}
3 changes: 3 additions & 0 deletions test/files/run/t7331b.check
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
reflective compilation has failed:

')' expected but eof found.
11 changes: 11 additions & 0 deletions test/files/run/t7331b.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import scala.reflect.runtime.universe._
import scala.reflect.runtime.{currentMirror => cm}
import scala.tools.reflect.{ToolBox, ToolBoxError}

object Test extends App {
val tb = cm.mkToolBox()
try tb.parse("f(x")
catch {
case ToolBoxError(msg, _) => println(msg)
}
}
3 changes: 3 additions & 0 deletions test/files/run/t7331c.check
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
ClassDef(Modifiers(), newTypeName("C"), List(), Template(List(Select(Ident(scala), newTypeName("AnyRef"))), emptyValDef, List(DefDef(Modifiers(), nme.CONSTRUCTOR, List(), List(List()), TypeTree(), Block(List(Apply(Select(Super(This(tpnme.EMPTY), tpnme.EMPTY), nme.CONSTRUCTOR), List())), Literal(Constant(())))))))
source-<toolbox>,line-1,offset=6
NoPosition
11 changes: 11 additions & 0 deletions test/files/run/t7331c.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import scala.reflect.runtime.universe._
import scala.reflect.runtime.{currentMirror => cm}
import scala.tools.reflect.ToolBox

object Test extends App {
val tb = cm.mkToolBox()
val tree = tb.parse("class C").asInstanceOf[ClassDef]
println(showRaw(tree))
println(tree.pos)
println(tree.impl.self.pos)
}

0 comments on commit 36524c2

Please sign in to comment.