Skip to content

Commit

Permalink
Minimal implementation of compiler utils for Scala 3 Dependency Analy…
Browse files Browse the repository at this point in the history
…zer tests.

Dependency Analyzer uses TestUtil to run compiler. For Scala 3 these utils have to be rewritten to work with new compiler.
  • Loading branch information
justinass-wix authored Mar 22, 2022
1 parent 75701d0 commit a2b971d
Show file tree
Hide file tree
Showing 7 changed files with 207 additions and 102 deletions.
4 changes: 2 additions & 2 deletions third_party/dependency_analyzer/src/test/BUILD
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
load(":analyzer_test.bzl", "analyzer_tests")
load(":analyzer_test.bzl", "tests")

analyzer_tests()
tests()
104 changes: 6 additions & 98 deletions third_party/dependency_analyzer/src/test/analyzer_test.bzl
Original file line number Diff line number Diff line change
@@ -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()
99 changes: 99 additions & 0 deletions third_party/dependency_analyzer/src/test/analyzer_test_scala_2.bzl
Original file line number Diff line number Diff line change
@@ -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",
],
)
27 changes: 27 additions & 0 deletions third_party/dependency_analyzer/src/test/analyzer_test_scala_3.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
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)",
# 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)",
]

scala_test(
name = "test_that_tests_run",
size = "small",
jvm_flags = common_jvm_flags,
srcs = [
"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",
],
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package io.bazel.rulesscala.dependencyanalyzer

import org.scalatest.funsuite.AnyFunSuite
import io.bazel.rulesscala.utils.Scala3CompilerUtils

class CompileTest extends AnyFunSuite {

test("Util compiles valid code") {
val scalaCode = "class Foo { }"
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 = Scala3CompilerUtils.runCompiler(scalaCode)

assert(
messages.exists(_.message.contains("Illegal start of toplevel definition")),
"Error must be reported when valid code is compiled"
)
}
}
7 changes: 5 additions & 2 deletions third_party/utils/src/test/BUILD
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
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 = [
srcs = ([
"io/bazel/rulesscala/utils/JavaCompileUtil.scala",
"io/bazel/rulesscala/utils/TestUtil.scala",
],
] if SCALA_MAJOR_VERSION.startswith("2") else [
"io/bazel/rulesscala/utils/Scala3CompilerUtils.scala",
]),
visibility = ["//visibility:public"],
deps = [
"//scala/private/toolchain_deps:scala_compile_classpath",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package io.bazel.rulesscala.utils

import dotty.tools.dotc.Compiler
import dotty.tools.dotc.core.Contexts._
import dotty.tools.dotc.reporting.{Diagnostic, StoreReporter}
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 = 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(SourceFile.virtual("scala_compiler_util_run_code.scala", code, maybeIncomplete = false) :: Nil)

reporter.storedInfos
}

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)
val libPath = Paths.get(baseDir, jar).toAbsolutePath
libPath.toString
}

private lazy val baseDir = System.getProperty("user.dir")
}

class TestReporter extends StoreReporter(null) {
def storedInfos: List[Diagnostic] = if (infos != null) infos.toList else List()
}

0 comments on commit a2b971d

Please sign in to comment.