From 09d93258ffbb6c15316fe520c3c3094f30f40cdb Mon Sep 17 00:00:00 2001 From: Justinas Simanavicius Date: Thu, 17 Mar 2022 16:34:59 +0200 Subject: [PATCH 01/10] dep analyzer 3 --- .../DependencyAnalyzer.scala | 25 +++-- .../dependency_analyzer/src/test/BUILD | 4 +- .../src/test/analyzer_test.bzl | 104 +----------------- .../src/test/analyzer_test_scala_2.bzl | 99 +++++++++++++++++ .../src/test/analyzer_test_scala_3.bzl | 12 ++ .../rulesscala/dependencyanalyzer3/Test.scala | 10 ++ 6 files changed, 143 insertions(+), 111 deletions(-) create mode 100644 third_party/dependency_analyzer/src/test/analyzer_test_scala_2.bzl create mode 100644 third_party/dependency_analyzer/src/test/analyzer_test_scala_3.bzl create mode 100644 third_party/dependency_analyzer/src/test/io/bazel/rulesscala/dependencyanalyzer3/Test.scala diff --git a/third_party/dependency_analyzer/src/main/io/bazel/rulesscala/dependencyanalyzer3/DependencyAnalyzer.scala b/third_party/dependency_analyzer/src/main/io/bazel/rulesscala/dependencyanalyzer3/DependencyAnalyzer.scala index d1050a78e..d2034003f 100644 --- a/third_party/dependency_analyzer/src/main/io/bazel/rulesscala/dependencyanalyzer3/DependencyAnalyzer.scala +++ b/third_party/dependency_analyzer/src/main/io/bazel/rulesscala/dependencyanalyzer3/DependencyAnalyzer.scala @@ -1,28 +1,30 @@ package io.bazel.rulesscala.dependencyanalyzer -import dotty.tools.dotc.ast.Trees.* +import dotty.tools.dotc.ast.Trees._ import dotty.tools.dotc.ast.tpd import dotty.tools.dotc.core.Constants.Constant import dotty.tools.dotc.core.Contexts.Context -import dotty.tools.dotc.core.Decorators.* -import dotty.tools.dotc.core.StdNames.* -import dotty.tools.dotc.core.Symbols.* +import dotty.tools.dotc.core.Decorators._ +import dotty.tools.dotc.core.StdNames._ +import dotty.tools.dotc.core.Symbols._ import dotty.tools.dotc.plugins.{PluginPhase, StandardPlugin} import dotty.tools.dotc.transform.{Pickler, Staging} -class DependencyAnalyzer extends StandardPlugin: +class DependencyAnalyzer extends StandardPlugin { override val name: String = "dependency-analyzer" override val description: String = "Analyzes the used dependencies. Can check and warn or fail the " + - "compilation for issues including not directly including " + - "dependencies which are directly included in the code, or " + - "including unused dependencies." + "compilation for issues including not directly including " + + "dependencies which are directly included in the code, or " + + "including unused dependencies." def init(options: List[String]): List[PluginPhase] = (new DependencyAnalyzerPhase) :: Nil +} -class DependencyAnalyzerPhase extends PluginPhase: - import tpd.* +class DependencyAnalyzerPhase extends PluginPhase { + + import tpd._ val phaseName = "dependecy-analyzer-phase" @@ -30,4 +32,5 @@ class DependencyAnalyzerPhase extends PluginPhase: override val runsBefore = Set(Staging.name) override def transformApply(tree: Apply)(implicit ctx: Context): Tree = - tree \ No newline at end of file + tree +} \ No newline at end of file diff --git a/third_party/dependency_analyzer/src/test/BUILD b/third_party/dependency_analyzer/src/test/BUILD index 2953466f0..000b77b5c 100644 --- a/third_party/dependency_analyzer/src/test/BUILD +++ b/third_party/dependency_analyzer/src/test/BUILD @@ -1,3 +1,3 @@ -load(":analyzer_test.bzl", "analyzer_tests") +load(":analyzer_test.bzl", "tests") -analyzer_tests() +tests() diff --git a/third_party/dependency_analyzer/src/test/analyzer_test.bzl b/third_party/dependency_analyzer/src/test/analyzer_test.bzl index 7bef01e99..2676ea7c5 100644 --- a/third_party/dependency_analyzer/src/test/analyzer_test.bzl +++ b/third_party/dependency_analyzer/src/test/analyzer_test.bzl @@ -1,101 +1,9 @@ -load("//scala:scala.bzl", "scala_test") +load(":analyzer_test_scala_2.bzl", "analyzer_tests_scala_2") +load(":analyzer_test_scala_3.bzl", "analyzer_tests_scala_3") load("@io_bazel_rules_scala_config//:config.bzl", "SCALA_MAJOR_VERSION") -def analyzer_tests(): +def tests(): if SCALA_MAJOR_VERSION.startswith("2"): - common_jvm_flags = [ - "-Dplugin.jar.location=$(execpath //third_party/dependency_analyzer/src/main:dependency_analyzer)", - "-Dscala.library.location=$(rootpath @io_bazel_rules_scala_scala_library)", - "-Dscala.reflect.location=$(rootpath @io_bazel_rules_scala_scala_reflect)", - ] - - scala_test( - name = "ast_used_jar_finder_test", - size = "small", - srcs = [ - "io/bazel/rulesscala/dependencyanalyzer/AstUsedJarFinderTest.scala", - ], - jvm_flags = common_jvm_flags, - deps = [ - "//src/java/io/bazel/rulesscala/io_utils", - "//third_party/dependency_analyzer/src/main:dependency_analyzer", - "//third_party/dependency_analyzer/src/main:scala_version", - "//third_party/utils/src/test:test_util", - "@io_bazel_rules_scala_scala_compiler", - "@io_bazel_rules_scala_scala_library", - "@io_bazel_rules_scala_scala_reflect", - ], - ) - - scala_test( - name = "scala_version_test", - size = "small", - srcs = [ - "io/bazel/rulesscala/dependencyanalyzer/ScalaVersionTest.scala", - ], - deps = [ - "//third_party/dependency_analyzer/src/main:scala_version", - "@io_bazel_rules_scala_scala_library", - "@io_bazel_rules_scala_scala_reflect", - ], - ) - - scala_test( - name = "scalac_dependency_test", - size = "small", - srcs = [ - "io/bazel/rulesscala/dependencyanalyzer/ScalacDependencyTest.scala", - ], - jvm_flags = common_jvm_flags, - unused_dependency_checker_mode = "off", - deps = [ - "//src/java/io/bazel/rulesscala/io_utils", - "//third_party/dependency_analyzer/src/main:dependency_analyzer", - "//third_party/utils/src/test:test_util", - "@io_bazel_rules_scala_scala_compiler", - "@io_bazel_rules_scala_scala_library", - "@io_bazel_rules_scala_scala_reflect", - ], - ) - - scala_test( - name = "strict_deps_test", - size = "small", - srcs = [ - "io/bazel/rulesscala/dependencyanalyzer/StrictDepsTest.scala", - ], - jvm_flags = common_jvm_flags + [ - "-Dguava.jar.location=$(rootpath @com_google_guava_guava_21_0_with_file//jar)", - "-Dapache.commons.jar.location=$(location @org_apache_commons_commons_lang_3_5_without_file//:linkable_org_apache_commons_commons_lang_3_5_without_file)", - ], - unused_dependency_checker_mode = "off", - deps = [ - "//third_party/dependency_analyzer/src/main:dependency_analyzer", - "//third_party/utils/src/test:test_util", - "@com_google_guava_guava_21_0_with_file//jar", - "@io_bazel_rules_scala_scala_compiler", - "@io_bazel_rules_scala_scala_library", - "@io_bazel_rules_scala_scala_reflect", - "@org_apache_commons_commons_lang_3_5_without_file//:linkable_org_apache_commons_commons_lang_3_5_without_file", - ], - ) - - scala_test( - name = "unused_dependency_checker_test", - size = "small", - srcs = [ - "io/bazel/rulesscala/dependencyanalyzer/UnusedDependencyCheckerTest.scala", - ], - jvm_flags = common_jvm_flags + [ - "-Dapache.commons.jar.location=$(location @org_apache_commons_commons_lang_3_5_without_file//:linkable_org_apache_commons_commons_lang_3_5_without_file)", - ], - unused_dependency_checker_mode = "off", - deps = [ - "//third_party/dependency_analyzer/src/main:dependency_analyzer", - "//third_party/utils/src/test:test_util", - "@io_bazel_rules_scala_scala_compiler", - "@io_bazel_rules_scala_scala_library", - "@io_bazel_rules_scala_scala_reflect", - "@org_apache_commons_commons_lang_3_5_without_file//:linkable_org_apache_commons_commons_lang_3_5_without_file", - ], - ) + analyzer_tests_scala_2() + else: + analyzer_tests_scala_3() diff --git a/third_party/dependency_analyzer/src/test/analyzer_test_scala_2.bzl b/third_party/dependency_analyzer/src/test/analyzer_test_scala_2.bzl new file mode 100644 index 000000000..d599b0119 --- /dev/null +++ b/third_party/dependency_analyzer/src/test/analyzer_test_scala_2.bzl @@ -0,0 +1,99 @@ +load("//scala:scala.bzl", "scala_test") + +def analyzer_tests_scala_2(): + common_jvm_flags = [ + "-Dplugin.jar.location=$(execpath //third_party/dependency_analyzer/src/main:dependency_analyzer)", + "-Dscala.library.location=$(rootpath @io_bazel_rules_scala_scala_library)", + "-Dscala.reflect.location=$(rootpath @io_bazel_rules_scala_scala_reflect)", + ] + + scala_test( + name = "ast_used_jar_finder_test", + size = "small", + srcs = [ + "io/bazel/rulesscala/dependencyanalyzer/AstUsedJarFinderTest.scala", + ], + jvm_flags = common_jvm_flags, + deps = [ + "//src/java/io/bazel/rulesscala/io_utils", + "//third_party/dependency_analyzer/src/main:dependency_analyzer", + "//third_party/dependency_analyzer/src/main:scala_version", + "//third_party/utils/src/test:test_util", + "@io_bazel_rules_scala_scala_compiler", + "@io_bazel_rules_scala_scala_library", + "@io_bazel_rules_scala_scala_reflect", + ], + ) + + scala_test( + name = "scala_version_test", + size = "small", + srcs = [ + "io/bazel/rulesscala/dependencyanalyzer/ScalaVersionTest.scala", + ], + deps = [ + "//third_party/dependency_analyzer/src/main:scala_version", + "@io_bazel_rules_scala_scala_library", + "@io_bazel_rules_scala_scala_reflect", + ], + ) + + scala_test( + name = "scalac_dependency_test", + size = "small", + srcs = [ + "io/bazel/rulesscala/dependencyanalyzer/ScalacDependencyTest.scala", + ], + jvm_flags = common_jvm_flags, + unused_dependency_checker_mode = "off", + deps = [ + "//src/java/io/bazel/rulesscala/io_utils", + "//third_party/dependency_analyzer/src/main:dependency_analyzer", + "//third_party/utils/src/test:test_util", + "@io_bazel_rules_scala_scala_compiler", + "@io_bazel_rules_scala_scala_library", + "@io_bazel_rules_scala_scala_reflect", + ], + ) + + scala_test( + name = "strict_deps_test", + size = "small", + srcs = [ + "io/bazel/rulesscala/dependencyanalyzer/StrictDepsTest.scala", + ], + jvm_flags = common_jvm_flags + [ + "-Dguava.jar.location=$(rootpath @com_google_guava_guava_21_0_with_file//jar)", + "-Dapache.commons.jar.location=$(location @org_apache_commons_commons_lang_3_5_without_file//:linkable_org_apache_commons_commons_lang_3_5_without_file)", + ], + unused_dependency_checker_mode = "off", + deps = [ + "//third_party/dependency_analyzer/src/main:dependency_analyzer", + "//third_party/utils/src/test:test_util", + "@com_google_guava_guava_21_0_with_file//jar", + "@io_bazel_rules_scala_scala_compiler", + "@io_bazel_rules_scala_scala_library", + "@io_bazel_rules_scala_scala_reflect", + "@org_apache_commons_commons_lang_3_5_without_file//:linkable_org_apache_commons_commons_lang_3_5_without_file", + ], + ) + + scala_test( + name = "unused_dependency_checker_test", + size = "small", + srcs = [ + "io/bazel/rulesscala/dependencyanalyzer/UnusedDependencyCheckerTest.scala", + ], + jvm_flags = common_jvm_flags + [ + "-Dapache.commons.jar.location=$(location @org_apache_commons_commons_lang_3_5_without_file//:linkable_org_apache_commons_commons_lang_3_5_without_file)", + ], + unused_dependency_checker_mode = "off", + deps = [ + "//third_party/dependency_analyzer/src/main:dependency_analyzer", + "//third_party/utils/src/test:test_util", + "@io_bazel_rules_scala_scala_compiler", + "@io_bazel_rules_scala_scala_library", + "@io_bazel_rules_scala_scala_reflect", + "@org_apache_commons_commons_lang_3_5_without_file//:linkable_org_apache_commons_commons_lang_3_5_without_file", + ], + ) diff --git a/third_party/dependency_analyzer/src/test/analyzer_test_scala_3.bzl b/third_party/dependency_analyzer/src/test/analyzer_test_scala_3.bzl new file mode 100644 index 000000000..88da3c9e7 --- /dev/null +++ b/third_party/dependency_analyzer/src/test/analyzer_test_scala_3.bzl @@ -0,0 +1,12 @@ +load("@io_bazel_rules_scala//scala:scala.bzl", "scala_test") + +def analyzer_tests_scala_3(): + common_jvm_flags = [ + ] + + scala_test( + name = "test_that_tests_run", + srcs = [ + "io/bazel/rulesscala/dependencyanalyzer3/Test.scala", + ], + ) diff --git a/third_party/dependency_analyzer/src/test/io/bazel/rulesscala/dependencyanalyzer3/Test.scala b/third_party/dependency_analyzer/src/test/io/bazel/rulesscala/dependencyanalyzer3/Test.scala new file mode 100644 index 000000000..633349ebe --- /dev/null +++ b/third_party/dependency_analyzer/src/test/io/bazel/rulesscala/dependencyanalyzer3/Test.scala @@ -0,0 +1,10 @@ +package io.bazel.rulesscala.dependencyanalyzer + +import org.scalatest.funsuite.AnyFunSuite + +class Test extends AnyFunSuite { + + test("An empty Set should have size 0") { + assert("true" == "true") + } +} \ No newline at end of file From 1e91cd6ada43966130d4e7bca6701276194c2c44 Mon Sep 17 00:00:00 2001 From: Justinas Simanavicius Date: Fri, 18 Mar 2022 17:28:14 +0200 Subject: [PATCH 02/10] dep analyzer 3 --- .../rulesscala/scalac/ScalacWorker3.java | 1 + .../src/test/analyzer_test_scala_3.bzl | 14 ++- .../dependencyanalyzer3/CompileTest.scala | 24 +++++ .../rulesscala/dependencyanalyzer3/Test.scala | 10 -- third_party/utils/src/test/BUILD | 3 +- .../io/bazel/rulesscala/utils/TestUtil3.scala | 92 +++++++++++++++++++ 6 files changed, 131 insertions(+), 13 deletions(-) create mode 100644 third_party/dependency_analyzer/src/test/io/bazel/rulesscala/dependencyanalyzer3/CompileTest.scala delete mode 100644 third_party/dependency_analyzer/src/test/io/bazel/rulesscala/dependencyanalyzer3/Test.scala create mode 100644 third_party/utils/src/test/io/bazel/rulesscala/utils/TestUtil3.scala diff --git a/src/java/io/bazel/rulesscala/scalac/ScalacWorker3.java b/src/java/io/bazel/rulesscala/scalac/ScalacWorker3.java index 370be2904..46d0fcfd5 100644 --- a/src/java/io/bazel/rulesscala/scalac/ScalacWorker3.java +++ b/src/java/io/bazel/rulesscala/scalac/ScalacWorker3.java @@ -268,6 +268,7 @@ private static void compileScalaSources(CompileOptions ops, String[] scalaSource Reporter reporter = driver.doCompile(compiler, r._1, r._2); + long stop = System.currentTimeMillis(); if (ops.printCompileTime) { System.err.println("Compiler runtime: " + (stop - start) + "ms."); diff --git a/third_party/dependency_analyzer/src/test/analyzer_test_scala_3.bzl b/third_party/dependency_analyzer/src/test/analyzer_test_scala_3.bzl index 88da3c9e7..2fe5234d9 100644 --- a/third_party/dependency_analyzer/src/test/analyzer_test_scala_3.bzl +++ b/third_party/dependency_analyzer/src/test/analyzer_test_scala_3.bzl @@ -2,11 +2,23 @@ load("@io_bazel_rules_scala//scala:scala.bzl", "scala_test") def analyzer_tests_scala_3(): common_jvm_flags = [ + "-Dplugin.jar.location=$(execpath //third_party/dependency_analyzer/src/main:dependency_analyzer)", + "-Dscala.library.location=$(rootpath @io_bazel_rules_scala_scala_library)", + "-Dscala.library2.location=$(rootpath @io_bazel_rules_scala_scala_library_2)", ] scala_test( name = "test_that_tests_run", + size = "small", + jvm_flags = common_jvm_flags, srcs = [ - "io/bazel/rulesscala/dependencyanalyzer3/Test.scala", + "io/bazel/rulesscala/dependencyanalyzer3/CompileTest.scala", + ], + deps = [ + "//scala/private/toolchain_deps:scala_compile_classpath", + "//third_party/dependency_analyzer/src/main:dependency_analyzer", + "//third_party/utils/src/test:test_util", + "@io_bazel_rules_scala_scala_library", + "@io_bazel_rules_scala_scala_library_2", ], ) diff --git a/third_party/dependency_analyzer/src/test/io/bazel/rulesscala/dependencyanalyzer3/CompileTest.scala b/third_party/dependency_analyzer/src/test/io/bazel/rulesscala/dependencyanalyzer3/CompileTest.scala new file mode 100644 index 000000000..0e941b751 --- /dev/null +++ b/third_party/dependency_analyzer/src/test/io/bazel/rulesscala/dependencyanalyzer3/CompileTest.scala @@ -0,0 +1,24 @@ +package io.bazel.rulesscala.dependencyanalyzer + +import org.scalatest.funsuite.AnyFunSuite +import io.bazel.rulesscala.utils.TestUtil3 + +class CompileTest extends AnyFunSuite { + + test("Util compiles valid code") { + val scalaCode = "class Foo { }" + val messages = TestUtil3.runCompiler(scalaCode) + + assert(messages.isEmpty, "No messages must be reported when valid code is compiled") + } + + test("Util returns errors on invalid code") { + val scalaCode = "!@#" + val messages = TestUtil3.runCompiler(scalaCode) + + assert( + messages.exists(_.message.contains("Illegal start of toplevel definition")), + "Error must be reported when valid code is compiled" + ) + } +} \ No newline at end of file diff --git a/third_party/dependency_analyzer/src/test/io/bazel/rulesscala/dependencyanalyzer3/Test.scala b/third_party/dependency_analyzer/src/test/io/bazel/rulesscala/dependencyanalyzer3/Test.scala deleted file mode 100644 index 633349ebe..000000000 --- a/third_party/dependency_analyzer/src/test/io/bazel/rulesscala/dependencyanalyzer3/Test.scala +++ /dev/null @@ -1,10 +0,0 @@ -package io.bazel.rulesscala.dependencyanalyzer - -import org.scalatest.funsuite.AnyFunSuite - -class Test extends AnyFunSuite { - - test("An empty Set should have size 0") { - assert("true" == "true") - } -} \ No newline at end of file diff --git a/third_party/utils/src/test/BUILD b/third_party/utils/src/test/BUILD index ae5a9e635..f9edfb4b4 100644 --- a/third_party/utils/src/test/BUILD +++ b/third_party/utils/src/test/BUILD @@ -5,8 +5,7 @@ licenses(["notice"]) # 3-clause BSD scala_library( name = "test_util", srcs = [ - "io/bazel/rulesscala/utils/JavaCompileUtil.scala", - "io/bazel/rulesscala/utils/TestUtil.scala", + "io/bazel/rulesscala/utils/TestUtil3.scala", ], visibility = ["//visibility:public"], deps = [ diff --git a/third_party/utils/src/test/io/bazel/rulesscala/utils/TestUtil3.scala b/third_party/utils/src/test/io/bazel/rulesscala/utils/TestUtil3.scala new file mode 100644 index 000000000..dd8fbc5ec --- /dev/null +++ b/third_party/utils/src/test/io/bazel/rulesscala/utils/TestUtil3.scala @@ -0,0 +1,92 @@ +package io.bazel.rulesscala.utils + +import dotty.tools.dotc.Compiler +import dotty.tools.dotc.core.Contexts._ +import dotty.tools.dotc.reporting.Diagnostic +import dotty.tools.dotc.util.SourceFile + +import java.nio.file.{Path, Paths} + +object TestUtil3 { + final val defaultTarget = "//..." + + case class DependencyAnalyzerTestParams( + //dependencyTrackingMethod: DependencyTrackingMethod, + strictDeps: Boolean = false, + unusedDeps: Boolean = false, + directJars: List[String] = List.empty, + directTargets: List[String] = List.empty, + indirectJars: List[String] = List.empty, + indirectTargets: List[String] = List.empty + ) + + /** + * Runs the compiler on a piece of code. + * + * @param dependencyAnalyzerParamsOpt If set, includes the dependency analyzer + * plugin with the provided parameters + * @param outputPathOpt If non-None, a directory to output the files in + * @return list of errors returned by the compiler + */ + def runCompiler( + code: String, + extraClasspath: List[String] = List.empty, + dependencyAnalyzerParamsOpt: Option[DependencyAnalyzerTestParams] = None, + outputPathOpt: Option[Path] = None + ): List[Diagnostic] = { + val reporter = new TestReporter() + implicit val ctx = (new ContextBase).initialCtx.fresh + .setReporter(reporter) + .setDebug + val fullClassPath = + (List(getClasspathArguments(extraClasspath)) :+ ctx.settings.classpath.value).mkString(":") + ctx.setSetting(ctx.settings.classpath, fullClassPath) + + val compiler = new Compiler() + val run = compiler.newRun + run.compileSources(List(SourceFile.virtual("some.scala", code, false))) + run.printSummary() + + reporter.storedInfos + } + + private def getClasspathArguments(extraClasspath: List[String]): String = { + val classpathEntries = { + val builtinClassPaths = builtinClasspaths.filterNot(_.isEmpty) + extraClasspath ++ builtinClassPaths + } + if (classpathEntries.isEmpty) { + "" + } else { + s"${classpathEntries.mkString(":")}" + } + } + + private lazy val builtinClasspaths: Vector[String] = + Vector( + pathOf("scala.library.location"), + pathOf("scala.library2.location") + ) + + lazy val guavaClasspath: String = + pathOf("guava.jar.location") + + lazy val apacheCommonsClasspath: String = + pathOf("apache.commons.jar.location") + + private def pathOf(jvmFlag: String) = { + val jar = System.getProperty(jvmFlag) + val libPath = Paths.get(baseDir, jar).toAbsolutePath + libPath.toString + } + + private lazy val baseDir = System.getProperty("user.dir") + + +} + +import dotty.tools.dotc.reporting.StoreReporter + +class TestReporter extends StoreReporter(null) { + def storedInfos = if(infos != null) infos.toList else List() +} \ No newline at end of file From 701d16fee87c406ac866cc5044f33e1511c57338 Mon Sep 17 00:00:00 2001 From: Justinas Simanavicius Date: Fri, 18 Mar 2022 17:52:20 +0200 Subject: [PATCH 03/10] dep analyzer 3 --- .../dependencyanalyzer3/CompileTest.scala | 6 +- third_party/utils/src/test/BUILD | 14 ++- .../utils/Scala3CompilerUtils.scala | 52 +++++++++++ .../io/bazel/rulesscala/utils/TestUtil3.scala | 92 ------------------- 4 files changed, 68 insertions(+), 96 deletions(-) create mode 100644 third_party/utils/src/test/io/bazel/rulesscala/utils/Scala3CompilerUtils.scala delete mode 100644 third_party/utils/src/test/io/bazel/rulesscala/utils/TestUtil3.scala diff --git a/third_party/dependency_analyzer/src/test/io/bazel/rulesscala/dependencyanalyzer3/CompileTest.scala b/third_party/dependency_analyzer/src/test/io/bazel/rulesscala/dependencyanalyzer3/CompileTest.scala index 0e941b751..157ea1437 100644 --- a/third_party/dependency_analyzer/src/test/io/bazel/rulesscala/dependencyanalyzer3/CompileTest.scala +++ b/third_party/dependency_analyzer/src/test/io/bazel/rulesscala/dependencyanalyzer3/CompileTest.scala @@ -1,20 +1,20 @@ package io.bazel.rulesscala.dependencyanalyzer import org.scalatest.funsuite.AnyFunSuite -import io.bazel.rulesscala.utils.TestUtil3 +import io.bazel.rulesscala.utils.Scala3CompilerUtils class CompileTest extends AnyFunSuite { test("Util compiles valid code") { val scalaCode = "class Foo { }" - val messages = TestUtil3.runCompiler(scalaCode) + val messages = Scala3CompilerUtils.runCompiler(scalaCode) assert(messages.isEmpty, "No messages must be reported when valid code is compiled") } test("Util returns errors on invalid code") { val scalaCode = "!@#" - val messages = TestUtil3.runCompiler(scalaCode) + val messages = Scala3CompilerUtils.runCompiler(scalaCode) assert( messages.exists(_.message.contains("Illegal start of toplevel definition")), diff --git a/third_party/utils/src/test/BUILD b/third_party/utils/src/test/BUILD index f9edfb4b4..278dd6967 100644 --- a/third_party/utils/src/test/BUILD +++ b/third_party/utils/src/test/BUILD @@ -1,11 +1,23 @@ load("//scala:scala.bzl", "scala_library") +load("@io_bazel_rules_scala_config//:config.bzl", "SCALA_MAJOR_VERSION") licenses(["notice"]) # 3-clause BSD scala_library( name = "test_util", srcs = [ - "io/bazel/rulesscala/utils/TestUtil3.scala", + "io/bazel/rulesscala/utils/JavaCompileUtil.scala", + "io/bazel/rulesscala/utils/TestUtil.scala", + ], + visibility = ["//visibility:public"], + deps = [ + "//scala/private/toolchain_deps:scala_compile_classpath", + "//third_party/dependency_analyzer/src/main:dependency_analyzer", + ], +) if SCALA_MAJOR_VERSION.startswith("2") else scala_library( + name = "test_util", + srcs = [ + "io/bazel/rulesscala/utils/Scala3CompilerUtils.scala", ], visibility = ["//visibility:public"], deps = [ diff --git a/third_party/utils/src/test/io/bazel/rulesscala/utils/Scala3CompilerUtils.scala b/third_party/utils/src/test/io/bazel/rulesscala/utils/Scala3CompilerUtils.scala new file mode 100644 index 000000000..68973239d --- /dev/null +++ b/third_party/utils/src/test/io/bazel/rulesscala/utils/Scala3CompilerUtils.scala @@ -0,0 +1,52 @@ +package io.bazel.rulesscala.utils + +import dotty.tools.dotc.Compiler +import dotty.tools.dotc.core.Contexts._ +import dotty.tools.dotc.reporting.Diagnostic +import dotty.tools.dotc.util.SourceFile + +import java.nio.file.Paths + +object Scala3CompilerUtils { + def runCompiler( + code: String, + extraClasspath: List[String] = List.empty, + ): List[Diagnostic] = { + val reporter = new TestReporter() + + implicit val context: FreshContext = (new ContextBase).initialCtx.fresh.setReporter(reporter) + + val fullClassPath = + builtinClasspaths.filterNot(_.isEmpty) ++ + extraClasspath :+ + context.settings.classpath.value + + context.setSetting(context.settings.classpath, fullClassPath.mkString(":")) + + val compiler = new Compiler() + val run = compiler.newRun + run.compileSources(List(SourceFile.virtual("code.scala", code, maybeIncomplete = false))) + + reporter.storedInfos + } + + private lazy val builtinClasspaths: Vector[String] = + Vector( + pathOf("scala.library.location"), + pathOf("scala.library2.location") + ) + + private def pathOf(jvmFlag: String) = { + val jar = System.getProperty(jvmFlag) + val libPath = Paths.get(baseDir, jar).toAbsolutePath + libPath.toString + } + + private lazy val baseDir = System.getProperty("user.dir") +} + +import dotty.tools.dotc.reporting.StoreReporter + +class TestReporter extends StoreReporter(null) { + def storedInfos: List[Diagnostic] = if (infos != null) infos.toList else List() +} diff --git a/third_party/utils/src/test/io/bazel/rulesscala/utils/TestUtil3.scala b/third_party/utils/src/test/io/bazel/rulesscala/utils/TestUtil3.scala deleted file mode 100644 index dd8fbc5ec..000000000 --- a/third_party/utils/src/test/io/bazel/rulesscala/utils/TestUtil3.scala +++ /dev/null @@ -1,92 +0,0 @@ -package io.bazel.rulesscala.utils - -import dotty.tools.dotc.Compiler -import dotty.tools.dotc.core.Contexts._ -import dotty.tools.dotc.reporting.Diagnostic -import dotty.tools.dotc.util.SourceFile - -import java.nio.file.{Path, Paths} - -object TestUtil3 { - final val defaultTarget = "//..." - - case class DependencyAnalyzerTestParams( - //dependencyTrackingMethod: DependencyTrackingMethod, - strictDeps: Boolean = false, - unusedDeps: Boolean = false, - directJars: List[String] = List.empty, - directTargets: List[String] = List.empty, - indirectJars: List[String] = List.empty, - indirectTargets: List[String] = List.empty - ) - - /** - * Runs the compiler on a piece of code. - * - * @param dependencyAnalyzerParamsOpt If set, includes the dependency analyzer - * plugin with the provided parameters - * @param outputPathOpt If non-None, a directory to output the files in - * @return list of errors returned by the compiler - */ - def runCompiler( - code: String, - extraClasspath: List[String] = List.empty, - dependencyAnalyzerParamsOpt: Option[DependencyAnalyzerTestParams] = None, - outputPathOpt: Option[Path] = None - ): List[Diagnostic] = { - val reporter = new TestReporter() - implicit val ctx = (new ContextBase).initialCtx.fresh - .setReporter(reporter) - .setDebug - val fullClassPath = - (List(getClasspathArguments(extraClasspath)) :+ ctx.settings.classpath.value).mkString(":") - ctx.setSetting(ctx.settings.classpath, fullClassPath) - - val compiler = new Compiler() - val run = compiler.newRun - run.compileSources(List(SourceFile.virtual("some.scala", code, false))) - run.printSummary() - - reporter.storedInfos - } - - private def getClasspathArguments(extraClasspath: List[String]): String = { - val classpathEntries = { - val builtinClassPaths = builtinClasspaths.filterNot(_.isEmpty) - extraClasspath ++ builtinClassPaths - } - if (classpathEntries.isEmpty) { - "" - } else { - s"${classpathEntries.mkString(":")}" - } - } - - private lazy val builtinClasspaths: Vector[String] = - Vector( - pathOf("scala.library.location"), - pathOf("scala.library2.location") - ) - - lazy val guavaClasspath: String = - pathOf("guava.jar.location") - - lazy val apacheCommonsClasspath: String = - pathOf("apache.commons.jar.location") - - private def pathOf(jvmFlag: String) = { - val jar = System.getProperty(jvmFlag) - val libPath = Paths.get(baseDir, jar).toAbsolutePath - libPath.toString - } - - private lazy val baseDir = System.getProperty("user.dir") - - -} - -import dotty.tools.dotc.reporting.StoreReporter - -class TestReporter extends StoreReporter(null) { - def storedInfos = if(infos != null) infos.toList else List() -} \ No newline at end of file From aa54377913ebdf754749ac352e08b0ebfe689bd7 Mon Sep 17 00:00:00 2001 From: Justinas Simanavicius Date: Fri, 18 Mar 2022 17:55:57 +0200 Subject: [PATCH 04/10] dep analyzer 3 --- src/java/io/bazel/rulesscala/scalac/ScalacWorker3.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/java/io/bazel/rulesscala/scalac/ScalacWorker3.java b/src/java/io/bazel/rulesscala/scalac/ScalacWorker3.java index 46d0fcfd5..370be2904 100644 --- a/src/java/io/bazel/rulesscala/scalac/ScalacWorker3.java +++ b/src/java/io/bazel/rulesscala/scalac/ScalacWorker3.java @@ -268,7 +268,6 @@ private static void compileScalaSources(CompileOptions ops, String[] scalaSource Reporter reporter = driver.doCompile(compiler, r._1, r._2); - long stop = System.currentTimeMillis(); if (ops.printCompileTime) { System.err.println("Compiler runtime: " + (stop - start) + "ms."); From 848cbee4efea1e96494a16d1c42759cabf94070d Mon Sep 17 00:00:00 2001 From: Justinas Simanavicius Date: Fri, 18 Mar 2022 18:03:03 +0200 Subject: [PATCH 05/10] dep analyzer 3 --- .../DependencyAnalyzer.scala | 25 ++++++++----------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/third_party/dependency_analyzer/src/main/io/bazel/rulesscala/dependencyanalyzer3/DependencyAnalyzer.scala b/third_party/dependency_analyzer/src/main/io/bazel/rulesscala/dependencyanalyzer3/DependencyAnalyzer.scala index d2034003f..d1050a78e 100644 --- a/third_party/dependency_analyzer/src/main/io/bazel/rulesscala/dependencyanalyzer3/DependencyAnalyzer.scala +++ b/third_party/dependency_analyzer/src/main/io/bazel/rulesscala/dependencyanalyzer3/DependencyAnalyzer.scala @@ -1,30 +1,28 @@ package io.bazel.rulesscala.dependencyanalyzer -import dotty.tools.dotc.ast.Trees._ +import dotty.tools.dotc.ast.Trees.* import dotty.tools.dotc.ast.tpd import dotty.tools.dotc.core.Constants.Constant import dotty.tools.dotc.core.Contexts.Context -import dotty.tools.dotc.core.Decorators._ -import dotty.tools.dotc.core.StdNames._ -import dotty.tools.dotc.core.Symbols._ +import dotty.tools.dotc.core.Decorators.* +import dotty.tools.dotc.core.StdNames.* +import dotty.tools.dotc.core.Symbols.* import dotty.tools.dotc.plugins.{PluginPhase, StandardPlugin} import dotty.tools.dotc.transform.{Pickler, Staging} -class DependencyAnalyzer extends StandardPlugin { +class DependencyAnalyzer extends StandardPlugin: override val name: String = "dependency-analyzer" override val description: String = "Analyzes the used dependencies. Can check and warn or fail the " + - "compilation for issues including not directly including " + - "dependencies which are directly included in the code, or " + - "including unused dependencies." + "compilation for issues including not directly including " + + "dependencies which are directly included in the code, or " + + "including unused dependencies." def init(options: List[String]): List[PluginPhase] = (new DependencyAnalyzerPhase) :: Nil -} -class DependencyAnalyzerPhase extends PluginPhase { - - import tpd._ +class DependencyAnalyzerPhase extends PluginPhase: + import tpd.* val phaseName = "dependecy-analyzer-phase" @@ -32,5 +30,4 @@ class DependencyAnalyzerPhase extends PluginPhase { override val runsBefore = Set(Staging.name) override def transformApply(tree: Apply)(implicit ctx: Context): Tree = - tree -} \ No newline at end of file + tree \ No newline at end of file From 0a0caec4d51def61696d3197ade91ba896b795b4 Mon Sep 17 00:00:00 2001 From: Justinas Simanavicius Date: Fri, 18 Mar 2022 18:12:42 +0200 Subject: [PATCH 06/10] dep analyzer 3 --- third_party/utils/src/test/BUILD | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/third_party/utils/src/test/BUILD b/third_party/utils/src/test/BUILD index 278dd6967..39f558e99 100644 --- a/third_party/utils/src/test/BUILD +++ b/third_party/utils/src/test/BUILD @@ -5,20 +5,12 @@ licenses(["notice"]) # 3-clause BSD scala_library( name = "test_util", - srcs = [ + srcs = ([ "io/bazel/rulesscala/utils/JavaCompileUtil.scala", "io/bazel/rulesscala/utils/TestUtil.scala", - ], - visibility = ["//visibility:public"], - deps = [ - "//scala/private/toolchain_deps:scala_compile_classpath", - "//third_party/dependency_analyzer/src/main:dependency_analyzer", - ], -) if SCALA_MAJOR_VERSION.startswith("2") else scala_library( - name = "test_util", - srcs = [ + ] if SCALA_MAJOR_VERSION.startswith("2") else [ "io/bazel/rulesscala/utils/Scala3CompilerUtils.scala", - ], + ]), visibility = ["//visibility:public"], deps = [ "//scala/private/toolchain_deps:scala_compile_classpath", From 600147016413f19b5a6923f59e18bab6bd2caa56 Mon Sep 17 00:00:00 2001 From: Justinas Simanavicius Date: Mon, 21 Mar 2022 09:55:37 +0200 Subject: [PATCH 07/10] Cleanup --- .../rulesscala/utils/Scala3CompilerUtils.scala | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/third_party/utils/src/test/io/bazel/rulesscala/utils/Scala3CompilerUtils.scala b/third_party/utils/src/test/io/bazel/rulesscala/utils/Scala3CompilerUtils.scala index 68973239d..953e45872 100644 --- a/third_party/utils/src/test/io/bazel/rulesscala/utils/Scala3CompilerUtils.scala +++ b/third_party/utils/src/test/io/bazel/rulesscala/utils/Scala3CompilerUtils.scala @@ -2,7 +2,7 @@ package io.bazel.rulesscala.utils import dotty.tools.dotc.Compiler import dotty.tools.dotc.core.Contexts._ -import dotty.tools.dotc.reporting.Diagnostic +import dotty.tools.dotc.reporting.{Diagnostic, StoreReporter} import dotty.tools.dotc.util.SourceFile import java.nio.file.Paths @@ -16,25 +16,19 @@ object Scala3CompilerUtils { implicit val context: FreshContext = (new ContextBase).initialCtx.fresh.setReporter(reporter) - val fullClassPath = - builtinClasspaths.filterNot(_.isEmpty) ++ - extraClasspath :+ - context.settings.classpath.value + val fullClassPath = context.settings.classpath.value :: extraClasspath ::: builtinClasspaths.filterNot(_.isEmpty) context.setSetting(context.settings.classpath, fullClassPath.mkString(":")) val compiler = new Compiler() val run = compiler.newRun - run.compileSources(List(SourceFile.virtual("code.scala", code, maybeIncomplete = false))) + run.compileSources(SourceFile.virtual("scala_compiler_util_run_code.scala", code, maybeIncomplete = false) :: Nil) reporter.storedInfos } - private lazy val builtinClasspaths: Vector[String] = - Vector( - pathOf("scala.library.location"), - pathOf("scala.library2.location") - ) + private lazy val builtinClasspaths: List[String] = + pathOf("scala.library.location") :: pathOf("scala.library2.location") :: Nil private def pathOf(jvmFlag: String) = { val jar = System.getProperty(jvmFlag) @@ -45,8 +39,6 @@ object Scala3CompilerUtils { private lazy val baseDir = System.getProperty("user.dir") } -import dotty.tools.dotc.reporting.StoreReporter - class TestReporter extends StoreReporter(null) { def storedInfos: List[Diagnostic] = if (infos != null) infos.toList else List() } From d705119089c8e9951d649356086583162be82b6d Mon Sep 17 00:00:00 2001 From: Justinas Simanavicius Date: Mon, 21 Mar 2022 10:08:32 +0200 Subject: [PATCH 08/10] Commend about including Scala 2 standard library --- .../dependency_analyzer/src/test/analyzer_test_scala_3.bzl | 3 +++ 1 file changed, 3 insertions(+) diff --git a/third_party/dependency_analyzer/src/test/analyzer_test_scala_3.bzl b/third_party/dependency_analyzer/src/test/analyzer_test_scala_3.bzl index 2fe5234d9..d25938271 100644 --- a/third_party/dependency_analyzer/src/test/analyzer_test_scala_3.bzl +++ b/third_party/dependency_analyzer/src/test/analyzer_test_scala_3.bzl @@ -4,6 +4,9 @@ def analyzer_tests_scala_3(): common_jvm_flags = [ "-Dplugin.jar.location=$(execpath //third_party/dependency_analyzer/src/main:dependency_analyzer)", "-Dscala.library.location=$(rootpath @io_bazel_rules_scala_scala_library)", + # Scala 2 standard library is required for compilation. + # Without it compilation fails with error: + # class dotty.tools.dotc.core.Symbols$NoSymbol$ cannot be cast to class dotty.tools.dotc.core.Symbols$ClassSymbol "-Dscala.library2.location=$(rootpath @io_bazel_rules_scala_scala_library_2)", ] From a82ac9459cb06b56072abfad2e0ce60e55ff3eed Mon Sep 17 00:00:00 2001 From: Justinas Simanavicius Date: Tue, 22 Mar 2022 10:54:04 +0200 Subject: [PATCH 09/10] Trigger rebuild --- third_party/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/third_party/README.md b/third_party/README.md index 54ee73139..75b06d06b 100644 --- a/third_party/README.md +++ b/third_party/README.md @@ -2,4 +2,4 @@ This file lists license and version information of all code we did not author # dependency_analyzer dependency_analyzer scala compiler plugin is based on [classpath-shrinker](https://github.com/scalacenter/classpath-shrinker) plugin. -License: 3-clause revised BSD \ No newline at end of file +License: 3-clause revised BSD \ No newline at end of file From 3a16b447bd428987c645b8902589728c49b5b340 Mon Sep 17 00:00:00 2001 From: Justinas Simanavicius Date: Tue, 22 Mar 2022 10:54:16 +0200 Subject: [PATCH 10/10] Trigger rebuild --- third_party/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/third_party/README.md b/third_party/README.md index 75b06d06b..54ee73139 100644 --- a/third_party/README.md +++ b/third_party/README.md @@ -2,4 +2,4 @@ This file lists license and version information of all code we did not author # dependency_analyzer dependency_analyzer scala compiler plugin is based on [classpath-shrinker](https://github.com/scalacenter/classpath-shrinker) plugin. -License: 3-clause revised BSD \ No newline at end of file +License: 3-clause revised BSD \ No newline at end of file