KT-33617: Handle non-hierarchical URIs for incremental annotation processing
JDK9 may decide to load .java files from jar when resolving a type, even when .class file exists in the same jar. Further on, these files will be parsed and analyzed, which triggers the listener used by incremental annotation processing. This commit avoids analyzing those files, and makes sure URI passed from the compiler are such that a File instance can be created. Test: KaptIncrementalWithIsolatingApt.testSourcesInCompileClasspathJars
This commit is contained in:
committed by
Yan Zhulanow
parent
941980c154
commit
8f94a71de7
+9
@@ -0,0 +1,9 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package test.kt33617;
|
||||
|
||||
public class MyClass {
|
||||
}
|
||||
+42
@@ -8,7 +8,9 @@ package org.jetbrains.kotlin.gradle
|
||||
import org.jetbrains.kotlin.gradle.incapt.IncrementalProcessor
|
||||
import org.jetbrains.kotlin.gradle.util.modify
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Assume
|
||||
import org.junit.Test
|
||||
import test.kt33617.MyClass
|
||||
import java.io.File
|
||||
import java.util.zip.ZipEntry
|
||||
import java.util.zip.ZipOutputStream
|
||||
@@ -113,6 +115,46 @@ class KaptIncrementalWithIsolatingApt : KaptIncrementalIT() {
|
||||
assertContains("Incremental annotation processing (apt mode): false")
|
||||
}
|
||||
}
|
||||
|
||||
/** Regression test for https://youtrack.jetbrains.com/issue/KT-33617. */
|
||||
@Test
|
||||
fun testSourcesInCompileClasspathJars() {
|
||||
val javaHome = File(System.getProperty("jdk9Home")!!)
|
||||
Assume.assumeTrue("JDK 9 isn't available", javaHome.isDirectory)
|
||||
val options = defaultBuildOptions().copy(javaHome = javaHome)
|
||||
|
||||
val project = getProject()
|
||||
// create jar with .class and .java file for the same type
|
||||
ZipOutputStream(project.projectDir.resolve("lib-with-sources.jar").outputStream()).use {
|
||||
it.putNextEntry(ZipEntry("test/kt33617/MyClass.class"))
|
||||
MyClass::class.java.classLoader.getResourceAsStream("test/kt33617/MyClass.class").use { input ->
|
||||
it.write(input!!.readBytes())
|
||||
}
|
||||
it.closeEntry()
|
||||
|
||||
it.putNextEntry(ZipEntry("test/kt33617/MyClass.java"))
|
||||
it.write(
|
||||
"""
|
||||
package test.kt33617;
|
||||
public class MyClass {}
|
||||
""".trimIndent().toByteArray(Charsets.UTF_8)
|
||||
)
|
||||
it.closeEntry()
|
||||
}
|
||||
project.gradleBuildScript().appendText(
|
||||
"""
|
||||
|
||||
dependencies {
|
||||
implementation files('lib-with-sources.jar')
|
||||
}
|
||||
""".trimIndent()
|
||||
)
|
||||
project.projectFile("useB.kt").modify { current -> "$current\nfun otherFunction(param: test.kt33617.MyClass) {}" }
|
||||
|
||||
project.build("clean", "kaptKotlin", options = options) {
|
||||
assertSuccessful()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private const val patternApt = "Processing java sources with annotation processors:"
|
||||
|
||||
+18
-1
@@ -9,6 +9,7 @@ import java.io.File
|
||||
import java.io.ObjectInputStream
|
||||
import java.io.ObjectOutputStream
|
||||
import java.io.Serializable
|
||||
import java.lang.IllegalArgumentException
|
||||
import java.net.URI
|
||||
import java.util.regex.Pattern
|
||||
|
||||
@@ -73,7 +74,23 @@ class JavaClassCache() : Serializable {
|
||||
output.writeObject(generatedTypes)
|
||||
}
|
||||
|
||||
fun isAlreadyProcessed(sourceFile: URI) = sourceCache.containsKey(sourceFile) || generatedTypes.containsKey(File(sourceFile))
|
||||
fun isAlreadyProcessed(sourceFile: URI): Boolean {
|
||||
if (!sourceFile.isAbsolute) {
|
||||
// we never want to process non-absolute URIs, see https://youtrack.jetbrains.com/issue/KT-33617
|
||||
return true
|
||||
}
|
||||
if (sourceFile.isOpaque) {
|
||||
// we never want to process non-hierarchical URIs, https://youtrack.jetbrains.com/issue/KT-33617
|
||||
return true
|
||||
}
|
||||
return try {
|
||||
val fileFromUri = File(sourceFile)
|
||||
sourceCache.containsKey(sourceFile) || generatedTypes.containsKey(fileFromUri)
|
||||
} catch (e: IllegalArgumentException) {
|
||||
// unable to create File instance, avoid processing these files
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
/** Used for testing only. */
|
||||
internal fun getStructure(sourceFile: File) = sourceCache[sourceFile.toURI()]
|
||||
|
||||
Reference in New Issue
Block a user