diff --git a/compile/src/test/scala/ApplicationsTest.scala b/compile/src/test/scala/ApplicationsTest.scala index 5e799422b..b2c30a465 100644 --- a/compile/src/test/scala/ApplicationsTest.scala +++ b/compile/src/test/scala/ApplicationsTest.scala @@ -104,7 +104,7 @@ object ApplicationsTest extends Specification "Analysis plugin should detect applications" in { WithFiles(sources : _*) { case files @ Seq(main, main2, main3, main4, main5, main6, main7, main8, main9, mainA, mainB, mainC, mainD, mainE, mainF) => for(scalaVersion <- TestCompile.allVersions) - CallbackTest(scalaVersion, files, Nil) { (callback, file, log) => + CallbackTest(scalaVersion, files, Nil, Nil) { (callback, file, log) => val expected = Seq( main -> "Main", main4 -> "Main4", main8 -> "Main8", main9 -> "Main9", mainB -> "MainB", mainE -> "MainE1", mainE -> "MainE2", mainE -> "MainE3", mainE -> "MainE4", mainE -> "MainE5", mainF -> "MainF1", mainF -> "MainF2", mainF -> "MainF4") diff --git a/compile/src/test/scala/CompileTest.scala b/compile/src/test/scala/CompileTest.scala index 000272daa..5b5ffe400 100644 --- a/compile/src/test/scala/CompileTest.scala +++ b/compile/src/test/scala/CompileTest.scala @@ -8,7 +8,7 @@ import org.specs._ object CompileTest extends Specification { - /*"Analysis compiler" should { + "Analysis compiler" should { "compile basic sources" in { WithCompiler( "2.7.2" )(testCompileAnalysis) WithCompiler( "2.7.3" )(testCompileAnalysis) @@ -16,9 +16,9 @@ object CompileTest extends Specification WithCompiler( "2.7.5" )(testCompileAnalysis) WithCompiler( "2.7.7" )(testCompileAnalysis) WithCompiler( "2.8.0.Beta1" )(testCompileAnalysis) - WithCompiler( "2.8.0-SNAPSHOT" )(testCompileAnalysis) + //WithCompiler( "2.8.0-SNAPSHOT" )(testCompileAnalysis) } - }*/ + } "Raw compiler" should { "Properly handle classpaths" in { @@ -32,7 +32,7 @@ object CompileTest extends Specification { WithFiles( new File("Test.scala") -> "object Test" ) { sources => withTemporaryDirectory { temp => - val callback = new xsbti.TestCallback(Array()) + val callback = new xsbti.TestCallback(Array(), Array()) compiler(Set() ++ sources, Set.empty, temp, Nil, callback, 10, log) (callback.beganSources) must haveTheSameElementsAs(sources) } @@ -52,7 +52,7 @@ object CompileTest extends Specification def compiler(autoBoot: Boolean, compilerOnClasspath: Boolean): RawCompiler = new RawCompiler(ScalaInstance(scalaVersion, launch), autoBoot, compilerOnClasspath, log) - val callback = new xsbti.TestCallback(Array()) + val callback = new xsbti.TestCallback(Array(), Array()) val standard = compiler(true, true) val noCompiler = compiler(true, false) diff --git a/compile/src/test/scala/DetectAnnotations.scala b/compile/src/test/scala/DetectAnnotations.scala new file mode 100644 index 000000000..20000fe52 --- /dev/null +++ b/compile/src/test/scala/DetectAnnotations.scala @@ -0,0 +1,52 @@ +package xsbt + +import java.io.File +import org.specs.Specification + +object DetectAnnotations extends Specification +{ + val sources = + ("c/A.scala" -> "package c; class A(x: Int, y: Int) extends Annotation") :: + ("B.scala" -> "class B extends Annotation") :: + ("a/Super1.scala" -> "package a; trait Super1") :: + ("a/Super2.scala" -> "package a; @A(3,4) trait Super2") :: + ("a/Super3.scala" -> "package a; @B class Super3") :: + ("a/Super4.scala" -> "package a; trait Super4 { @B def test = () }") :: + ("b/Middle.scala" -> "package y.w; trait Mid extends a.Super2 with a.Super3") :: + ("b/Sub1.scala" -> "package a; class Sub1 extends a.Super3 with y.w.Mid") :: + ("b/Sub2.scala" -> "final class Sub2 extends a.Super1") :: + ("b/Sub3.scala" -> "@B @A(3,4) final class Sub3 extends a.Super1") :: + ("d/Sub4.scala" -> "@B private class Sub4 extends a.Super1") :: + ("d/Sub5.scala" -> "@B protected class Sub5 extends a.Super1") :: + ("d/Sub6.scala" -> "@B abstract class Sub6 extends a.Super1") :: + ("d/Sub7.scala" -> "class Sub7 extends a.Super4") :: + ("d/Sub8.scala" -> "class Sub8 { @A(5,6) def test(s: Int) = s }") :: + ("d/Sub9.scala" -> "object Sub9 { @B def test(s: String) = s }") :: + ("d/SubA.scala" -> "object SubA { @A(3,3) def test = s }\nclass SubA { @B private def test = s }") :: + ("d/SubB.scala" -> "object SubB { @A(3,3) def test = s }\nclass SubB { @B def test = s }") :: + Nil + + "Analysis plugin should detect annotations" in { + WithFiles(sources.map{case (file, content) => (new File(file), content)} : _*) + { + case files @ Seq(sup1File, sup2File, sup3File, sup4File, midFile, sub1File, sub2File, sub3File, sub4File, sub5File, sub6File, sub7File, sub8File, sub9File, subAFile, subBFile) => + for(scalaVersion <- TestCompile.allVersions) + CallbackTest(scalaVersion, files, Nil, Seq("c.A", "B") ) { (callback, x, xx) => + val expected = + (sup3File, "a.Super3", "B", false) :: + (sub1File, "a.Sub1", "B", false) :: + (sub1File, "a.Sub1", "c.A", false) :: + (sub3File, "Sub3", "B", false) :: + (sub3File, "Sub3", "c.A", false) :: + (sub7File, "Sub7", "B", false) :: + (sub8File, "Sub8", "c.A", false) :: + (sub9File, "Sub9", "B", true) :: + (subAFile, "SubA", "c.A", true) :: + (subBFile, "SubB", "c.A", true) :: + (subBFile, "SubB", "B", false) :: + Nil + (callback.foundAnnotated) must haveTheSameElementsAs(expected) + } + } + } +} \ No newline at end of file diff --git a/compile/src/test/scala/DetectSubclasses.scala b/compile/src/test/scala/DetectSubclasses.scala index 60e5c889c..33382c734 100644 --- a/compile/src/test/scala/DetectSubclasses.scala +++ b/compile/src/test/scala/DetectSubclasses.scala @@ -19,7 +19,7 @@ object DetectSubclasses extends Specification { case files @ Seq(supFile, sup2File, midFile, sub1File, sub2File, sub3File) => for(scalaVersion <- TestCompile.allVersions) - CallbackTest(scalaVersion, files, Seq( "a.Super", "Super2", "x.Super3", "Super4") ) { (callback, x, xx) => + CallbackTest(scalaVersion, files, Seq( "a.Super", "Super2", "x.Super3", "Super4"), Nil ) { (callback, x, xx) => val expected = (sub1File, "a.Sub1", "a.Super", false) :: (sub2File, "Sub2", "a.Super", false) :: diff --git a/compile/src/test/scala/TestCompile.scala b/compile/src/test/scala/TestCompile.scala index 898d5d468..25f2495d9 100644 --- a/compile/src/test/scala/TestCompile.scala +++ b/compile/src/test/scala/TestCompile.scala @@ -11,9 +11,9 @@ object TestCompile def allVersions = List("2.7.2", "2.7.5", "2.7.7", "2.8.0-SNAPSHOT", "2.8.0.Beta1")//List("2.7.2", "2.7.3", "2.7.4", "2.7.5", "2.8.0-SNAPSHOT") /** Tests running the compiler interface with the analyzer plugin with a test callback. The test callback saves all information * that the plugin sends it for post-compile analysis by the provided function.*/ - def apply[T](scalaVersion: String, sources: Set[File], outputDirectory: File, options: Seq[String], superclassNames: Seq[String])(f: (TestCallback, CompileLogger) => T): T = + def apply[T](scalaVersion: String, sources: Set[File], outputDirectory: File, options: Seq[String], superclassNames: Seq[String], annotationNames: Seq[String])(f: (TestCallback, CompileLogger) => T): T = { - val testCallback = new TestCallback(superclassNames.toArray) + val testCallback = new TestCallback(superclassNames.toArray, annotationNames.toArray) WithCompiler(scalaVersion) { (compiler, log) => compiler(sources, Set.empty, outputDirectory, options, testCallback, 5, log) f(testCallback, log) @@ -22,14 +22,14 @@ object TestCompile /** Tests running the compiler interface with the analyzer plugin. The provided function is given a ClassLoader that can * load the compiled classes..*/ def apply[T](scalaVersion: String, sources: Seq[File])(f: ClassLoader => T): T = - CallbackTest.apply(scalaVersion, sources, Nil){ case (callback, outputDir, log) => f(new URLClassLoader(Array(outputDir.toURI.toURL))) } + CallbackTest.apply(scalaVersion, sources, Nil, Nil){ case (callback, outputDir, log) => f(new URLClassLoader(Array(outputDir.toURI.toURL))) } } object CallbackTest { def apply[T](scalaVersion: String, sources: Iterable[File])(f: TestCallback => T): T = - apply(scalaVersion, sources.toSeq, Nil){ case (callback, outputDir, log) => f(callback) } - def apply[T](scalaVersion: String, sources: Seq[File], superclassNames: Seq[String])(f: (TestCallback, File, CompileLogger) => T): T = + apply(scalaVersion, sources.toSeq, Nil, Nil){ case (callback, outputDir, log) => f(callback) } + def apply[T](scalaVersion: String, sources: Seq[File], superclassNames: Seq[String], annotationNames: Seq[String])(f: (TestCallback, File, CompileLogger) => T): T = withTemporaryDirectory { outputDir => - TestCompile(scalaVersion, Set() ++ sources, outputDir, Nil, superclassNames) { case (callback, log) => f(callback, outputDir, log) } + TestCompile(scalaVersion, Set() ++ sources, outputDir, Nil, superclassNames, annotationNames) { case (callback, log) => f(callback, outputDir, log) } } } \ No newline at end of file diff --git a/interface/src/test/scala/TestCallback.scala b/interface/src/test/scala/TestCallback.scala index 23978f920..8e7014af7 100644 --- a/interface/src/test/scala/TestCallback.scala +++ b/interface/src/test/scala/TestCallback.scala @@ -3,12 +3,13 @@ package xsbti import java.io.File import scala.collection.mutable.ArrayBuffer -class TestCallback(val superclassNames: Array[String]) extends AnalysisCallback +class TestCallback(val superclassNames: Array[String], val annotationNames: Array[String]) extends AnalysisCallback { val invalidSuperclasses = new ArrayBuffer[String] val beganSources = new ArrayBuffer[File] val endedSources = new ArrayBuffer[File] val foundSubclasses = new ArrayBuffer[(File, String, String, Boolean)] + val foundAnnotated = new ArrayBuffer[(File, String, String, Boolean)] val sourceDependencies = new ArrayBuffer[(File, File)] val jarDependencies = new ArrayBuffer[(File, File)] val classDependencies = new ArrayBuffer[(File, File)] @@ -19,6 +20,8 @@ class TestCallback(val superclassNames: Array[String]) extends AnalysisCallback def beginSource(source: File) { beganSources += source } def foundSubclass(source: File, subclassName: String, superclassName: String, isModule: Boolean): Unit = foundSubclasses += ((source, subclassName, superclassName, isModule)) + def foundAnnotated(source: File, className: String, annotationName: String, isModule: Boolean): Unit = + foundAnnotated += ((source, className, annotationName, isModule)) def sourceDependency(dependsOn: File, source: File) { sourceDependencies += ((dependsOn, source)) } def jarDependency(jar: File, source: File) { jarDependencies += ((jar, source)) } def classDependency(clazz: File, source: File) { classDependencies += ((clazz, source)) }