diff --git a/compile/src/test/resources/sbt/compiler/javac/hasstaticfinal.java b/compile/src/test/resources/sbt/compiler/javac/hasstaticfinal.java new file mode 100644 index 000000000..00c21740a --- /dev/null +++ b/compile/src/test/resources/sbt/compiler/javac/hasstaticfinal.java @@ -0,0 +1,4 @@ +public class hasstaticfinal { + // the `TEMPLATE` string is replaced with various values during tests + public static final String HELLO = "TEMPLATE"; +} diff --git a/compile/src/test/scala/sbt/compiler/javac/JavaCompilerSpec.scala b/compile/src/test/scala/sbt/compiler/javac/JavaCompilerSpec.scala index aadfab796..f5a131674 100644 --- a/compile/src/test/scala/sbt/compiler/javac/JavaCompilerSpec.scala +++ b/compile/src/test/scala/sbt/compiler/javac/JavaCompilerSpec.scala @@ -5,6 +5,8 @@ import java.net.URLClassLoader import sbt._ import org.specs2.Specification +import xsbt.api.SameAPI +import xsbti.api.SourceAPI import xsbti.{ Severity, Problem } object JavaCompilerSpec extends Specification { @@ -14,17 +16,21 @@ object JavaCompilerSpec extends Specification { Compiling a java file with local javac should - compile a java file ${works(local)} - issue errors and warnings ${findsErrors(local)} + compile a java file ${works(local)} + issue errors and warnings ${findsErrors(local)} Compiling a file with forked javac should - compile a java file ${works(forked)} - issue errors and warnings ${findsErrors(forked)} - yield the same errors as local javac $forkSameAsLocal + compile a java file ${works(forked)} + issue errors and warnings ${findsErrors(forked)} + yield the same errors as local javac $forkSameAsLocal Documenting a file with forked javadoc should - document a java file ${docWorks(forked)} - find errors in a java file ${findsDocErrors(forked)} + document a java file ${docWorks(forked)} + find errors in a java file ${findsDocErrors(forked)} + + // TODO: move somewhere analysis-specific + Analyzing classes generated by javac should + result in different APIs for static-final-primitive fields ${analyzeStaticDifference(local)} """ // TODO - write a test to ensure that java .class files wind up in the right spot, and we can call the compiled java code. @@ -64,6 +70,30 @@ object JavaCompilerSpec extends Specification { errored and foundErrorAndWarning and hasKnownErrors } + def analyzeStaticDifference(compiler: JavaTools) = { + def compileWithPrimitive(templateValue: String) = + IO.withTemporaryDirectory { out => + // copy the input file to a temporary location and change the templateValue + val input = new File(out, hasStaticFinalFile.getName()) + IO.writeLines( + input, + IO.readLines(hasStaticFinalFile).map(_.replace("TEMPLATE", templateValue)) + ) + + // then compile it + val (result, problems) = compile(compiler, Seq(input), Seq("-d", out.getAbsolutePath)) + val origCompiled = result must beTrue + val clazzz = new URLClassLoader(Array(out.toURI.toURL)).loadClass("hasstaticfinal") + (origCompiled, ClassToAPI(Seq(clazzz))) + } + + // compile with two different primitive values, and confirm that they're non-equal + val (prevCompiled, prevAPI) = compileWithPrimitive("A") + val (nextCompiled, nextAPI) = compileWithPrimitive("B") + val apisNonEqual = SameAPI(prevAPI, nextAPI) must beFalse + prevCompiled and nextCompiled and apisNonEqual + } + def lineMatches(p: Problem, lineno: Int): Boolean = p.position.line.isDefined && (p.position.line.get == lineno) def isError(p: Problem): Boolean = p.severity == Severity.Error @@ -131,4 +161,8 @@ object JavaCompilerSpec extends Specification { def knownSampleGoodFile = new java.io.File(getClass.getResource("good.java").toURI) -} \ No newline at end of file + + def hasStaticFinalFile = + new java.io.File(getClass.getResource("hasstaticfinal.java").toURI) + +}