Support reading annotations on java 9 module on sources and binaries
This commit is contained in:
@@ -37,6 +37,7 @@ import org.jetbrains.kotlin.cli.jvm.modules.CliJavaModuleFinder
|
|||||||
import org.jetbrains.kotlin.cli.jvm.modules.JavaModuleGraph
|
import org.jetbrains.kotlin.cli.jvm.modules.JavaModuleGraph
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.name.isValidJavaFqName
|
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.JavaModule
|
||||||
import org.jetbrains.kotlin.resolve.jvm.modules.JavaModuleInfo
|
import org.jetbrains.kotlin.resolve.jvm.modules.JavaModuleInfo
|
||||||
import org.jetbrains.kotlin.resolve.jvm.modules.KOTLIN_STDLIB_MODULE_NAME
|
import org.jetbrains.kotlin.resolve.jvm.modules.KOTLIN_STDLIB_MODULE_NAME
|
||||||
@@ -52,7 +53,8 @@ class ClasspathRootsResolver(
|
|||||||
private val contentRootToVirtualFile: (JvmContentRoot) -> VirtualFile?,
|
private val contentRootToVirtualFile: (JvmContentRoot) -> VirtualFile?,
|
||||||
private val javaModuleFinder: CliJavaModuleFinder,
|
private val javaModuleFinder: CliJavaModuleFinder,
|
||||||
private val requireStdlibModule: Boolean,
|
private val requireStdlibModule: Boolean,
|
||||||
private val outputDirectory: VirtualFile?
|
private val outputDirectory: VirtualFile?,
|
||||||
|
private val javaFileManager: KotlinCliJavaFileManager
|
||||||
) {
|
) {
|
||||||
val javaModuleGraph = JavaModuleGraph(javaModuleFinder)
|
val javaModuleGraph = JavaModuleGraph(javaModuleFinder)
|
||||||
|
|
||||||
@@ -160,7 +162,7 @@ class ClasspathRootsResolver(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (moduleInfoFile != null) {
|
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)
|
return JavaModule.Explicit(moduleInfo, listOf(JavaModule.Root(root, isBinary = true)), moduleInfoFile)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -35,6 +35,10 @@ class CliVirtualFileFinder(
|
|||||||
override fun findVirtualFileWithHeader(classId: ClassId): VirtualFile? =
|
override fun findVirtualFileWithHeader(classId: ClassId): VirtualFile? =
|
||||||
findBinaryClass(classId, classId.relativeClassName.asString().replace('.', '$') + ".class")
|
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? {
|
override fun findMetadata(classId: ClassId): InputStream? {
|
||||||
assert(!classId.isNestedClass) { "Nested classes are not supported here: $classId" }
|
assert(!classId.isNestedClass) { "Nested classes are not supported here: $classId" }
|
||||||
|
|
||||||
@@ -61,8 +65,11 @@ class CliVirtualFileFinder(
|
|||||||
return findBinaryClass(classId, BuiltInSerializerProtocol.getBuiltInsFileName(packageFqName))?.inputStream
|
return findBinaryClass(classId, BuiltInSerializerProtocol.getBuiltInsFileName(packageFqName))?.inputStream
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun findBinaryClass(classId: ClassId, fileName: String): VirtualFile? =
|
private fun findClass(classId: ClassId, fileName: String, rootType: Set<JavaRoot.RootType>) =
|
||||||
index.findClass(classId, acceptedRootTypes = JavaRoot.OnlyBinary) { dir, _ ->
|
index.findClass(classId, acceptedRootTypes = rootType) { dir, _ ->
|
||||||
dir.findChild(fileName)?.takeIf(VirtualFile::isValid)
|
dir.findChild(fileName)?.takeIf(VirtualFile::isValid)
|
||||||
}?.takeIf { it in scope }
|
}?.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)
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-2
@@ -82,7 +82,9 @@ class KotlinCliJavaFileManagerImpl(private val myPsiManager: PsiManager) : CoreJ
|
|||||||
private val binaryCache: MutableMap<ClassId, JavaClass?> = THashMap()
|
private val binaryCache: MutableMap<ClassId, JavaClass?> = THashMap()
|
||||||
private val signatureParsingComponent = BinaryClassSignatureParser()
|
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? {
|
override fun findClass(request: JavaClassFinder.Request, searchScope: GlobalSearchScope): JavaClass? {
|
||||||
val (classId, classFileContentFromRequest, outerClassFromRequest) = request
|
val (classId, classFileContentFromRequest, outerClassFromRequest) = request
|
||||||
@@ -110,7 +112,7 @@ class KotlinCliJavaFileManagerImpl(private val myPsiManager: PsiManager) : CoreJ
|
|||||||
val classContent = classFileContentFromRequest ?: virtualFile.contentsToByteArray()
|
val classContent = classFileContentFromRequest ?: virtualFile.contentsToByteArray()
|
||||||
if (virtualFile.nameWithoutExtension.contains("$") && isNotTopLevelClass(classContent)) return@getOrPut null
|
if (virtualFile.nameWithoutExtension.contains("$") && isNotTopLevelClass(classContent)) return@getOrPut null
|
||||||
|
|
||||||
val resolver = ClassifierResolutionContext { findClass(it, allScope) }
|
val resolver = ClassifierResolutionContext { findClass(it) }
|
||||||
|
|
||||||
BinaryJavaClass(
|
BinaryJavaClass(
|
||||||
virtualFile, classId.asSingleFqName(), resolver, signatureParsingComponent,
|
virtualFile, classId.asSingleFqName(), resolver, signatureParsingComponent,
|
||||||
|
|||||||
@@ -190,11 +190,16 @@ class KotlinCoreEnvironment private constructor(
|
|||||||
|
|
||||||
sourceFiles.sortBy { it.virtualFile.path }
|
sourceFiles.sortBy { it.virtualFile.path }
|
||||||
|
|
||||||
|
val javaFileManager = ServiceManager.getService(project, CoreJavaFileManager::class.java) as KotlinCliJavaFileManagerImpl
|
||||||
|
|
||||||
val jdkHome = configuration.get(JVMConfigurationKeys.JDK_HOME)
|
val jdkHome = configuration.get(JVMConfigurationKeys.JDK_HOME)
|
||||||
val jrtFileSystem = VirtualFileManager.getInstance().getFileSystem(StandardFileSystems.JRT_PROTOCOL)
|
val jrtFileSystem = VirtualFileManager.getInstance().getFileSystem(StandardFileSystems.JRT_PROTOCOL)
|
||||||
val javaModuleFinder = CliJavaModuleFinder(jdkHome?.path?.let { path ->
|
val javaModuleFinder = CliJavaModuleFinder(
|
||||||
jrtFileSystem?.findFileByPath(path + URLUtil.JAR_SEPARATOR)
|
jdkHome?.path?.let { path ->
|
||||||
})
|
jrtFileSystem?.findFileByPath(path + URLUtil.JAR_SEPARATOR)
|
||||||
|
},
|
||||||
|
javaFileManager
|
||||||
|
)
|
||||||
|
|
||||||
val outputDirectory =
|
val outputDirectory =
|
||||||
configuration.get(JVMConfigurationKeys.MODULES)?.singleOrNull()?.getOutputDirectory()
|
configuration.get(JVMConfigurationKeys.MODULES)?.singleOrNull()?.getOutputDirectory()
|
||||||
@@ -207,7 +212,8 @@ class KotlinCoreEnvironment private constructor(
|
|||||||
this::contentRootToVirtualFile,
|
this::contentRootToVirtualFile,
|
||||||
javaModuleFinder,
|
javaModuleFinder,
|
||||||
!configuration.getBoolean(CLIConfigurationKeys.ALLOW_KOTLIN_PACKAGE),
|
!configuration.getBoolean(CLIConfigurationKeys.ALLOW_KOTLIN_PACKAGE),
|
||||||
outputDirectory?.let(this::findLocalFile)
|
outputDirectory?.let(this::findLocalFile),
|
||||||
|
javaFileManager
|
||||||
)
|
)
|
||||||
|
|
||||||
val (initialRoots, javaModules) =
|
val (initialRoots, javaModules) =
|
||||||
@@ -231,7 +237,7 @@ class KotlinCoreEnvironment private constructor(
|
|||||||
updateClasspathFromRootsIndex(this)
|
updateClasspathFromRootsIndex(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
(ServiceManager.getService(project, CoreJavaFileManager::class.java) as KotlinCliJavaFileManagerImpl).initialize(
|
javaFileManager.initialize(
|
||||||
rootsIndex,
|
rootsIndex,
|
||||||
packagePartProviders,
|
packagePartProviders,
|
||||||
SingleJavaFileRootsIndex(singleJavaFileRoots),
|
SingleJavaFileRootsIndex(singleJavaFileRoots),
|
||||||
@@ -240,7 +246,7 @@ class KotlinCoreEnvironment private constructor(
|
|||||||
|
|
||||||
project.registerService(
|
project.registerService(
|
||||||
JavaModuleResolver::class.java,
|
JavaModuleResolver::class.java,
|
||||||
CliJavaModuleResolver(classpathRootsResolver.javaModuleGraph, javaModules, javaModuleFinder.systemModules.toList())
|
CliJavaModuleResolver(classpathRootsResolver.javaModuleGraph, javaModules, javaModuleFinder.systemModules.toList(), project)
|
||||||
)
|
)
|
||||||
|
|
||||||
val finderFactory = CliVirtualFileFinderFactory(rootsIndex)
|
val finderFactory = CliVirtualFileFinderFactory(rootsIndex)
|
||||||
|
|||||||
+13
-10
@@ -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.ClassBuilderInterceptorExtension
|
||||||
import org.jetbrains.kotlin.codegen.extensions.ExpressionCodegenExtension
|
import org.jetbrains.kotlin.codegen.extensions.ExpressionCodegenExtension
|
||||||
import org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar
|
import org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar
|
||||||
import org.jetbrains.kotlin.config.APPEND_JAVA_SOURCE_ROOTS_HANDLER_KEY
|
import org.jetbrains.kotlin.config.*
|
||||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
|
||||||
import org.jetbrains.kotlin.config.JVMConfigurationKeys
|
|
||||||
import org.jetbrains.kotlin.config.languageVersionSettings
|
|
||||||
import org.jetbrains.kotlin.extensions.*
|
import org.jetbrains.kotlin.extensions.*
|
||||||
import org.jetbrains.kotlin.extensions.internal.CandidateInterceptor
|
import org.jetbrains.kotlin.extensions.internal.CandidateInterceptor
|
||||||
import org.jetbrains.kotlin.extensions.internal.TypeResolutionInterceptor
|
import org.jetbrains.kotlin.extensions.internal.TypeResolutionInterceptor
|
||||||
@@ -193,11 +190,16 @@ class KotlinCoreEnvironment private constructor(
|
|||||||
|
|
||||||
sourceFiles.sortBy { it.virtualFile.path }
|
sourceFiles.sortBy { it.virtualFile.path }
|
||||||
|
|
||||||
|
val javaFileManager = ServiceManager.getService(project, CoreJavaFileManager::class.java) as KotlinCliJavaFileManagerImpl
|
||||||
|
|
||||||
val jdkHome = configuration.get(JVMConfigurationKeys.JDK_HOME)
|
val jdkHome = configuration.get(JVMConfigurationKeys.JDK_HOME)
|
||||||
val jrtFileSystem = VirtualFileManager.getInstance().getFileSystem(StandardFileSystems.JRT_PROTOCOL)
|
val jrtFileSystem = VirtualFileManager.getInstance().getFileSystem(StandardFileSystems.JRT_PROTOCOL)
|
||||||
val javaModuleFinder = CliJavaModuleFinder(jdkHome?.path?.let { path ->
|
val javaModuleFinder = CliJavaModuleFinder(
|
||||||
jrtFileSystem?.findFileByPath(path + URLUtil.JAR_SEPARATOR)
|
jdkHome?.path?.let { path ->
|
||||||
})
|
jrtFileSystem?.findFileByPath(path + URLUtil.JAR_SEPARATOR)
|
||||||
|
},
|
||||||
|
javaFileManager
|
||||||
|
)
|
||||||
|
|
||||||
val outputDirectory =
|
val outputDirectory =
|
||||||
configuration.get(JVMConfigurationKeys.MODULES)?.singleOrNull()?.getOutputDirectory()
|
configuration.get(JVMConfigurationKeys.MODULES)?.singleOrNull()?.getOutputDirectory()
|
||||||
@@ -210,7 +212,8 @@ class KotlinCoreEnvironment private constructor(
|
|||||||
this::contentRootToVirtualFile,
|
this::contentRootToVirtualFile,
|
||||||
javaModuleFinder,
|
javaModuleFinder,
|
||||||
!configuration.getBoolean(CLIConfigurationKeys.ALLOW_KOTLIN_PACKAGE),
|
!configuration.getBoolean(CLIConfigurationKeys.ALLOW_KOTLIN_PACKAGE),
|
||||||
outputDirectory?.let(this::findLocalFile)
|
outputDirectory?.let(this::findLocalFile),
|
||||||
|
javaFileManager
|
||||||
)
|
)
|
||||||
|
|
||||||
val (initialRoots, javaModules) =
|
val (initialRoots, javaModules) =
|
||||||
@@ -234,7 +237,7 @@ class KotlinCoreEnvironment private constructor(
|
|||||||
updateClasspathFromRootsIndex(this)
|
updateClasspathFromRootsIndex(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
(ServiceManager.getService(project, CoreJavaFileManager::class.java) as KotlinCliJavaFileManagerImpl).initialize(
|
javaFileManager.initialize(
|
||||||
rootsIndex,
|
rootsIndex,
|
||||||
packagePartProviders,
|
packagePartProviders,
|
||||||
SingleJavaFileRootsIndex(singleJavaFileRoots),
|
SingleJavaFileRootsIndex(singleJavaFileRoots),
|
||||||
@@ -243,7 +246,7 @@ class KotlinCoreEnvironment private constructor(
|
|||||||
|
|
||||||
project.registerService(
|
project.registerService(
|
||||||
JavaModuleResolver::class.java,
|
JavaModuleResolver::class.java,
|
||||||
CliJavaModuleResolver(classpathRootsResolver.javaModuleGraph, javaModules, javaModuleFinder.systemModules.toList())
|
CliJavaModuleResolver(classpathRootsResolver.javaModuleGraph, javaModules, javaModuleFinder.systemModules.toList(), project)
|
||||||
)
|
)
|
||||||
|
|
||||||
val finderFactory = CliVirtualFileFinderFactory(rootsIndex)
|
val finderFactory = CliVirtualFileFinderFactory(rootsIndex)
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ data class JavaRoot(val file: VirtualFile, val type: RootType, val prefixFqName:
|
|||||||
|
|
||||||
companion object RootTypes {
|
companion object RootTypes {
|
||||||
val OnlyBinary: Set<RootType> = EnumSet.of(RootType.BINARY)
|
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)
|
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.openapi.vfs.VirtualFile
|
||||||
import com.intellij.psi.PsiJavaModule
|
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.JavaModule
|
||||||
import org.jetbrains.kotlin.resolve.jvm.modules.JavaModuleFinder
|
import org.jetbrains.kotlin.resolve.jvm.modules.JavaModuleFinder
|
||||||
import org.jetbrains.kotlin.resolve.jvm.modules.JavaModuleInfo
|
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 modulesRoot = jrtFileSystemRoot?.findChild("modules")
|
||||||
private val userModules = linkedMapOf<String, JavaModule>()
|
private val userModules = linkedMapOf<String, JavaModule>()
|
||||||
|
|
||||||
@@ -41,7 +42,7 @@ class CliJavaModuleFinder(jrtFileSystemRoot: VirtualFile?) : JavaModuleFinder {
|
|||||||
|
|
||||||
private fun findSystemModule(moduleRoot: VirtualFile): JavaModule.Explicit? {
|
private fun findSystemModule(moduleRoot: VirtualFile): JavaModule.Explicit? {
|
||||||
val file = moduleRoot.findChild(PsiJavaModule.MODULE_INFO_CLS_FILE) ?: return null
|
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)
|
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.JavaClassFileType
|
||||||
import com.intellij.ide.highlighter.JavaFileType
|
import com.intellij.ide.highlighter.JavaFileType
|
||||||
|
import com.intellij.openapi.project.Project
|
||||||
import com.intellij.openapi.vfs.StandardFileSystems
|
import com.intellij.openapi.vfs.StandardFileSystems
|
||||||
import com.intellij.openapi.vfs.VfsUtilCore
|
import com.intellij.openapi.vfs.VfsUtilCore
|
||||||
import com.intellij.openapi.vfs.VirtualFile
|
import com.intellij.openapi.vfs.VirtualFile
|
||||||
import org.jetbrains.kotlin.idea.KotlinFileType
|
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.name.FqName
|
||||||
import org.jetbrains.kotlin.resolve.jvm.modules.JavaModule
|
import org.jetbrains.kotlin.resolve.jvm.modules.JavaModule
|
||||||
import org.jetbrains.kotlin.resolve.jvm.modules.JavaModuleResolver
|
import org.jetbrains.kotlin.resolve.jvm.modules.JavaModuleResolver
|
||||||
@@ -29,7 +33,8 @@ import org.jetbrains.kotlin.resolve.jvm.modules.JavaModuleResolver
|
|||||||
class CliJavaModuleResolver(
|
class CliJavaModuleResolver(
|
||||||
private val moduleGraph: JavaModuleGraph,
|
private val moduleGraph: JavaModuleGraph,
|
||||||
private val userModules: List<JavaModule>,
|
private val userModules: List<JavaModule>,
|
||||||
private val systemModules: List<JavaModule.Explicit>
|
private val systemModules: List<JavaModule.Explicit>,
|
||||||
|
private val project: Project
|
||||||
) : JavaModuleResolver {
|
) : JavaModuleResolver {
|
||||||
init {
|
init {
|
||||||
assert(userModules.count(JavaModule::isSourceModule) <= 1) {
|
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 val sourceModule: JavaModule? = userModules.firstOrNull(JavaModule::isSourceModule)
|
||||||
|
|
||||||
private fun findJavaModule(file: VirtualFile): JavaModule? {
|
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.JavaDescriptorResolver
|
||||||
import org.jetbrains.kotlin.resolve.jvm.JvmDiagnosticComponents
|
import org.jetbrains.kotlin.resolve.jvm.JvmDiagnosticComponents
|
||||||
import org.jetbrains.kotlin.resolve.jvm.extensions.SyntheticJavaResolveExtension
|
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.multiplatform.OptionalAnnotationPackageFragmentProvider
|
||||||
import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatformAnalyzerServices
|
import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatformAnalyzerServices
|
||||||
import org.jetbrains.kotlin.resolve.lazy.declarations.DeclarationProviderFactory
|
import org.jetbrains.kotlin.resolve.lazy.declarations.DeclarationProviderFactory
|
||||||
@@ -147,6 +148,7 @@ fun StorageComponentContainer.configureJavaSpecificComponents(
|
|||||||
typeEnhancementImprovementsInStrictMode = languageVersionSettings.supportsFeature(LanguageFeature.TypeEnhancementImprovementsInStrictMode)
|
typeEnhancementImprovementsInStrictMode = languageVersionSettings.supportsFeature(LanguageFeature.TypeEnhancementImprovementsInStrictMode)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
useInstance(JavaModuleResolver.getInstance(moduleContext.project))
|
||||||
|
|
||||||
useImpl<FilesByFacadeFqNameIndexer>()
|
useImpl<FilesByFacadeFqNameIndexer>()
|
||||||
useImpl<JvmDiagnosticComponents>()
|
useImpl<JvmDiagnosticComponents>()
|
||||||
|
|||||||
@@ -29,6 +29,8 @@ import org.jetbrains.kotlin.utils.sure
|
|||||||
abstract class VirtualFileFinder : KotlinClassFinder {
|
abstract class VirtualFileFinder : KotlinClassFinder {
|
||||||
abstract fun findVirtualFileWithHeader(classId: ClassId): VirtualFile?
|
abstract fun findVirtualFileWithHeader(classId: ClassId): VirtualFile?
|
||||||
|
|
||||||
|
abstract fun findSourceOrBinaryVirtualFile(classId: ClassId): VirtualFile?
|
||||||
|
|
||||||
override fun findKotlinClassOrContent(classId: ClassId): KotlinClassFinder.Result? {
|
override fun findKotlinClassOrContent(classId: ClassId): KotlinClassFinder.Result? {
|
||||||
val file = findVirtualFileWithHeader(classId) ?: return null
|
val file = findVirtualFileWithHeader(classId) ?: return null
|
||||||
return KotlinBinaryClassCache.getKotlinBinaryClassOrClassFileContent(file)
|
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.openapi.vfs.VirtualFile
|
||||||
import com.intellij.psi.PsiJavaModule
|
import com.intellij.psi.PsiJavaModule
|
||||||
import com.intellij.psi.PsiModifier
|
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.name.FqName
|
||||||
|
import org.jetbrains.kotlin.resolve.jvm.KotlinCliJavaFileManager
|
||||||
|
import org.jetbrains.org.objectweb.asm.*
|
||||||
import org.jetbrains.kotlin.utils.compact
|
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 org.jetbrains.org.objectweb.asm.Opcodes.ACC_TRANSITIVE
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
|
|
||||||
class JavaModuleInfo(
|
class JavaModuleInfo(
|
||||||
val moduleName: String,
|
val moduleName: String,
|
||||||
val requires: List<Requires>,
|
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)
|
data class Requires(val moduleName: String, val isTransitive: Boolean)
|
||||||
|
|
||||||
@@ -51,15 +56,20 @@ class JavaModuleInfo(
|
|||||||
statement.packageName?.let { packageName ->
|
statement.packageName?.let { packageName ->
|
||||||
Exports(FqName(packageName), statement.moduleNames)
|
Exports(FqName(packageName), statement.moduleNames)
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
psiJavaModule.annotations.convert(::JavaAnnotationImpl)
|
||||||
)
|
)
|
||||||
|
|
||||||
fun read(file: VirtualFile): JavaModuleInfo? {
|
fun read(file: VirtualFile, javaFileManager: KotlinCliJavaFileManager): JavaModuleInfo? {
|
||||||
val contents = try { file.contentsToByteArray() } catch (e: IOException) { return null }
|
val contents = try {
|
||||||
|
file.contentsToByteArray()
|
||||||
|
} catch (e: IOException) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
var moduleName: String? = null
|
var moduleName: String? = null
|
||||||
val requires = arrayListOf<Requires>()
|
val requires = arrayListOf<Requires>()
|
||||||
val exports = arrayListOf<Exports>()
|
val exports = arrayListOf<Exports>()
|
||||||
|
val annotations = arrayListOf<JavaAnnotation>()
|
||||||
|
|
||||||
try {
|
try {
|
||||||
ClassReader(contents).accept(object : ClassVisitor(Opcodes.API_VERSION) {
|
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)
|
}, ClassReader.SKIP_DEBUG or ClassReader.SKIP_CODE or ClassReader.SKIP_FRAMES)
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
throw IllegalStateException(
|
throw IllegalStateException(
|
||||||
@@ -86,9 +111,7 @@ class JavaModuleInfo(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
return if (moduleName != null)
|
return moduleName?.let { JavaModuleInfo(it, requires.compact(), exports.compact(), annotations) }
|
||||||
JavaModuleInfo(moduleName!!, requires.compact(), exports.compact())
|
|
||||||
else null
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-3
@@ -19,9 +19,10 @@ package org.jetbrains.kotlin.resolve.jvm.modules
|
|||||||
import com.intellij.openapi.components.ServiceManager
|
import com.intellij.openapi.components.ServiceManager
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
import com.intellij.openapi.vfs.VirtualFile
|
import com.intellij.openapi.vfs.VirtualFile
|
||||||
|
import org.jetbrains.kotlin.load.java.lazy.JavaModuleAnnotationsProvider
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
|
|
||||||
interface JavaModuleResolver {
|
interface JavaModuleResolver : JavaModuleAnnotationsProvider {
|
||||||
fun checkAccessibility(fileFromOurModule: VirtualFile?, referencedFile: VirtualFile, referencedPackage: FqName?): AccessError?
|
fun checkAccessibility(fileFromOurModule: VirtualFile?, referencedFile: VirtualFile, referencedPackage: FqName?): AccessError?
|
||||||
|
|
||||||
sealed class AccessError {
|
sealed class AccessError {
|
||||||
@@ -31,7 +32,6 @@ interface JavaModuleResolver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
companion object SERVICE {
|
companion object SERVICE {
|
||||||
fun getInstance(project: Project): JavaModuleResolver =
|
fun getInstance(project: Project): JavaModuleResolver = ServiceManager.getService(project, JavaModuleResolver::class.java)
|
||||||
ServiceManager.getService(project, JavaModuleResolver::class.java)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
@@ -20,9 +20,11 @@ import com.intellij.psi.impl.file.impl.JavaFileManager
|
|||||||
import com.intellij.psi.search.GlobalSearchScope
|
import com.intellij.psi.search.GlobalSearchScope
|
||||||
import org.jetbrains.kotlin.load.java.JavaClassFinder
|
import org.jetbrains.kotlin.load.java.JavaClassFinder
|
||||||
import org.jetbrains.kotlin.load.java.structure.JavaClass
|
import org.jetbrains.kotlin.load.java.structure.JavaClass
|
||||||
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
|
|
||||||
interface KotlinCliJavaFileManager : JavaFileManager {
|
interface KotlinCliJavaFileManager : JavaFileManager {
|
||||||
|
fun findClass(classId: ClassId): JavaClass?
|
||||||
fun findClass(request: JavaClassFinder.Request, searchScope: GlobalSearchScope): JavaClass?
|
fun findClass(request: JavaClassFinder.Request, searchScope: GlobalSearchScope): JavaClass?
|
||||||
fun knownClassNamesInPackage(packageFqName: FqName): Set<String>?
|
fun knownClassNamesInPackage(packageFqName: FqName): Set<String>?
|
||||||
}
|
}
|
||||||
|
|||||||
+13
@@ -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 settings: JavaResolverSettings,
|
||||||
val kotlinTypeChecker: NewKotlinTypeChecker,
|
val kotlinTypeChecker: NewKotlinTypeChecker,
|
||||||
val javaTypeEnhancementState: JavaTypeEnhancementState,
|
val javaTypeEnhancementState: JavaTypeEnhancementState,
|
||||||
|
val javaModuleResolver: JavaModuleAnnotationsProvider,
|
||||||
val syntheticPartsProvider: SyntheticJavaPartsProvider = SyntheticJavaPartsProvider.EMPTY
|
val syntheticPartsProvider: SyntheticJavaPartsProvider = SyntheticJavaPartsProvider.EMPTY
|
||||||
) {
|
) {
|
||||||
fun replace(
|
fun replace(
|
||||||
@@ -75,8 +76,7 @@ class JavaResolverComponents(
|
|||||||
javaPropertyInitializerEvaluator, samConversionResolver, sourceElementFactory,
|
javaPropertyInitializerEvaluator, samConversionResolver, sourceElementFactory,
|
||||||
moduleClassResolver, packagePartProvider, supertypeLoopChecker, lookupTracker, module, reflectionTypes,
|
moduleClassResolver, packagePartProvider, supertypeLoopChecker, lookupTracker, module, reflectionTypes,
|
||||||
annotationTypeQualifierResolver, signatureEnhancement, javaClassesTracker, settings,
|
annotationTypeQualifierResolver, signatureEnhancement, javaClassesTracker, settings,
|
||||||
kotlinTypeChecker,
|
kotlinTypeChecker, javaTypeEnhancementState, javaModuleResolver
|
||||||
javaTypeEnhancementState
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+6
-1
@@ -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.JavaResolverCache
|
||||||
import org.jetbrains.kotlin.load.java.components.SignaturePropagator
|
import org.jetbrains.kotlin.load.java.components.SignaturePropagator
|
||||||
import org.jetbrains.kotlin.load.java.lazy.*
|
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.JavaTypeEnhancement
|
||||||
import org.jetbrains.kotlin.load.java.typeEnhancement.SignatureEnhancement
|
import org.jetbrains.kotlin.load.java.typeEnhancement.SignatureEnhancement
|
||||||
import org.jetbrains.kotlin.load.kotlin.*
|
import org.jetbrains.kotlin.load.kotlin.*
|
||||||
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.resolve.jvm.JavaDescriptorResolver
|
import org.jetbrains.kotlin.resolve.jvm.JavaDescriptorResolver
|
||||||
import org.jetbrains.kotlin.resolve.sam.SamConversionResolverImpl
|
import org.jetbrains.kotlin.resolve.sam.SamConversionResolverImpl
|
||||||
@@ -119,7 +121,10 @@ fun makeLazyJavaPackageFragmentFromClassLoaderProvider(
|
|||||||
singleModuleClassResolver, packagePartProvider, SupertypeLoopChecker.EMPTY, LookupTracker.DO_NOTHING, module,
|
singleModuleClassResolver, packagePartProvider, SupertypeLoopChecker.EMPTY, LookupTracker.DO_NOTHING, module,
|
||||||
ReflectionTypes(module, notFoundClasses), annotationTypeQualifierResolver,
|
ReflectionTypes(module, notFoundClasses), annotationTypeQualifierResolver,
|
||||||
SignatureEnhancement(annotationTypeQualifierResolver, JavaTypeEnhancementState.DISABLED_JSR_305, JavaTypeEnhancement(JavaResolverSettings.Default)),
|
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)
|
return LazyJavaPackageFragmentProvider(javaResolverComponents)
|
||||||
|
|||||||
@@ -10,10 +10,24 @@ import com.intellij.openapi.project.Project
|
|||||||
import com.intellij.openapi.vfs.VirtualFile
|
import com.intellij.openapi.vfs.VirtualFile
|
||||||
import com.intellij.psi.PsiJavaModule
|
import com.intellij.psi.PsiJavaModule
|
||||||
import com.intellij.psi.impl.light.LightJavaModule
|
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.name.FqName
|
||||||
|
import org.jetbrains.kotlin.resolve.jvm.modules.JavaModule
|
||||||
import org.jetbrains.kotlin.resolve.jvm.modules.JavaModuleResolver
|
import org.jetbrains.kotlin.resolve.jvm.modules.JavaModuleResolver
|
||||||
|
|
||||||
class IdeJavaModuleResolver(private val project: Project) : 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)
|
private fun findJavaModule(file: VirtualFile): PsiJavaModule? = ModuleHighlightUtil2.getModuleDescriptor(file, project)
|
||||||
|
|
||||||
override fun checkAccessibility(
|
override fun checkAccessibility(
|
||||||
|
|||||||
@@ -32,6 +32,8 @@ class IDEVirtualFileFinder(private val scope: GlobalSearchScope) : VirtualFileFi
|
|||||||
override fun findBuiltInsData(packageFqName: FqName): InputStream? =
|
override fun findBuiltInsData(packageFqName: FqName): InputStream? =
|
||||||
findVirtualFileWithHeader(packageFqName, KotlinBuiltInsMetadataIndex.KEY)?.inputStream
|
findVirtualFileWithHeader(packageFqName, KotlinBuiltInsMetadataIndex.KEY)?.inputStream
|
||||||
|
|
||||||
|
override fun findSourceOrBinaryVirtualFile(classId: ClassId) = findVirtualFileWithHeader(classId)
|
||||||
|
|
||||||
init {
|
init {
|
||||||
if (scope != GlobalSearchScope.EMPTY_SCOPE && scope.project == null) {
|
if (scope != GlobalSearchScope.EMPTY_SCOPE && scope.project == null) {
|
||||||
LOG.warn("Scope with null project $scope")
|
LOG.warn("Scope with null project $scope")
|
||||||
|
|||||||
Reference in New Issue
Block a user