1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
|
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)
}
}
}
|