Pass reporter to PsiSourceParser and related methods
Removes a dependency onto the global `reporter` variable which would
prevent this being moved into a separate library.
Adds a simple `BasicReporter` that can be used for tests that need to
be run separately from the main commands.
Bug: 294725097
Test: ./gradlew
Change-Id: I82df1103e927686ab8206048d9102ac0c3434226
diff --git a/metalava-reporter/src/main/java/com/android/tools/metalava/reporter/Reporter.kt b/metalava-reporter/src/main/java/com/android/tools/metalava/reporter/Reporter.kt
index 3ab4a19..6472299 100644
--- a/metalava-reporter/src/main/java/com/android/tools/metalava/reporter/Reporter.kt
+++ b/metalava-reporter/src/main/java/com/android/tools/metalava/reporter/Reporter.kt
@@ -19,6 +19,7 @@
import com.android.tools.metalava.model.Item
import com.android.tools.metalava.model.Location
import java.io.File
+import java.io.PrintWriter
interface Reporter {
@@ -93,3 +94,34 @@
*/
fun showProgressTick()
}
+
+/**
+ * Basic implementation of a [Reporter] that performs no filtering and simply outputs the message to
+ * the supplied [PrintWriter].
+ */
+class BasicReporter(private val stderr: PrintWriter) : Reporter {
+ override fun report(
+ id: Issues.Issue,
+ item: Item?,
+ message: String,
+ location: Location
+ ): Boolean {
+ stderr.println(
+ buildString {
+ append(item?.location() ?: location)
+ append(": ")
+ append(id.defaultLevel.name.lowercase())
+ append(": ")
+ append(message)
+ append(" [")
+ append(id.name)
+ append("]")
+ }
+ )
+ return true
+ }
+
+ override fun isSuppressed(id: Issues.Issue, item: Item?, message: String?): Boolean = false
+
+ override fun showProgressTick() {}
+}
diff --git a/src/main/java/com/android/tools/metalava/AnnotationsMerger.kt b/src/main/java/com/android/tools/metalava/AnnotationsMerger.kt
index 449d118..d402b7e 100644
--- a/src/main/java/com/android/tools/metalava/AnnotationsMerger.kt
+++ b/src/main/java/com/android/tools/metalava/AnnotationsMerger.kt
@@ -117,7 +117,7 @@
// Set up class path to contain our main sources such that we can
// resolve types in the stubs
val roots = mutableListOf<File>()
- extractRoots(options.sources, roots)
+ extractRoots(reporter, options.sources, roots)
roots.addAll(options.sourcePath)
val javaStubsCodebase =
psiSourceParser.parseSources(
diff --git a/src/main/java/com/android/tools/metalava/ConvertJarsToSignatureFiles.kt b/src/main/java/com/android/tools/metalava/ConvertJarsToSignatureFiles.kt
index 5925b17..d3d89a9 100644
--- a/src/main/java/com/android/tools/metalava/ConvertJarsToSignatureFiles.kt
+++ b/src/main/java/com/android/tools/metalava/ConvertJarsToSignatureFiles.kt
@@ -72,7 +72,7 @@
// there: package private super classes etc.
val jarCodebase =
loadFromJarFile(
- PsiSourceParser(psiEnvironmentManager),
+ PsiSourceParser(psiEnvironmentManager, reporter),
apiJar,
preFiltered = false,
DefaultAnnotationManager()
diff --git a/src/main/java/com/android/tools/metalava/Driver.kt b/src/main/java/com/android/tools/metalava/Driver.kt
index 89a4297..3d642ae 100644
--- a/src/main/java/com/android/tools/metalava/Driver.kt
+++ b/src/main/java/com/android/tools/metalava/Driver.kt
@@ -219,6 +219,7 @@
val psiSourceParser =
PsiSourceParser(
psiEnvironmentManager,
+ reporter = reporter,
javaLanguageLevel = options.javaLanguageLevel,
kotlinLanguageLevel = options.kotlinLanguageLevel,
allowImplicitRoot = options.allowImplicitRoot,
@@ -707,7 +708,7 @@
"No source files specified: recursively including all sources found in the source path (${options.sourcePath.joinToString()}})"
)
}
- gatherSources(options.sourcePath)
+ gatherSources(reporter, options.sourcePath)
}
progress("Reading Codebase: ")
diff --git a/src/main/java/com/android/tools/metalava/PsiSourceParser.kt b/src/main/java/com/android/tools/metalava/PsiSourceParser.kt
index 7f1f715..3f60fd6 100644
--- a/src/main/java/com/android/tools/metalava/PsiSourceParser.kt
+++ b/src/main/java/com/android/tools/metalava/PsiSourceParser.kt
@@ -26,6 +26,7 @@
import com.android.tools.metalava.model.psi.PsiEnvironmentManager
import com.android.tools.metalava.model.psi.packageHtmlToJavadoc
import com.android.tools.metalava.reporter.Issues
+import com.android.tools.metalava.reporter.Reporter
import com.google.common.collect.Lists
import com.google.common.io.Files
import com.intellij.pom.java.LanguageLevel
@@ -60,6 +61,7 @@
*/
class PsiSourceParser(
private val psiEnvironmentManager: PsiEnvironmentManager,
+ private val reporter: Reporter,
private val javaLanguageLevel: LanguageLevel = defaultJavaLanguageLevel,
private val kotlinLanguageLevel: LanguageVersionSettings = defaultKotlinLanguageLevel,
private val allowImplicitRoot: Boolean = true,
@@ -84,7 +86,7 @@
sourcePath.filter { it.path.isNotBlank() }.map { it.absoluteFile }.toMutableList()
// Add in source roots implied by the source files
if (allowImplicitRoot) {
- extractRoots(absoluteSources, absoluteSourceRoots)
+ extractRoots(reporter, absoluteSources, absoluteSourceRoots)
}
val absoluteClasspath = classpath.map { it.absoluteFile }
@@ -220,7 +222,7 @@
private fun skippableDirectory(file: File): Boolean =
file.path.endsWith(".git") && file.name == ".git"
-private fun addSourceFiles(list: MutableList<File>, file: File) {
+private fun addSourceFiles(reporter: Reporter, list: MutableList<File>, file: File) {
if (file.isDirectory) {
if (skippableDirectory(file)) {
return
@@ -236,7 +238,7 @@
val files = file.listFiles()
if (files != null) {
for (child in files) {
- addSourceFiles(list, child)
+ addSourceFiles(reporter, list, child)
}
}
} else if (file.isFile) {
@@ -249,19 +251,20 @@
}
}
-fun gatherSources(sourcePath: List<File>): List<File> {
+fun gatherSources(reporter: Reporter, sourcePath: List<File>): List<File> {
val sources = Lists.newArrayList<File>()
for (file in sourcePath) {
if (file.path.isBlank()) {
// --source-path "" means don't search source path; use "." for pwd
continue
}
- addSourceFiles(sources, file.absoluteFile)
+ addSourceFiles(reporter, sources, file.absoluteFile)
}
return sources.sortedWith(compareBy { it.name })
}
fun extractRoots(
+ reporter: Reporter,
sources: List<File>,
sourceRoots: MutableList<File> = mutableListOf()
): List<File> {
@@ -275,7 +278,7 @@
continue
}
- val root = findRoot(file) ?: continue
+ val root = findRoot(reporter, file) ?: continue
dirToRootCache[parent.path] = root
if (!sourceRoots.contains(root)) {
@@ -290,7 +293,7 @@
* If given a full path to a Java or Kotlin source file, produces the path to the source root if
* possible.
*/
-private fun findRoot(file: File): File? {
+private fun findRoot(reporter: Reporter, file: File): File? {
val path = file.path
if (path.endsWith(SdkConstants.DOT_JAVA) || path.endsWith(SdkConstants.DOT_KT)) {
val pkg = findPackage(file) ?: return null
@@ -303,7 +306,7 @@
reporter.report(
Issues.IO_ERROR,
file,
- "$PROGRAM_NAME was unable to determine the package name. " +
+ "Unable to determine the package name. " +
"This usually means that a source file was where the directory does not seem to match the package " +
"declaration; we expected the path $path to end with /${pkg.replace('.', '/') + '/' + file.name}"
)
diff --git a/src/test/java/com/android/tools/metalava/DriverTest.kt b/src/test/java/com/android/tools/metalava/DriverTest.kt
index 487b90a..45fd112 100644
--- a/src/test/java/com/android/tools/metalava/DriverTest.kt
+++ b/src/test/java/com/android/tools/metalava/DriverTest.kt
@@ -1355,7 +1355,11 @@
if (checkCompilation && stubsDir != null) {
val generated =
- gatherSources(listOf(stubsDir)).asSequence().map { it.path }.toList().toTypedArray()
+ gatherSources(reporter, listOf(stubsDir))
+ .asSequence()
+ .map { it.path }
+ .toList()
+ .toTypedArray()
// Also need to include on the compile path annotation classes referenced in the stubs
val extraAnnotationsDir = File("stub-annotations/src/main/java")
@@ -1368,7 +1372,7 @@
)
}
val extraAnnotations =
- gatherSources(listOf(extraAnnotationsDir))
+ gatherSources(reporter, listOf(extraAnnotationsDir))
.asSequence()
.map { it.path }
.toList()
diff --git a/src/test/java/com/android/tools/metalava/model/psi/PsiTestUtils.kt b/src/test/java/com/android/tools/metalava/model/psi/PsiTestUtils.kt
index bb6bd31..61f2619 100644
--- a/src/test/java/com/android/tools/metalava/model/psi/PsiTestUtils.kt
+++ b/src/test/java/com/android/tools/metalava/model/psi/PsiTestUtils.kt
@@ -21,12 +21,14 @@
import com.android.tools.lint.checks.infrastructure.TestFile
import com.android.tools.metalava.ENV_VAR_METALAVA_TESTS_RUNNING
import com.android.tools.metalava.PsiSourceParser
+import com.android.tools.metalava.reporter.BasicReporter
import com.android.tools.metalava.testing.findKotlinStdlibPaths
import com.android.tools.metalava.testing.getAndroidJar
import com.android.tools.metalava.testing.tempDirectory
import com.android.tools.metalava.updateGlobalOptionsForTest
import com.intellij.openapi.util.Disposer
import java.io.File
+import java.io.PrintWriter
import kotlin.test.assertNotNull
inline fun testCodebase(vararg sources: TestFile, action: (PsiBasedCodebase) -> Unit) {
@@ -54,7 +56,8 @@
val kotlinStdlibPaths = findKotlinStdlibPaths(sourcePaths)
updateGlobalOptionsForTest(emptyArray())
- return PsiSourceParser(psiEnvironmentManager)
+ val reporter = BasicReporter(PrintWriter(System.err))
+ return PsiSourceParser(psiEnvironmentManager, reporter)
.parseSources(
sources = sources.map { it.createFile(directory) },
description = "Test Codebase",
diff --git a/src/test/java/com/android/tools/metalava/model/psi/PsiTypePrinterTest.kt b/src/test/java/com/android/tools/metalava/model/psi/PsiTypePrinterTest.kt
index 6255bb9..3c6c4c0 100644
--- a/src/test/java/com/android/tools/metalava/model/psi/PsiTypePrinterTest.kt
+++ b/src/test/java/com/android/tools/metalava/model/psi/PsiTypePrinterTest.kt
@@ -24,6 +24,7 @@
import com.android.tools.metalava.model.Item
import com.android.tools.metalava.nonNullSource
import com.android.tools.metalava.nullableSource
+import com.android.tools.metalava.reporter.BasicReporter
import com.android.tools.metalava.testing.TemporaryFolderOwner
import com.android.tools.metalava.testing.getAndroidJar
import com.android.tools.metalava.testing.java
@@ -878,9 +879,10 @@
classPath.add(getAndroidJar())
updateGlobalOptionsForTest(emptyArray())
+ val reporter = BasicReporter(PrintWriter(System.err))
// TestDriver#check normally sets this for all the other tests
val codebase =
- PsiSourceParser(psiEnvironmentManagerRule.manager)
+ PsiSourceParser(psiEnvironmentManagerRule.manager, reporter)
.parseSources(
sourceFiles,
"test project",
diff --git a/src/test/java/com/android/tools/metalava/stub/StubsTest.kt b/src/test/java/com/android/tools/metalava/stub/StubsTest.kt
index 0bcbf19..490b102 100644
--- a/src/test/java/com/android/tools/metalava/stub/StubsTest.kt
+++ b/src/test/java/com/android/tools/metalava/stub/StubsTest.kt
@@ -22,6 +22,7 @@
import com.android.tools.metalava.extractRoots
import com.android.tools.metalava.gatherSources
import com.android.tools.metalava.model.FileFormat
+import com.android.tools.metalava.reporter
import com.android.tools.metalava.supportParameterName
import com.android.tools.metalava.systemApiSource
import com.android.tools.metalava.testApiSource
@@ -1183,8 +1184,8 @@
check(
expectedIssues =
"""
- src/test/Something2.java: error: metalava was unable to determine the package name. This usually means that a source file was where the directory does not seem to match the package declaration; we expected the path TESTROOT/src/test/Something2.java to end with /test/wrong/Something2.java [IoError]
- src/test/Something2.java: error: metalava was unable to determine the package name. This usually means that a source file was where the directory does not seem to match the package declaration; we expected the path TESTROOT/src/test/Something2.java to end with /test/wrong/Something2.java [IoError]
+ src/test/Something2.java: error: Unable to determine the package name. This usually means that a source file was where the directory does not seem to match the package declaration; we expected the path TESTROOT/src/test/Something2.java to end with /test/wrong/Something2.java [IoError]
+ src/test/Something2.java: error: Unable to determine the package name. This usually means that a source file was where the directory does not seem to match the package declaration; we expected the path TESTROOT/src/test/Something2.java to end with /test/wrong/Something2.java [IoError]
""",
sourceFiles =
arrayOf(
@@ -1227,8 +1228,8 @@
projectSetup = { dir ->
// Make sure we handle blank/doc-only java doc files in root extraction
val src = listOf(File(dir, "src"))
- val files = gatherSources(src)
- val roots = extractRoots(files)
+ val files = gatherSources(reporter, src)
+ val roots = extractRoots(reporter, files)
assertEquals(1, roots.size)
assertEquals(src[0].path, roots[0].path)
}