From 526f6c3934f31902fc3f5a0e690a472e86ecfc48 Mon Sep 17 00:00:00 2001 From: Grzegorz Kossakowski Date: Sat, 27 Jul 2013 01:38:45 -0700 Subject: Add example of SymbolTable unit test. Add a SymbolTableTest which contains all the code needed to initialize a SymbolTable in JUnit environment. It shows that initialization of definitions works and one can easily lookup some symbols and perform tests like subtyping tests. --- .../nsc/symtab/SymbolTableForUnitTesting.scala | 89 ++++++++++++++++++++++ .../scala/tools/nsc/symtab/SymbolTableTest.scala | 29 +++++++ 2 files changed, 118 insertions(+) create mode 100644 test/junit/scala/tools/nsc/symtab/SymbolTableForUnitTesting.scala create mode 100644 test/junit/scala/tools/nsc/symtab/SymbolTableTest.scala (limited to 'test/junit') diff --git a/test/junit/scala/tools/nsc/symtab/SymbolTableForUnitTesting.scala b/test/junit/scala/tools/nsc/symtab/SymbolTableForUnitTesting.scala new file mode 100644 index 0000000000..209d93adb2 --- /dev/null +++ b/test/junit/scala/tools/nsc/symtab/SymbolTableForUnitTesting.scala @@ -0,0 +1,89 @@ +package scala.tools.nsc +package symtab + +import scala.reflect.internal.{Phase, NoPhase, SomePhase} +import scala.tools.util.PathResolver +import util.ClassPath +import io.AbstractFile + +/** + * A complete SymbolTable implementation designed to be used in JUnit tests. + * + * It enables `usejavacp` setting so classpath of JUnit runner is being used + * for symbol table's classpath. + * + * This class contains enough of logic implemented to make it possible to + * initialize definitions and inspect symbols. + */ +class SymbolTableForUnitTesting extends SymbolTable { + // Members declared in scala.reflect.api.Trees + override def newStrictTreeCopier: TreeCopier = new StrictTreeCopier + override def newLazyTreeCopier: TreeCopier = new LazyTreeCopier + trait TreeCopier extends InternalTreeCopierOps + // these should be mocks + class StrictTreeCopier extends super.StrictTreeCopier with TreeCopier + class LazyTreeCopier extends super.LazyTreeCopier with TreeCopier + + override def isCompilerUniverse: Boolean = true + def classPath = new PathResolver(settings).result + + object platform extends backend.Platform { + val symbolTable: SymbolTableForUnitTesting.this.type = SymbolTableForUnitTesting.this + lazy val loaders: SymbolTableForUnitTesting.this.loaders.type = SymbolTableForUnitTesting.this.loaders + def platformPhases: List[SubComponent] = Nil + val classPath: ClassPath[AbstractFile] = new PathResolver(settings).result + def doLoad(cls: ClassPath[AbstractFile]#ClassRep): Boolean = true + def isMaybeBoxed(sym: Symbol): Boolean = ??? + def needCompile(bin: AbstractFile, src: AbstractFile): Boolean = ??? + def externalEquals: Symbol = ??? + def updateClassPath(subst: Map[ClassPath[AbstractFile], ClassPath[AbstractFile]]): Unit = ??? + } + + object loaders extends symtab.SymbolLoaders { + val symbolTable: SymbolTableForUnitTesting.this.type = SymbolTableForUnitTesting.this + lazy val platform: symbolTable.platform.type = symbolTable.platform + protected def lookupMemberAtTyperPhaseIfPossible(sym: Symbol, name: Name): Symbol = + sym.info.member(name) + protected override def compileLate(srcfile: AbstractFile): Unit = + sys.error(s"We do not expect compileLate to be called in SymbolTableTest. The srcfile passed in is $srcfile") + } + + class GlobalMirror extends Roots(NoSymbol) { + val universe: SymbolTableForUnitTesting.this.type = SymbolTableForUnitTesting.this + def rootLoader: LazyType = new loaders.PackageLoader(classPath) + override def toString = "compiler mirror" + } + + lazy val rootMirror: Mirror = { + val rm = new GlobalMirror + rm.init() + rm.asInstanceOf[Mirror] + } + + def settings: Settings = { + val s = new Settings + // initialize classpath using java classpath + s.usejavacp.value = true + s + } + + // Members declared in scala.reflect.internal.Required + def picklerPhase: scala.reflect.internal.Phase = SomePhase + + // Members declared in scala.reflect.internal.SymbolTable + def currentRunId: Int = 1 + def log(msg: => AnyRef): Unit = println(msg) + def mirrorThatLoaded(sym: Symbol): Mirror = rootMirror + val phases: Seq[Phase] = List(NoPhase, SomePhase) + val phaseWithId: Array[Phase] = { + val maxId = phases.map(_.id).max + val phasesArray = Array.ofDim[Phase](maxId+1) + phases foreach { phase => + phasesArray(phase.id) = phase + } + phasesArray + } + lazy val treeInfo: scala.reflect.internal.TreeInfo{val global: SymbolTableForUnitTesting.this.type} = ??? + + phase = SomePhase +} diff --git a/test/junit/scala/tools/nsc/symtab/SymbolTableTest.scala b/test/junit/scala/tools/nsc/symtab/SymbolTableTest.scala new file mode 100644 index 0000000000..166e0382f7 --- /dev/null +++ b/test/junit/scala/tools/nsc/symtab/SymbolTableTest.scala @@ -0,0 +1,29 @@ +package scala.tools.nsc +package symtab + +import org.junit.Assert._ +import org.junit.Test +import org.junit.runner.RunWith + +import org.junit.runners.JUnit4 + +@RunWith(classOf[JUnit4]) +class SymbolTableTest { + private def createSymbolTable: SymbolTable = new SymbolTableForUnitTesting + + @Test + def initDefinitions = { + val symbolTable = createSymbolTable + symbolTable.definitions.init() + } + + @Test + def basicSubTypeCheck = { + val symbolTable = createSymbolTable + symbolTable.definitions.init() + val listClassTpe = symbolTable.definitions.ListClass.tpe + val seqClassTpe = symbolTable.definitions.SeqClass.tpe + assertTrue("List should be subclass of Seq", listClassTpe <:< seqClassTpe) + } + +} -- cgit v1.2.3