diff --git a/integration/feature/auxiliary-class-files/repo/app/src/foo.scala b/integration/feature/auxiliary-class-files/repo/app/src/foo.scala new file mode 100644 index 00000000000..7ed8ede3e5d --- /dev/null +++ b/integration/feature/auxiliary-class-files/repo/app/src/foo.scala @@ -0,0 +1 @@ +object foo diff --git a/integration/feature/auxiliary-class-files/repo/build.sc b/integration/feature/auxiliary-class-files/repo/build.sc new file mode 100644 index 00000000000..3a783ad4c6e --- /dev/null +++ b/integration/feature/auxiliary-class-files/repo/build.sc @@ -0,0 +1,20 @@ +// Issue https://github.com/com-lihaoyi/mill/issues/3068 +import mill._ +import mill.scalalib._ +import mill.scalajslib._ +import mill.scalanativelib._ + +object app extends Module { + trait Common extends ScalaModule { + def millSourcePath = super.millSourcePath / os.up + def scalaVersion = "3.4.0" + } + + object jvm extends Common + object js extends Common with ScalaJSModule { + def scalaJSVersion = "1.15.0" + } + object native extends Common with ScalaNativeModule { + def scalaNativeVersion = "0.4.17" + } +} diff --git a/integration/feature/auxiliary-class-files/test/src/AuxiliaryClassFilesTests.scala b/integration/feature/auxiliary-class-files/test/src/AuxiliaryClassFilesTests.scala new file mode 100644 index 00000000000..e61be90f33f --- /dev/null +++ b/integration/feature/auxiliary-class-files/test/src/AuxiliaryClassFilesTests.scala @@ -0,0 +1,59 @@ +package mill.integration + +import utest._ + +// Regress test for issue https://github.com/com-lihaoyi/mill/issues/1901 +object AuxiliaryClassFilesTests extends IntegrationTestSuite { + val tests: Tests = Tests { + test("tasty files are deleted together with companion class files") { + initWorkspace() + eval("app.jvm.compile") + + val classes = wd / "out" / "app" / "jvm" / "compile.dest" / "classes" + val firstRun = os.list(classes).map(_.last) + + os.remove(wd / "app" / "src" / "foo.scala") + + eval("app.jvm.compile") + + val secondRun = os.list(classes).map(_.last) + + assert(firstRun == Seq("foo$.class", "foo.class", "foo.tasty")) + assert(secondRun == Seq.empty) + } + + test("nir files are deleted together with companion class files") { + initWorkspace() + eval("app.native.compile") + + val classes = wd / "out" / "app" / "native" / "compile.dest" / "classes" + val firstRun = os.list(classes).map(_.last) + + os.remove(wd / "app" / "src" / "foo.scala") + + eval("app.native.compile") + + val secondRun = os.list(classes).map(_.last) + + assert(firstRun == Seq("foo$.class", "foo$.nir", "foo.class", "foo.nir", "foo.tasty")) + assert(secondRun == Seq.empty) + } + + test("sjsir files are deleted together with companion class files") { + initWorkspace() + eval("app.js.compile") + + val classes = wd / "out" / "app" / "js" / "compile.dest" / "classes" + val firstRun = os.list(classes).map(_.last) + + os.remove(wd / "app" / "src" / "foo.scala") + + eval("app.js.compile") + + val secondRun = os.list(classes).map(_.last) + + assert(firstRun == Seq("foo$.class", "foo$.sjsir", "foo.class", "foo.tasty")) + assert(secondRun == Seq.empty) + } + } +} diff --git a/scalalib/api/src/mill/scalalib/api/ZincWorkerApi.scala b/scalalib/api/src/mill/scalalib/api/ZincWorkerApi.scala index dc04fb91a15..f0a1b103ef4 100644 --- a/scalalib/api/src/mill/scalalib/api/ZincWorkerApi.scala +++ b/scalalib/api/src/mill/scalalib/api/ZincWorkerApi.scala @@ -56,6 +56,7 @@ trait ZincWorkerApi { compileClasspath: Agg[os.Path], javacOptions: Seq[String], scalaVersion: String, + platformSuffix: String, scalaOrganization: String, scalacOptions: Seq[String], compilerClasspath: Agg[PathRef], @@ -70,13 +71,15 @@ trait ZincWorkerApi { compileClasspath = compileClasspath, javacOptions = javacOptions, scalaVersion = scalaVersion, + platformSuffix = platformSuffix, scalaOrganization = scalaOrganization, scalacOptions = scalacOptions, compilerClasspath = compilerClasspath, scalacPluginClasspath = scalacPluginClasspath, reporter = reporter, - reportCachedProblems = reportCachedProblems - ): @nowarn("cat=deprecation") + reportCachedProblems = reportCachedProblems, + incrementalCompilation = incrementalCompilation + ) /** Compile a mixed Scala/Java or Scala-only project */ @deprecated("Use override with `incrementalCompilation` parameter", "Mill 0.11.6") @@ -99,6 +102,7 @@ trait ZincWorkerApi { compileClasspath = compileClasspath, javacOptions = javacOptions, scalaVersion = scalaVersion, + platformSuffix = "", scalaOrganization = scalaOrganization, scalacOptions = scalacOptions, compilerClasspath = compilerClasspath, @@ -108,6 +112,38 @@ trait ZincWorkerApi { incrementalCompilation = true ) + /** Compile a mixed Scala/Java or Scala-only project */ + @deprecated("Use override with `platformSuffix` parameter", "Mill 0.11.8") + def compileMixed( + upstreamCompileOutput: Seq[CompilationResult], + sources: Agg[os.Path], + compileClasspath: Agg[os.Path], + javacOptions: Seq[String], + scalaVersion: String, + scalaOrganization: String, + scalacOptions: Seq[String], + compilerClasspath: Agg[PathRef], + scalacPluginClasspath: Agg[PathRef], + reporter: Option[CompileProblemReporter], + reportCachedProblems: Boolean, + incrementalCompilation: Boolean + )(implicit ctx: ZincWorkerApi.Ctx): mill.api.Result[CompilationResult] = + compileMixed( + upstreamCompileOutput = upstreamCompileOutput, + sources = sources, + compileClasspath = compileClasspath, + javacOptions = javacOptions, + scalaVersion = scalaVersion, + platformSuffix = "", + scalaOrganization = scalaOrganization, + scalacOptions = scalacOptions, + compilerClasspath = compilerClasspath, + scalacPluginClasspath = scalacPluginClasspath, + reporter = reporter, + reportCachedProblems = reportCachedProblems, + incrementalCompilation = incrementalCompilation + ) + def discoverMainClasses(compilationResult: CompilationResult): Seq[String] def docJar( diff --git a/scalalib/src/mill/scalalib/ScalaModule.scala b/scalalib/src/mill/scalalib/ScalaModule.scala index da7eed4b6c8..8974720a1c9 100644 --- a/scalalib/src/mill/scalalib/ScalaModule.scala +++ b/scalalib/src/mill/scalalib/ScalaModule.scala @@ -292,6 +292,7 @@ trait ScalaModule extends JavaModule with TestModule.ScalaModuleBase { outer => compileClasspath = compileClasspath().map(_.path), javacOptions = javacOptions(), scalaVersion = sv, + platformSuffix = platformSuffix(), scalaOrganization = scalaOrganization(), scalacOptions = allScalacOptions(), compilerClasspath = scalaCompilerClasspath(), @@ -659,6 +660,7 @@ trait ScalaModule extends JavaModule with TestModule.ScalaModuleBase { outer => (compileClasspath() ++ resolvedSemanticDbJavaPluginIvyDeps()).map(_.path), javacOptions = javacOpts, scalaVersion = sv, + platformSuffix = platformSuffix(), scalaOrganization = scalaOrganization(), scalacOptions = scalacOptions, compilerClasspath = scalaCompilerClasspath(), diff --git a/scalalib/worker/src/mill/scalalib/worker/ZincWorkerImpl.scala b/scalalib/worker/src/mill/scalalib/worker/ZincWorkerImpl.scala index b604c673d27..d0c68dc4a13 100644 --- a/scalalib/worker/src/mill/scalalib/worker/ZincWorkerImpl.scala +++ b/scalalib/worker/src/mill/scalalib/worker/ZincWorkerImpl.scala @@ -20,6 +20,7 @@ import sbt.internal.util.{ConsoleAppender, ConsoleOut} import sbt.mill.SbtLoggerUtils import xsbti.compile.{ AnalysisContents, + AuxiliaryClassFiles, ClasspathOptions, CompileAnalysis, CompileOrder, @@ -27,7 +28,10 @@ import xsbti.compile.{ IncOptions, JavaTools, MiniSetup, - PreviousResult + PreviousResult, + ScalaJSFiles, + ScalaNativeFiles, + TastyFiles } import xsbti.{PathBasedFile, VirtualFile} @@ -303,6 +307,7 @@ class ZincWorkerImpl( compileClasspath = compileClasspath, javacOptions = javacOptions, scalacOptions = Nil, + platformSuffix = "", compilers = javaOnlyCompilers(javacOptions), reporter = reporter, reportCachedProblems = reportCachedProblems, @@ -316,6 +321,7 @@ class ZincWorkerImpl( compileClasspath: Agg[os.Path], javacOptions: Seq[String], scalaVersion: String, + platformSuffix: String, scalaOrganization: String, scalacOptions: Seq[String], compilerClasspath: Agg[PathRef], @@ -337,6 +343,7 @@ class ZincWorkerImpl( compileClasspath = compileClasspath, javacOptions = javacOptions, scalacOptions = scalacOptions, + platformSuffix = platformSuffix, compilers = compilers, reporter = reporter, reportCachedProblems: Boolean, @@ -420,6 +427,7 @@ class ZincWorkerImpl( compileClasspath: Agg[os.Path], javacOptions: Seq[String], scalacOptions: Seq[String], + platformSuffix: String, compilers: Compilers, reporter: Option[CompileProblemReporter], reportCachedProblems: Boolean, @@ -496,6 +504,25 @@ class ZincWorkerImpl( .map(path => converter.toVirtualFile(path.toNIO)) .toArray + val incOptions = { + val platformSpecificFiles: Array[AuxiliaryClassFiles] = platformSuffix match { + case s"_sjs$_" => Array(ScalaJSFiles.instance()) + case s"_native$_" => Array(ScalaNativeFiles.instance()) + case _ => Array.empty[AuxiliaryClassFiles] + } + + val scalaVersionSpecificFiles: Array[AuxiliaryClassFiles] = + if (ZincWorkerUtil.isDottyOrScala3(compilers.scalac().scalaInstance().version())) + Array(TastyFiles.instance()) + else + Array.empty[AuxiliaryClassFiles] + + val auxiliaryClassFiles: Array[AuxiliaryClassFiles] = + platformSpecificFiles ++ scalaVersionSpecificFiles + + IncOptions.of().withAuxiliaryClassFiles(auxiliaryClassFiles) + } + val inputs = ic.inputs( classpath = classpath, sources = virtualSources, @@ -512,7 +539,7 @@ class ZincWorkerImpl( skip = false, cacheFile = zincFile.toNIO, cache = new FreshCompilerCache, - incOptions = IncOptions.of(), + incOptions = incOptions, reporter = newReporter, progress = None, earlyAnalysisStore = None,