blob: 128896ccaae0b3fb3b9828f66142bf3962b31683 (
plain) (
tree)
|
|
import scala.tools.nsc.interactive.tests.InteractiveTest
import scala.reflect.internal.util.SourceFile
import scala.tools.nsc.interactive.Response
object Test extends InteractiveTest {
override def execute(): Unit = {
val sf = sourceFiles.find(_.file.name == "A.scala").head
noNewSymbols(sf)
uniqueParseTree(sf)
unattributedParseTree(sf)
neverModifyParseTree(sf)
shouldAlwaysReturnParseTree(sf)
}
/**
* Asking for a parseTree should not enter any new symbols.
*/
private def noNewSymbols(sf: SourceFile) {
def nextId() = compiler.NoSymbol.newTermSymbol(compiler.TermName("dummy"), compiler.NoPosition, compiler.NoFlags).id
val id = nextId()
val tree = compiler.parseTree(sf)
val id2 = nextId()
if (id2 == id + 1) {
reporter.println("NoNewSymbolsEntered OK")
} else {
reporter.println("NoNewSymbolsEntered FAILED")
}
}
/**
* Asking twice for a parseTree on the same source should always return a new tree
*/
private def uniqueParseTree(sf: SourceFile) {
val parseTree1 = compiler.parseTree(sf)
val parseTree2 = compiler.parseTree(sf)
if (parseTree1 != parseTree2) {
reporter.println("Unique OK")
} else {
reporter.println("Unique FAILED")
}
}
/**
* A parseTree should never contain any symbols or types
*/
private def unattributedParseTree(sf: SourceFile) {
if (noSymbolsOrTypes(compiler.parseTree(sf))) {
reporter.println("Unattributed OK")
} else {
reporter.println("Unattributed FAILED")
}
}
/**
* Once you have obtained a parseTree it should never change
*/
private def neverModifyParseTree(sf: SourceFile) {
val parsedTree = compiler.parseTree(sf)
loadSourceAndWaitUntilTypechecked(sf)
if (noSymbolsOrTypes(parsedTree)) {
reporter.println("NeverModify OK")
} else {
reporter.println("NeverModify FAILED")
}
}
/**
* Should always return a parse tree
*/
private def shouldAlwaysReturnParseTree(sf: SourceFile) {
loadSourceAndWaitUntilTypechecked(sf)
if (noSymbolsOrTypes(compiler.parseTree(sf))) {
reporter.println("AlwaysParseTree OK")
} else {
reporter.println("AlwaysParseTree FAILED")
}
}
/**
* Load a source and block while it is type-checking.
*/
private def loadSourceAndWaitUntilTypechecked(sf: SourceFile): Unit = {
compiler.askToDoFirst(sf)
val res = new Response[Unit]
compiler.askReload(List(sf), res)
res.get
askLoadedTyped(sf).get
}
/**
* Traverses a tree and makes sure that there are no types or symbols present in the tree with
* the exception of the symbol for the package 'scala'. This is because that symbol will be
* present in some of the nodes that the compiler generates.
*/
private def noSymbolsOrTypes(tree: compiler.Tree): Boolean = {
tree.forAll { t =>
(t.symbol == null ||
t.symbol == compiler.NoSymbol ||
t.symbol == compiler.definitions.ScalaPackage // ignore the symbol for the scala package for now
) && (
t.tpe == null ||
t.tpe == compiler.NoType)
}
}
}
|