[FIR] Support of importing optional annotation classes (JS/Native), ^KT-51757 Fixed
This commit is contained in:
+23
-3
@@ -47,6 +47,7 @@ import org.jetbrains.kotlin.fir.extensions.predicate.DeclarationPredicate
|
||||
import org.jetbrains.kotlin.fir.java.FirJavaFacadeForSource
|
||||
import org.jetbrains.kotlin.fir.java.JavaSymbolProvider
|
||||
import org.jetbrains.kotlin.fir.java.deserialization.JvmClassFileBasedSymbolProvider
|
||||
import org.jetbrains.kotlin.fir.java.deserialization.OptionalAnnotationClassesProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.FirDependenciesSymbolProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.FirProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
|
||||
@@ -230,11 +231,12 @@ internal object LLFirSessionFactory {
|
||||
register(FirKotlinScopeProvider::class, kotlinScopeProvider)
|
||||
|
||||
val moduleDataProvider = createModuleDataProviderWithLibraryDependencies(sourceModule, this)
|
||||
val packagePartProvider = project.createPackagePartProviderForLibrary(searchScope)
|
||||
val classFileBasedSymbolProvider = JvmClassFileBasedSymbolProvider(
|
||||
this@session,
|
||||
moduleDataProvider = moduleDataProvider,
|
||||
kotlinScopeProvider = kotlinScopeProvider,
|
||||
packagePartProvider = project.createPackagePartProviderForLibrary(searchScope),
|
||||
packagePartProvider = packagePartProvider,
|
||||
kotlinClassFinder = VirtualFileFinderFactory.getInstance(project).create(searchScope),
|
||||
javaFacade = LLFirJavaFacadeForBinaries(
|
||||
this@session,
|
||||
@@ -243,8 +245,17 @@ internal object LLFirSessionFactory {
|
||||
moduleDataProvider
|
||||
)
|
||||
)
|
||||
val optionalAnnotationClassesProvider = OptionalAnnotationClassesProvider(
|
||||
this,
|
||||
moduleDataProvider,
|
||||
kotlinScopeProvider,
|
||||
packagePartProvider
|
||||
)
|
||||
val symbolProvider =
|
||||
FirCompositeSymbolProvider(this, listOf(classFileBasedSymbolProvider, builtinsAndCloneableSession.symbolProvider))
|
||||
FirCompositeSymbolProvider(
|
||||
this,
|
||||
listOf(classFileBasedSymbolProvider, optionalAnnotationClassesProvider, builtinsAndCloneableSession.symbolProvider)
|
||||
)
|
||||
register(FirProvider::class, LLFirLibrariesSessionProvider(symbolProvider))
|
||||
register(FirSymbolProvider::class, symbolProvider)
|
||||
register(FirJvmTypeMapper::class, FirJvmTypeMapper(this))
|
||||
@@ -374,6 +385,7 @@ internal object LLFirSessionFactory {
|
||||
val dependentProviders = buildList {
|
||||
val librariesSearchScope = ProjectScope.getLibrariesScope(project)
|
||||
.intersectWith(GlobalSearchScope.notScope(libraryModule.contentScope)) // <all libraries scope> - <current library scope>
|
||||
val packagePartProvider = project.createPackagePartProviderForLibrary(librariesSearchScope)
|
||||
add(builtinsAndCloneableSession.symbolProvider)
|
||||
val libraryDependenciesModuleDataProvider = createModuleDataProviderWithLibraryDependencies(module, this@session)
|
||||
add(
|
||||
@@ -381,7 +393,7 @@ internal object LLFirSessionFactory {
|
||||
this@session,
|
||||
moduleDataProvider = libraryDependenciesModuleDataProvider,
|
||||
kotlinScopeProvider = scopeProvider,
|
||||
packagePartProvider = project.createPackagePartProviderForLibrary(librariesSearchScope),
|
||||
packagePartProvider = packagePartProvider,
|
||||
kotlinClassFinder = VirtualFileFinderFactory.getInstance(project).create(librariesSearchScope),
|
||||
javaFacade = LLFirJavaFacadeForBinaries(
|
||||
this@session,
|
||||
@@ -391,6 +403,14 @@ internal object LLFirSessionFactory {
|
||||
)
|
||||
)
|
||||
)
|
||||
add(
|
||||
OptionalAnnotationClassesProvider(
|
||||
this@session,
|
||||
moduleDataProvider = libraryDependenciesModuleDataProvider,
|
||||
kotlinScopeProvider = scopeProvider,
|
||||
packagePartProvider = packagePartProvider,
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
// We need FirRegisteredPluginAnnotations during extensions' registration process
|
||||
|
||||
+6
@@ -13084,6 +13084,12 @@ public class DiagnosisCompilerTestFE10TestdataTestGenerated extends AbstractDiag
|
||||
runTest("compiler/testData/diagnostics/tests/imports/OperatorRenameOnImport.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("OptionalAnnotationClasses.kt")
|
||||
public void testOptionalAnnotationClasses() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/imports/OptionalAnnotationClasses.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("PackageLocalClassNotImported.kt")
|
||||
public void testPackageLocalClassNotImported() throws Exception {
|
||||
|
||||
+6
@@ -13084,6 +13084,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
|
||||
runTest("compiler/testData/diagnostics/tests/imports/OperatorRenameOnImport.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("OptionalAnnotationClasses.kt")
|
||||
public void testOptionalAnnotationClasses() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/imports/OptionalAnnotationClasses.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("PackageLocalClassNotImported.kt")
|
||||
public void testPackageLocalClassNotImported() throws Exception {
|
||||
|
||||
+6
@@ -13084,6 +13084,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac
|
||||
runTest("compiler/testData/diagnostics/tests/imports/OperatorRenameOnImport.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("OptionalAnnotationClasses.kt")
|
||||
public void testOptionalAnnotationClasses() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/imports/OptionalAnnotationClasses.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("PackageLocalClassNotImported.kt")
|
||||
public void testPackageLocalClassNotImported() throws Exception {
|
||||
|
||||
@@ -24,6 +24,7 @@ import org.jetbrains.kotlin.fir.java.FirCliSession
|
||||
import org.jetbrains.kotlin.fir.java.FirProjectSessionProvider
|
||||
import org.jetbrains.kotlin.fir.java.JavaSymbolProvider
|
||||
import org.jetbrains.kotlin.fir.java.deserialization.JvmClassFileBasedSymbolProvider
|
||||
import org.jetbrains.kotlin.fir.java.deserialization.OptionalAnnotationClassesProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.FirDependenciesSymbolProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.FirProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
|
||||
@@ -73,7 +74,7 @@ object FirSessionFactory {
|
||||
// (maybe easiest way to achieve is to delete libraries
|
||||
// TODO: consider passing something more abstract instead of precompiler component, in order to avoid file ops here
|
||||
val previousFirSessionsSymbolProviders: Collection<FirSymbolProvider>,
|
||||
val precomiledBinariesPackagePartProvider: PackagePartProvider?,
|
||||
val precompiledBinariesPackagePartProvider: PackagePartProvider?,
|
||||
val precompiledBinariesFileScope: AbstractProjectFileSearchScope?
|
||||
)
|
||||
|
||||
@@ -155,19 +156,31 @@ object FirSessionFactory {
|
||||
val firProvider = FirProviderImpl(this, kotlinScopeProvider)
|
||||
register(FirProvider::class, firProvider)
|
||||
|
||||
val symbolProviderForBinariesFromIncrementalCompilation =
|
||||
incrementalCompilationContext?.let { (_, precompiledBinariesPackagePartProvider, precompiledBinariesFileScope) ->
|
||||
if (precompiledBinariesPackagePartProvider == null || precompiledBinariesFileScope == null) null
|
||||
else JvmClassFileBasedSymbolProvider(
|
||||
this@session,
|
||||
SingleModuleDataProvider(moduleData),
|
||||
kotlinScopeProvider,
|
||||
precompiledBinariesPackagePartProvider,
|
||||
projectEnvironment.getKotlinClassFinder(precompiledBinariesFileScope),
|
||||
projectEnvironment.getFirJavaFacade(this, moduleData, precompiledBinariesFileScope),
|
||||
defaultDeserializationOrigin = FirDeclarationOrigin.Precompiled
|
||||
)
|
||||
var symbolProviderForBinariesFromIncrementalCompilation: JvmClassFileBasedSymbolProvider? = null
|
||||
var optionalAnnotationClassesProviderForBinariesFromIncrementalCompilation: OptionalAnnotationClassesProvider? = null
|
||||
incrementalCompilationContext?.let {
|
||||
if (it.precompiledBinariesPackagePartProvider != null && it.precompiledBinariesFileScope != null) {
|
||||
val moduleDataProvider = SingleModuleDataProvider(moduleData)
|
||||
symbolProviderForBinariesFromIncrementalCompilation =
|
||||
JvmClassFileBasedSymbolProvider(
|
||||
this@session,
|
||||
moduleDataProvider,
|
||||
kotlinScopeProvider,
|
||||
it.precompiledBinariesPackagePartProvider,
|
||||
projectEnvironment.getKotlinClassFinder(it.precompiledBinariesFileScope),
|
||||
projectEnvironment.getFirJavaFacade(this, moduleData, it.precompiledBinariesFileScope),
|
||||
defaultDeserializationOrigin = FirDeclarationOrigin.Precompiled
|
||||
)
|
||||
optionalAnnotationClassesProviderForBinariesFromIncrementalCompilation =
|
||||
OptionalAnnotationClassesProvider(
|
||||
this@session,
|
||||
moduleDataProvider,
|
||||
kotlinScopeProvider,
|
||||
it.precompiledBinariesPackagePartProvider,
|
||||
defaultDeserializationOrigin = FirDeclarationOrigin.Precompiled
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
FirSessionConfigurator(this).apply {
|
||||
registerCommonCheckers()
|
||||
@@ -188,6 +201,7 @@ object FirSessionFactory {
|
||||
firProvider.symbolProvider,
|
||||
*(incrementalCompilationContext?.previousFirSessionsSymbolProviders?.toTypedArray() ?: emptyArray()),
|
||||
symbolProviderForBinariesFromIncrementalCompilation,
|
||||
optionalAnnotationClassesProviderForBinariesFromIncrementalCompilation,
|
||||
generatedSymbolsProvider,
|
||||
JavaSymbolProvider(this, projectEnvironment.getFirJavaFacade(this, moduleData, javaSourcesScope)),
|
||||
dependenciesSymbolProvider,
|
||||
@@ -238,6 +252,13 @@ object FirSessionFactory {
|
||||
projectEnvironment.getFirJavaFacade(this, moduleDataProvider.allModuleData.last(), scope)
|
||||
)
|
||||
|
||||
val optionalAnnotationClassesProvider = OptionalAnnotationClassesProvider(
|
||||
this,
|
||||
moduleDataProvider,
|
||||
kotlinScopeProvider,
|
||||
packagePartProvider
|
||||
)
|
||||
|
||||
val builtinsModuleData = createModuleDataForBuiltins(
|
||||
mainModuleName,
|
||||
moduleDataProvider.platform,
|
||||
@@ -248,6 +269,7 @@ object FirSessionFactory {
|
||||
this,
|
||||
listOf(
|
||||
classFileBasedSymbolProvider,
|
||||
optionalAnnotationClassesProvider,
|
||||
FirBuiltinSymbolProvider(this, builtinsModuleData, kotlinScopeProvider),
|
||||
FirCloneableSymbolProvider(this, builtinsModuleData, kotlinScopeProvider),
|
||||
FirDependenciesSymbolProviderImpl(this)
|
||||
|
||||
+7
-6
@@ -6,6 +6,7 @@
|
||||
package org.jetbrains.kotlin.fir.deserialization
|
||||
|
||||
import com.intellij.openapi.progress.ProcessCanceledException
|
||||
import org.jetbrains.kotlin.fir.FirModuleData
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.caches.FirCache
|
||||
import org.jetbrains.kotlin.fir.caches.createCache
|
||||
@@ -107,10 +108,10 @@ abstract class AbstractFirDeserializedSymbolProvider(
|
||||
data class Metadata(
|
||||
val nameResolver: NameResolver,
|
||||
val classProto: ProtoBuf.Class,
|
||||
val annotationDeserializer: AbstractAnnotationDeserializer,
|
||||
val containingLibraryPath: Path?,
|
||||
val sourceElement: DeserializedContainerSource,
|
||||
val classPostProcessor: DeserializedClassPostProcessor
|
||||
val annotationDeserializer: AbstractAnnotationDeserializer?,
|
||||
val moduleData: FirModuleData?,
|
||||
val sourceElement: DeserializedContainerSource?,
|
||||
val classPostProcessor: DeserializedClassPostProcessor?
|
||||
) : ClassMetadataFindResult()
|
||||
}
|
||||
|
||||
@@ -138,8 +139,8 @@ abstract class AbstractFirDeserializedSymbolProvider(
|
||||
return when (val result = extractClassMetadata(classId, parentContext)) {
|
||||
is ClassMetadataFindResult.NoMetadata -> FirRegularClassSymbol(classId) to result.classPostProcessor
|
||||
is ClassMetadataFindResult.Metadata -> {
|
||||
val (nameResolver, classProto, annotationDeserializer, containingLibrary, sourceElement, postProcessor) = result
|
||||
val moduleData = moduleDataProvider.getModuleData(containingLibrary) ?: return null to null
|
||||
val (nameResolver, classProto, annotationDeserializer, moduleData, sourceElement, postProcessor) = result
|
||||
moduleData ?: return null to null
|
||||
val symbol = FirRegularClassSymbol(classId)
|
||||
deserializeClassToSymbol(
|
||||
classId,
|
||||
|
||||
+2
-2
@@ -27,7 +27,7 @@ import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmProtoBufUtil
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
|
||||
import org.jetbrains.kotlin.serialization.deserialization.IncompatibleVersionErrorData
|
||||
import org.jetbrains.kotlin.serialization.deserialization.*
|
||||
import java.nio.file.Path
|
||||
import java.nio.file.Paths
|
||||
|
||||
@@ -132,7 +132,7 @@ class JvmClassFileBasedSymbolProvider(
|
||||
nameResolver,
|
||||
classProto,
|
||||
JvmBinaryAnnotationDeserializer(session, kotlinClass, kotlinClassFinder, result.byteContent),
|
||||
kotlinClass.containingLibrary.toPath(),
|
||||
moduleDataProvider.getModuleData(kotlinClass.containingLibrary?.toPath()),
|
||||
KotlinJvmBinarySourceElement(kotlinClass),
|
||||
classPostProcessor = { loadAnnotationsFromClassFile(result, it) }
|
||||
)
|
||||
|
||||
+73
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright 2010-2022 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.fir.java.deserialization
|
||||
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin
|
||||
import org.jetbrains.kotlin.fir.deserialization.AbstractFirDeserializedSymbolProvider
|
||||
import org.jetbrains.kotlin.fir.deserialization.FirDeserializationContext
|
||||
import org.jetbrains.kotlin.fir.deserialization.ModuleDataProvider
|
||||
import org.jetbrains.kotlin.fir.deserialization.PackagePartsCacheData
|
||||
import org.jetbrains.kotlin.fir.scopes.FirKotlinScopeProvider
|
||||
import org.jetbrains.kotlin.load.kotlin.PackagePartProvider
|
||||
import org.jetbrains.kotlin.metadata.ProtoBuf
|
||||
import org.jetbrains.kotlin.metadata.jvm.JvmProtoBuf
|
||||
import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmFlags
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.serialization.deserialization.ClassData
|
||||
import org.jetbrains.kotlin.serialization.deserialization.getClassId
|
||||
|
||||
class OptionalAnnotationClassesProvider(
|
||||
session: FirSession,
|
||||
moduleDataProvider: ModuleDataProvider,
|
||||
kotlinScopeProvider: FirKotlinScopeProvider,
|
||||
packagePartProvider: PackagePartProvider,
|
||||
defaultDeserializationOrigin: FirDeclarationOrigin = FirDeclarationOrigin.Library
|
||||
) : AbstractFirDeserializedSymbolProvider(session, moduleDataProvider, kotlinScopeProvider, defaultDeserializationOrigin) {
|
||||
private val optionalAnnotationClasses: Map<ClassId, ClassData>
|
||||
private val optionalAnnotationPackages: Set<FqName>
|
||||
|
||||
init {
|
||||
val optionalAnnotationClasses = mutableMapOf<ClassId, ClassData>()
|
||||
val optionalAnnotationPackages = mutableSetOf<FqName>()
|
||||
|
||||
for (klass in packagePartProvider.getAllOptionalAnnotationClasses()) {
|
||||
val classId = klass.nameResolver.getClassId(klass.classProto.fqName)
|
||||
optionalAnnotationClasses[classId] = klass
|
||||
optionalAnnotationPackages.add(classId.packageFqName)
|
||||
}
|
||||
|
||||
this.optionalAnnotationClasses = optionalAnnotationClasses
|
||||
this.optionalAnnotationPackages = optionalAnnotationPackages
|
||||
}
|
||||
|
||||
override fun computePackagePartsInfos(packageFqName: FqName): List<PackagePartsCacheData> {
|
||||
return emptyList()
|
||||
}
|
||||
|
||||
override fun extractClassMetadata(
|
||||
classId: ClassId,
|
||||
parentContext: FirDeserializationContext?
|
||||
): ClassMetadataFindResult? {
|
||||
val optionalAnnotationClass = optionalAnnotationClasses[classId] ?: return null
|
||||
|
||||
return ClassMetadataFindResult.Metadata(
|
||||
optionalAnnotationClass.nameResolver,
|
||||
optionalAnnotationClass.classProto,
|
||||
null,
|
||||
moduleDataProvider.allModuleData.last(),
|
||||
null,
|
||||
classPostProcessor = null
|
||||
)
|
||||
}
|
||||
|
||||
override fun isNewPlaceForBodyGeneration(classProto: ProtoBuf.Class): Boolean {
|
||||
return JvmFlags.IS_COMPILED_IN_JVM_DEFAULT_MODE.get(classProto.getExtension(JvmProtoBuf.jvmClassFlags))
|
||||
}
|
||||
|
||||
override fun getPackage(fqName: FqName): FqName? = if (optionalAnnotationPackages.contains(fqName)) fqName else null
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
// FIR_IDENTICAL
|
||||
// WITH_STDLIB
|
||||
|
||||
@file:Suppress("OPTIONAL_DECLARATION_USAGE_IN_NON_COMMON_SOURCE")
|
||||
|
||||
import kotlin.js.*
|
||||
import kotlin.native.concurrent.*
|
||||
|
||||
@JsName("")
|
||||
public fun test() {}
|
||||
|
||||
@SharedImmutable
|
||||
private val EmptyArray: Array<Int> = arrayOf()
|
||||
@@ -0,0 +1,4 @@
|
||||
package
|
||||
|
||||
@kotlin.native.concurrent.SharedImmutable private val EmptyArray: kotlin.Array<kotlin.Int>
|
||||
@kotlin.js.JsName(name = "") public fun test(): kotlin.Unit
|
||||
Generated
+6
@@ -13090,6 +13090,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
|
||||
runTest("compiler/testData/diagnostics/tests/imports/OperatorRenameOnImport.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("OptionalAnnotationClasses.kt")
|
||||
public void testOptionalAnnotationClasses() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/imports/OptionalAnnotationClasses.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("PackageLocalClassNotImported.kt")
|
||||
public void testPackageLocalClassNotImported() throws Exception {
|
||||
|
||||
Reference in New Issue
Block a user