Support reading annotations on java 9 module on sources and binaries

This commit is contained in:
Victor Petukhov
2021-04-07 17:09:29 +03:00
parent 24685ee9d6
commit bc5e92033b
18 changed files with 140 additions and 43 deletions
@@ -37,6 +37,7 @@ import org.jetbrains.kotlin.cli.jvm.modules.CliJavaModuleFinder
import org.jetbrains.kotlin.cli.jvm.modules.JavaModuleGraph
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.isValidJavaFqName
import org.jetbrains.kotlin.resolve.jvm.KotlinCliJavaFileManager
import org.jetbrains.kotlin.resolve.jvm.modules.JavaModule
import org.jetbrains.kotlin.resolve.jvm.modules.JavaModuleInfo
import org.jetbrains.kotlin.resolve.jvm.modules.KOTLIN_STDLIB_MODULE_NAME
@@ -52,7 +53,8 @@ class ClasspathRootsResolver(
private val contentRootToVirtualFile: (JvmContentRoot) -> VirtualFile?,
private val javaModuleFinder: CliJavaModuleFinder,
private val requireStdlibModule: Boolean,
private val outputDirectory: VirtualFile?
private val outputDirectory: VirtualFile?,
private val javaFileManager: KotlinCliJavaFileManager
) {
val javaModuleGraph = JavaModuleGraph(javaModuleFinder)
@@ -160,7 +162,7 @@ class ClasspathRootsResolver(
}
if (moduleInfoFile != null) {
val moduleInfo = JavaModuleInfo.read(moduleInfoFile) ?: return null
val moduleInfo = JavaModuleInfo.read(moduleInfoFile, javaFileManager) ?: return null
return JavaModule.Explicit(moduleInfo, listOf(JavaModule.Root(root, isBinary = true)), moduleInfoFile)
}
@@ -35,6 +35,10 @@ class CliVirtualFileFinder(
override fun findVirtualFileWithHeader(classId: ClassId): VirtualFile? =
findBinaryClass(classId, classId.relativeClassName.asString().replace('.', '$') + ".class")
override fun findSourceOrBinaryVirtualFile(classId: ClassId) =
findBinaryClass(classId, classId.relativeClassName.asString().replace('.', '$') + ".class")
?: findSourceClass(classId, classId.relativeClassName.asString() + ".java")
override fun findMetadata(classId: ClassId): InputStream? {
assert(!classId.isNestedClass) { "Nested classes are not supported here: $classId" }
@@ -61,8 +65,11 @@ class CliVirtualFileFinder(
return findBinaryClass(classId, BuiltInSerializerProtocol.getBuiltInsFileName(packageFqName))?.inputStream
}
private fun findBinaryClass(classId: ClassId, fileName: String): VirtualFile? =
index.findClass(classId, acceptedRootTypes = JavaRoot.OnlyBinary) { dir, _ ->
private fun findClass(classId: ClassId, fileName: String, rootType: Set<JavaRoot.RootType>) =
index.findClass(classId, acceptedRootTypes = rootType) { dir, _ ->
dir.findChild(fileName)?.takeIf(VirtualFile::isValid)
}?.takeIf { it in scope }
private fun findBinaryClass(classId: ClassId, fileName: String) = findClass(classId, fileName, JavaRoot.OnlyBinary)
private fun findSourceClass(classId: ClassId, fileName: String) = findClass(classId, fileName, JavaRoot.OnlySource)
}
@@ -82,7 +82,9 @@ class KotlinCliJavaFileManagerImpl(private val myPsiManager: PsiManager) : CoreJ
private val binaryCache: MutableMap<ClassId, JavaClass?> = THashMap()
private val signatureParsingComponent = BinaryClassSignatureParser()
fun findClass(classId: ClassId, searchScope: GlobalSearchScope): JavaClass? = findClass(JavaClassFinder.Request(classId), searchScope)
fun findClass(classId: ClassId, searchScope: GlobalSearchScope) = findClass(JavaClassFinder.Request(classId), searchScope)
override fun findClass(classId: ClassId): JavaClass? = findClass(JavaClassFinder.Request(classId), allScope)
override fun findClass(request: JavaClassFinder.Request, searchScope: GlobalSearchScope): JavaClass? {
val (classId, classFileContentFromRequest, outerClassFromRequest) = request
@@ -110,7 +112,7 @@ class KotlinCliJavaFileManagerImpl(private val myPsiManager: PsiManager) : CoreJ
val classContent = classFileContentFromRequest ?: virtualFile.contentsToByteArray()
if (virtualFile.nameWithoutExtension.contains("$") && isNotTopLevelClass(classContent)) return@getOrPut null
val resolver = ClassifierResolutionContext { findClass(it, allScope) }
val resolver = ClassifierResolutionContext { findClass(it) }
BinaryJavaClass(
virtualFile, classId.asSingleFqName(), resolver, signatureParsingComponent,
@@ -190,11 +190,16 @@ class KotlinCoreEnvironment private constructor(
sourceFiles.sortBy { it.virtualFile.path }
val javaFileManager = ServiceManager.getService(project, CoreJavaFileManager::class.java) as KotlinCliJavaFileManagerImpl
val jdkHome = configuration.get(JVMConfigurationKeys.JDK_HOME)
val jrtFileSystem = VirtualFileManager.getInstance().getFileSystem(StandardFileSystems.JRT_PROTOCOL)
val javaModuleFinder = CliJavaModuleFinder(jdkHome?.path?.let { path ->
jrtFileSystem?.findFileByPath(path + URLUtil.JAR_SEPARATOR)
})
val javaModuleFinder = CliJavaModuleFinder(
jdkHome?.path?.let { path ->
jrtFileSystem?.findFileByPath(path + URLUtil.JAR_SEPARATOR)
},
javaFileManager
)
val outputDirectory =
configuration.get(JVMConfigurationKeys.MODULES)?.singleOrNull()?.getOutputDirectory()
@@ -207,7 +212,8 @@ class KotlinCoreEnvironment private constructor(
this::contentRootToVirtualFile,
javaModuleFinder,
!configuration.getBoolean(CLIConfigurationKeys.ALLOW_KOTLIN_PACKAGE),
outputDirectory?.let(this::findLocalFile)
outputDirectory?.let(this::findLocalFile),
javaFileManager
)
val (initialRoots, javaModules) =
@@ -231,7 +237,7 @@ class KotlinCoreEnvironment private constructor(
updateClasspathFromRootsIndex(this)
}
(ServiceManager.getService(project, CoreJavaFileManager::class.java) as KotlinCliJavaFileManagerImpl).initialize(
javaFileManager.initialize(
rootsIndex,
packagePartProviders,
SingleJavaFileRootsIndex(singleJavaFileRoots),
@@ -240,7 +246,7 @@ class KotlinCoreEnvironment private constructor(
project.registerService(
JavaModuleResolver::class.java,
CliJavaModuleResolver(classpathRootsResolver.javaModuleGraph, javaModules, javaModuleFinder.systemModules.toList())
CliJavaModuleResolver(classpathRootsResolver.javaModuleGraph, javaModules, javaModuleFinder.systemModules.toList(), project)
)
val finderFactory = CliVirtualFileFinderFactory(rootsIndex)
@@ -78,10 +78,7 @@ import org.jetbrains.kotlin.cli.jvm.modules.CoreJrtFileSystem
import org.jetbrains.kotlin.codegen.extensions.ClassBuilderInterceptorExtension
import org.jetbrains.kotlin.codegen.extensions.ExpressionCodegenExtension
import org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar
import org.jetbrains.kotlin.config.APPEND_JAVA_SOURCE_ROOTS_HANDLER_KEY
import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.config.JVMConfigurationKeys
import org.jetbrains.kotlin.config.languageVersionSettings
import org.jetbrains.kotlin.config.*
import org.jetbrains.kotlin.extensions.*
import org.jetbrains.kotlin.extensions.internal.CandidateInterceptor
import org.jetbrains.kotlin.extensions.internal.TypeResolutionInterceptor
@@ -193,11 +190,16 @@ class KotlinCoreEnvironment private constructor(
sourceFiles.sortBy { it.virtualFile.path }
val javaFileManager = ServiceManager.getService(project, CoreJavaFileManager::class.java) as KotlinCliJavaFileManagerImpl
val jdkHome = configuration.get(JVMConfigurationKeys.JDK_HOME)
val jrtFileSystem = VirtualFileManager.getInstance().getFileSystem(StandardFileSystems.JRT_PROTOCOL)
val javaModuleFinder = CliJavaModuleFinder(jdkHome?.path?.let { path ->
jrtFileSystem?.findFileByPath(path + URLUtil.JAR_SEPARATOR)
})
val javaModuleFinder = CliJavaModuleFinder(
jdkHome?.path?.let { path ->
jrtFileSystem?.findFileByPath(path + URLUtil.JAR_SEPARATOR)
},
javaFileManager
)
val outputDirectory =
configuration.get(JVMConfigurationKeys.MODULES)?.singleOrNull()?.getOutputDirectory()
@@ -210,7 +212,8 @@ class KotlinCoreEnvironment private constructor(
this::contentRootToVirtualFile,
javaModuleFinder,
!configuration.getBoolean(CLIConfigurationKeys.ALLOW_KOTLIN_PACKAGE),
outputDirectory?.let(this::findLocalFile)
outputDirectory?.let(this::findLocalFile),
javaFileManager
)
val (initialRoots, javaModules) =
@@ -234,7 +237,7 @@ class KotlinCoreEnvironment private constructor(
updateClasspathFromRootsIndex(this)
}
(ServiceManager.getService(project, CoreJavaFileManager::class.java) as KotlinCliJavaFileManagerImpl).initialize(
javaFileManager.initialize(
rootsIndex,
packagePartProviders,
SingleJavaFileRootsIndex(singleJavaFileRoots),
@@ -243,7 +246,7 @@ class KotlinCoreEnvironment private constructor(
project.registerService(
JavaModuleResolver::class.java,
CliJavaModuleResolver(classpathRootsResolver.javaModuleGraph, javaModules, javaModuleFinder.systemModules.toList())
CliJavaModuleResolver(classpathRootsResolver.javaModuleGraph, javaModules, javaModuleFinder.systemModules.toList(), project)
)
val finderFactory = CliVirtualFileFinderFactory(rootsIndex)
@@ -45,6 +45,7 @@ data class JavaRoot(val file: VirtualFile, val type: RootType, val prefixFqName:
companion object RootTypes {
val OnlyBinary: Set<RootType> = EnumSet.of(RootType.BINARY)
val OnlySource: Set<RootType> = EnumSet.of(RootType.SOURCE)
val SourceAndBinary: Set<RootType> = EnumSet.of(RootType.BINARY, RootType.SOURCE)
}
}
@@ -18,11 +18,12 @@ package org.jetbrains.kotlin.cli.jvm.modules
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.psi.PsiJavaModule
import org.jetbrains.kotlin.resolve.jvm.KotlinCliJavaFileManager
import org.jetbrains.kotlin.resolve.jvm.modules.JavaModule
import org.jetbrains.kotlin.resolve.jvm.modules.JavaModuleFinder
import org.jetbrains.kotlin.resolve.jvm.modules.JavaModuleInfo
class CliJavaModuleFinder(jrtFileSystemRoot: VirtualFile?) : JavaModuleFinder {
class CliJavaModuleFinder(jrtFileSystemRoot: VirtualFile?, val javaFileManager: KotlinCliJavaFileManager) : JavaModuleFinder {
private val modulesRoot = jrtFileSystemRoot?.findChild("modules")
private val userModules = linkedMapOf<String, JavaModule>()
@@ -41,7 +42,7 @@ class CliJavaModuleFinder(jrtFileSystemRoot: VirtualFile?) : JavaModuleFinder {
private fun findSystemModule(moduleRoot: VirtualFile): JavaModule.Explicit? {
val file = moduleRoot.findChild(PsiJavaModule.MODULE_INFO_CLS_FILE) ?: return null
val moduleInfo = JavaModuleInfo.read(file) ?: return null
val moduleInfo = JavaModuleInfo.read(file, javaFileManager) ?: return null
return JavaModule.Explicit(moduleInfo, listOf(JavaModule.Root(moduleRoot, isBinary = true)), file)
}
}
@@ -18,10 +18,14 @@ package org.jetbrains.kotlin.cli.jvm.modules
import com.intellij.ide.highlighter.JavaClassFileType
import com.intellij.ide.highlighter.JavaFileType
import com.intellij.openapi.project.Project
import com.intellij.openapi.vfs.StandardFileSystems
import com.intellij.openapi.vfs.VfsUtilCore
import com.intellij.openapi.vfs.VirtualFile
import org.jetbrains.kotlin.idea.KotlinFileType
import org.jetbrains.kotlin.load.java.structure.JavaAnnotation
import org.jetbrains.kotlin.load.kotlin.VirtualFileFinder
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.resolve.jvm.modules.JavaModule
import org.jetbrains.kotlin.resolve.jvm.modules.JavaModuleResolver
@@ -29,7 +33,8 @@ import org.jetbrains.kotlin.resolve.jvm.modules.JavaModuleResolver
class CliJavaModuleResolver(
private val moduleGraph: JavaModuleGraph,
private val userModules: List<JavaModule>,
private val systemModules: List<JavaModule.Explicit>
private val systemModules: List<JavaModule.Explicit>,
private val project: Project
) : JavaModuleResolver {
init {
assert(userModules.count(JavaModule::isSourceModule) <= 1) {
@@ -37,6 +42,13 @@ class CliJavaModuleResolver(
}
}
private val virtualFileFinder by lazy { VirtualFileFinder.getInstance(project) }
override fun getModuleAnnotations(classId: ClassId): List<JavaAnnotation>? {
val virtualFile = virtualFileFinder.findSourceOrBinaryVirtualFile(classId) ?: return null
return (findJavaModule(virtualFile) as? JavaModule.Explicit)?.moduleInfo?.annotations
}
private val sourceModule: JavaModule? = userModules.firstOrNull(JavaModule::isSourceModule)
private fun findJavaModule(file: VirtualFile): JavaModule? {
@@ -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)
@@ -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) }
}
}
}
@@ -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)
}
}
@@ -20,9 +20,11 @@ import com.intellij.psi.impl.file.impl.JavaFileManager
import com.intellij.psi.search.GlobalSearchScope
import org.jetbrains.kotlin.load.java.JavaClassFinder
import org.jetbrains.kotlin.load.java.structure.JavaClass
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
interface KotlinCliJavaFileManager : JavaFileManager {
fun findClass(classId: ClassId): JavaClass?
fun findClass(request: JavaClassFinder.Request, searchScope: GlobalSearchScope): JavaClass?
fun knownClassNamesInPackage(packageFqName: FqName): Set<String>?
}
@@ -0,0 +1,13 @@
/*
* Copyright 2010-2021 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 org.jetbrains.kotlin.load.java.lazy
import org.jetbrains.kotlin.load.java.structure.JavaAnnotation
import org.jetbrains.kotlin.name.ClassId
interface JavaModuleAnnotationsProvider {
fun getModuleAnnotations(classId: ClassId): List<JavaAnnotation>?
}
@@ -65,6 +65,7 @@ class JavaResolverComponents(
val settings: JavaResolverSettings,
val kotlinTypeChecker: NewKotlinTypeChecker,
val javaTypeEnhancementState: JavaTypeEnhancementState,
val javaModuleResolver: JavaModuleAnnotationsProvider,
val syntheticPartsProvider: SyntheticJavaPartsProvider = SyntheticJavaPartsProvider.EMPTY
) {
fun replace(
@@ -75,8 +76,7 @@ class JavaResolverComponents(
javaPropertyInitializerEvaluator, samConversionResolver, sourceElementFactory,
moduleClassResolver, packagePartProvider, supertypeLoopChecker, lookupTracker, module, reflectionTypes,
annotationTypeQualifierResolver, signatureEnhancement, javaClassesTracker, settings,
kotlinTypeChecker,
javaTypeEnhancementState
kotlinTypeChecker, javaTypeEnhancementState, javaModuleResolver
)
}
@@ -31,9 +31,11 @@ import org.jetbrains.kotlin.load.java.components.JavaPropertyInitializerEvaluato
import org.jetbrains.kotlin.load.java.components.JavaResolverCache
import org.jetbrains.kotlin.load.java.components.SignaturePropagator
import org.jetbrains.kotlin.load.java.lazy.*
import org.jetbrains.kotlin.load.java.structure.JavaAnnotation
import org.jetbrains.kotlin.load.java.typeEnhancement.JavaTypeEnhancement
import org.jetbrains.kotlin.load.java.typeEnhancement.SignatureEnhancement
import org.jetbrains.kotlin.load.kotlin.*
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.jvm.JavaDescriptorResolver
import org.jetbrains.kotlin.resolve.sam.SamConversionResolverImpl
@@ -119,7 +121,10 @@ fun makeLazyJavaPackageFragmentFromClassLoaderProvider(
singleModuleClassResolver, packagePartProvider, SupertypeLoopChecker.EMPTY, LookupTracker.DO_NOTHING, module,
ReflectionTypes(module, notFoundClasses), annotationTypeQualifierResolver,
SignatureEnhancement(annotationTypeQualifierResolver, JavaTypeEnhancementState.DISABLED_JSR_305, JavaTypeEnhancement(JavaResolverSettings.Default)),
JavaClassesTracker.Default, JavaResolverSettings.Default, NewKotlinTypeChecker.Default, javaTypeEnhancementState
JavaClassesTracker.Default, JavaResolverSettings.Default, NewKotlinTypeChecker.Default, javaTypeEnhancementState,
object : JavaModuleAnnotationsProvider {
override fun getModuleAnnotations(classId: ClassId): List<JavaAnnotation>? = null
}
)
return LazyJavaPackageFragmentProvider(javaResolverComponents)
@@ -10,10 +10,24 @@ import com.intellij.openapi.project.Project
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.psi.PsiJavaModule
import com.intellij.psi.impl.light.LightJavaModule
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.convert
import org.jetbrains.kotlin.load.kotlin.VirtualFileFinder
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.resolve.jvm.modules.JavaModule
import org.jetbrains.kotlin.resolve.jvm.modules.JavaModuleResolver
class IdeJavaModuleResolver(private val project: Project) : JavaModuleResolver {
private val virtualFileFinder by lazy { VirtualFileFinder.getInstance(project) }
override fun getModuleAnnotations(classId: ClassId): List<JavaAnnotation>? {
val virtualFile = virtualFileFinder.findVirtualFileWithHeader(classId) ?: return null
return findJavaModule(virtualFile)?.annotations?.convert(::JavaAnnotationImpl)
}
private fun findJavaModule(file: VirtualFile): PsiJavaModule? = ModuleHighlightUtil2.getModuleDescriptor(file, project)
override fun checkAccessibility(
@@ -32,6 +32,8 @@ class IDEVirtualFileFinder(private val scope: GlobalSearchScope) : VirtualFileFi
override fun findBuiltInsData(packageFqName: FqName): InputStream? =
findVirtualFileWithHeader(packageFqName, KotlinBuiltInsMetadataIndex.KEY)?.inputStream
override fun findSourceOrBinaryVirtualFile(classId: ClassId) = findVirtualFileWithHeader(classId)
init {
if (scope != GlobalSearchScope.EMPTY_SCOPE && scope.project == null) {
LOG.warn("Scope with null project $scope")