Support reading annotations on java 9 module on sources and binaries
This commit is contained in:
@@ -46,6 +46,7 @@ import org.jetbrains.kotlin.resolve.calls.tower.ImplicitsExtensionsResolutionFil
|
||||
import org.jetbrains.kotlin.resolve.jvm.JavaDescriptorResolver
|
||||
import org.jetbrains.kotlin.resolve.jvm.JvmDiagnosticComponents
|
||||
import org.jetbrains.kotlin.resolve.jvm.extensions.SyntheticJavaResolveExtension
|
||||
import org.jetbrains.kotlin.resolve.jvm.modules.JavaModuleResolver
|
||||
import org.jetbrains.kotlin.resolve.jvm.multiplatform.OptionalAnnotationPackageFragmentProvider
|
||||
import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatformAnalyzerServices
|
||||
import org.jetbrains.kotlin.resolve.lazy.declarations.DeclarationProviderFactory
|
||||
@@ -147,6 +148,7 @@ fun StorageComponentContainer.configureJavaSpecificComponents(
|
||||
typeEnhancementImprovementsInStrictMode = languageVersionSettings.supportsFeature(LanguageFeature.TypeEnhancementImprovementsInStrictMode)
|
||||
)
|
||||
)
|
||||
useInstance(JavaModuleResolver.getInstance(moduleContext.project))
|
||||
|
||||
useImpl<FilesByFacadeFqNameIndexer>()
|
||||
useImpl<JvmDiagnosticComponents>()
|
||||
|
||||
@@ -29,6 +29,8 @@ import org.jetbrains.kotlin.utils.sure
|
||||
abstract class VirtualFileFinder : KotlinClassFinder {
|
||||
abstract fun findVirtualFileWithHeader(classId: ClassId): VirtualFile?
|
||||
|
||||
abstract fun findSourceOrBinaryVirtualFile(classId: ClassId): VirtualFile?
|
||||
|
||||
override fun findKotlinClassOrContent(classId: ClassId): KotlinClassFinder.Result? {
|
||||
val file = findVirtualFileWithHeader(classId) ?: return null
|
||||
return KotlinBinaryClassCache.getKotlinBinaryClassOrClassFileContent(file)
|
||||
|
||||
+35
-12
@@ -19,19 +19,24 @@ package org.jetbrains.kotlin.resolve.jvm.modules
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import com.intellij.psi.PsiJavaModule
|
||||
import com.intellij.psi.PsiModifier
|
||||
import org.jetbrains.kotlin.load.java.structure.JavaAnnotation
|
||||
import org.jetbrains.kotlin.load.java.structure.impl.JavaAnnotationImpl
|
||||
import org.jetbrains.kotlin.load.java.structure.impl.classFiles.BinaryClassSignatureParser
|
||||
import org.jetbrains.kotlin.load.java.structure.impl.classFiles.BinaryJavaAnnotation
|
||||
import org.jetbrains.kotlin.load.java.structure.impl.classFiles.ClassifierResolutionContext
|
||||
import org.jetbrains.kotlin.load.java.structure.impl.convert
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.resolve.jvm.KotlinCliJavaFileManager
|
||||
import org.jetbrains.org.objectweb.asm.*
|
||||
import org.jetbrains.kotlin.utils.compact
|
||||
import org.jetbrains.org.objectweb.asm.ClassReader
|
||||
import org.jetbrains.org.objectweb.asm.ClassVisitor
|
||||
import org.jetbrains.org.objectweb.asm.ModuleVisitor
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes.ACC_TRANSITIVE
|
||||
import java.io.IOException
|
||||
|
||||
class JavaModuleInfo(
|
||||
val moduleName: String,
|
||||
val requires: List<Requires>,
|
||||
val exports: List<Exports>
|
||||
val exports: List<Exports>,
|
||||
val annotations: List<JavaAnnotation>
|
||||
) {
|
||||
data class Requires(val moduleName: String, val isTransitive: Boolean)
|
||||
|
||||
@@ -51,15 +56,20 @@ class JavaModuleInfo(
|
||||
statement.packageName?.let { packageName ->
|
||||
Exports(FqName(packageName), statement.moduleNames)
|
||||
}
|
||||
}
|
||||
},
|
||||
psiJavaModule.annotations.convert(::JavaAnnotationImpl)
|
||||
)
|
||||
|
||||
fun read(file: VirtualFile): JavaModuleInfo? {
|
||||
val contents = try { file.contentsToByteArray() } catch (e: IOException) { return null }
|
||||
|
||||
fun read(file: VirtualFile, javaFileManager: KotlinCliJavaFileManager): JavaModuleInfo? {
|
||||
val contents = try {
|
||||
file.contentsToByteArray()
|
||||
} catch (e: IOException) {
|
||||
return null
|
||||
}
|
||||
var moduleName: String? = null
|
||||
val requires = arrayListOf<Requires>()
|
||||
val exports = arrayListOf<Exports>()
|
||||
val annotations = arrayListOf<JavaAnnotation>()
|
||||
|
||||
try {
|
||||
ClassReader(contents).accept(object : ClassVisitor(Opcodes.API_VERSION) {
|
||||
@@ -77,6 +87,21 @@ class JavaModuleInfo(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitAnnotation(descriptor: String?, visible: Boolean): AnnotationVisitor? {
|
||||
if (descriptor == null) return null
|
||||
|
||||
val (annotation, visitor) = BinaryJavaAnnotation.createAnnotationAndVisitor(
|
||||
descriptor,
|
||||
ClassifierResolutionContext(javaFileManager::findClass),
|
||||
BinaryClassSignatureParser(),
|
||||
isFreshlySupportedTypeUseAnnotation = true
|
||||
)
|
||||
|
||||
annotations.add(annotation)
|
||||
|
||||
return visitor
|
||||
}
|
||||
}, ClassReader.SKIP_DEBUG or ClassReader.SKIP_CODE or ClassReader.SKIP_FRAMES)
|
||||
} catch (e: Exception) {
|
||||
throw IllegalStateException(
|
||||
@@ -86,9 +111,7 @@ class JavaModuleInfo(
|
||||
)
|
||||
}
|
||||
|
||||
return if (moduleName != null)
|
||||
JavaModuleInfo(moduleName!!, requires.compact(), exports.compact())
|
||||
else null
|
||||
return moduleName?.let { JavaModuleInfo(it, requires.compact(), exports.compact(), annotations) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -19,9 +19,10 @@ package org.jetbrains.kotlin.resolve.jvm.modules
|
||||
import com.intellij.openapi.components.ServiceManager
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import org.jetbrains.kotlin.load.java.lazy.JavaModuleAnnotationsProvider
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
|
||||
interface JavaModuleResolver {
|
||||
interface JavaModuleResolver : JavaModuleAnnotationsProvider {
|
||||
fun checkAccessibility(fileFromOurModule: VirtualFile?, referencedFile: VirtualFile, referencedPackage: FqName?): AccessError?
|
||||
|
||||
sealed class AccessError {
|
||||
@@ -31,7 +32,6 @@ interface JavaModuleResolver {
|
||||
}
|
||||
|
||||
companion object SERVICE {
|
||||
fun getInstance(project: Project): JavaModuleResolver =
|
||||
ServiceManager.getService(project, JavaModuleResolver::class.java)
|
||||
fun getInstance(project: Project): JavaModuleResolver = ServiceManager.getService(project, JavaModuleResolver::class.java)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user