From 30c8fa89f67c65f9a93f362c45e649aaec5090af Mon Sep 17 00:00:00 2001 From: pyos Date: Mon, 13 Sep 2021 14:21:32 +0200 Subject: [PATCH] FIR: rename JavaSymbolProvider to JavaClassConverter --- .../FirRepeatableAnnotationChecker.kt | 4 +- .../AbstractFirDeserializedSymbolsProvider.kt | 2 +- ...ymbolProvider.kt => JavaClassConverter.kt} | 53 +++++++++---------- .../jetbrains/kotlin/fir/java/JavaUtils.kt | 2 +- .../KotlinDeserializedJvmSymbolsProvider.kt | 23 ++++---- 5 files changed, 43 insertions(+), 41 deletions(-) rename compiler/fir/java/src/org/jetbrains/kotlin/fir/java/{JavaSymbolProvider.kt => JavaClassConverter.kt} (93%) diff --git a/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/declaration/FirRepeatableAnnotationChecker.kt b/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/declaration/FirRepeatableAnnotationChecker.kt index fceaf2afb0b..9632bb23ea8 100644 --- a/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/declaration/FirRepeatableAnnotationChecker.kt +++ b/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/declaration/FirRepeatableAnnotationChecker.kt @@ -21,7 +21,7 @@ import org.jetbrains.kotlin.fir.analysis.jvm.checkers.isJvm6 import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.utils.classId import org.jetbrains.kotlin.fir.expressions.* -import org.jetbrains.kotlin.fir.java.JavaSymbolProvider +import org.jetbrains.kotlin.fir.java.JavaClassConverter import org.jetbrains.kotlin.fir.languageVersionSettings import org.jetbrains.kotlin.fir.resolve.defaultType import org.jetbrains.kotlin.fir.resolve.symbolProvider @@ -166,7 +166,7 @@ object FirRepeatableAnnotationChecker : FirAnnotatedDeclarationChecker() { ?: return val valueParameterSymbols = containerCtor.valueParameterSymbols - val parameterName = JavaSymbolProvider.VALUE_METHOD_NAME + val parameterName = JavaClassConverter.VALUE_METHOD_NAME val value = valueParameterSymbols.find { it.name == parameterName } if (value == null || !value.resolvedReturnTypeRef.isArrayType || value.resolvedReturnTypeRef.type.typeArguments.single().type != annotationClass.defaultType() diff --git a/compiler/fir/fir-deserialization/src/org/jetbrains/kotlin/fir/deserialization/AbstractFirDeserializedSymbolsProvider.kt b/compiler/fir/fir-deserialization/src/org/jetbrains/kotlin/fir/deserialization/AbstractFirDeserializedSymbolsProvider.kt index cc13f8163e7..1b9665fa83c 100644 --- a/compiler/fir/fir-deserialization/src/org/jetbrains/kotlin/fir/deserialization/AbstractFirDeserializedSymbolsProvider.kt +++ b/compiler/fir/fir-deserialization/src/org/jetbrains/kotlin/fir/deserialization/AbstractFirDeserializedSymbolsProvider.kt @@ -187,7 +187,7 @@ abstract class AbstractFirDeserializedSymbolsProvider( protected open fun shouldLoadParentsFirst(classId: ClassId): Boolean = false - protected open fun getClass( + protected fun getClass( classId: ClassId, parentContext: FirDeserializationContext? = null ): FirRegularClassSymbol? { diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaSymbolProvider.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaClassConverter.kt similarity index 93% rename from compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaSymbolProvider.kt rename to compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaClassConverter.kt index 4e4df93a91c..bfba24f4ec4 100644 --- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaSymbolProvider.kt +++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaClassConverter.kt @@ -47,28 +47,32 @@ import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.types.Variance.INVARIANT import org.jetbrains.kotlin.util.OperatorNameConventions +// This symbol provider only loads JVM classes *not* annotated with Kotlin `@Metadata` annotation. +// Use it in application sessions for loading classes from Java files listed on the command line. +// For library and incremental compilation sessions use `KotlinDeserializedJvmSymbolsProvider` +// in order to load Kotlin classes as well. class JavaSymbolProviderWrapper(session: FirSession, baseModuleData: FirModuleData, facade: JavaClassFinder) : FirSymbolProvider(session) { - private val javaSymbolProvider = JavaSymbolProvider(session, baseModuleData, facade) + private val javaClassConverter = JavaClassConverter(session, baseModuleData, facade) private val classCache = session.firCachesFactory.createCacheWithPostCompute( createValue = { classId: ClassId, parentClassSymbol: FirRegularClassSymbol? -> - javaSymbolProvider.findClass(classId)?.let { FirRegularClassSymbol(classId) to (it to parentClassSymbol) } + javaClassConverter.findClass(classId)?.let { FirRegularClassSymbol(classId) to (it to parentClassSymbol) } ?: null to (null to null) }, postCompute = { _, classSymbol, (javaClass, parentClassSymbol) -> if (classSymbol != null && javaClass != null) { - javaSymbolProvider.convertJavaClassToFir(classSymbol, parentClassSymbol, javaClass) + javaClassConverter.convertJavaClassToFir(classSymbol, parentClassSymbol, javaClass) } } ) override fun getPackage(fqName: FqName): FqName? = - javaSymbolProvider.getPackage(fqName) + javaClassConverter.getPackage(fqName) override fun getClassLikeSymbolByClassId(classId: ClassId): FirRegularClassSymbol? = try { - if (javaSymbolProvider.hasTopLevelClassOf(classId)) getFirJavaClass(classId) else null + if (javaClassConverter.hasTopLevelClassOf(classId)) getFirJavaClass(classId) else null } catch (e: ProcessCanceledException) { null } @@ -87,7 +91,7 @@ class JavaSymbolProviderWrapper(session: FirSession, baseModuleData: FirModuleDa } @ThreadSafeMutableState -class JavaSymbolProvider( +class JavaClassConverter( private val session: FirSession, private val baseModuleData: FirModuleData, private val facade: JavaClassFinder @@ -104,7 +108,7 @@ class JavaSymbolProvider( fun findClass(classId: ClassId, knownContent: ByteArray? = null): JavaClass? = facade.findClass(JavaClassFinder.Request(classId, knownContent)) - ?.takeIf { !it.hasDifferentClassId(classId) && !it.hasMetadataAnnotation() } + ?.takeIf { it.classId == classId && !it.hasMetadataAnnotation() } fun getPackage(fqName: FqName): FqName? = try { @@ -120,7 +124,7 @@ class JavaSymbolProvider( private fun JavaTypeParameter.toFirTypeParameter(javaTypeParameterStack: JavaTypeParameterStack): FirTypeParameter { return buildTypeParameter { - moduleData = this@JavaSymbolProvider.baseModuleData + moduleData = baseModuleData origin = FirDeclarationOrigin.Java resolvePhase = FirResolvePhase.ANALYZED_DEPENDENCIES name = this@toFirTypeParameter.name @@ -145,9 +149,6 @@ class JavaSymbolProvider( private fun List.convertTypeParameters(stack: JavaTypeParameterStack): List = map { it.toFirTypeParameter(stack) } - private fun JavaClass.hasDifferentClassId(lookupClassId: ClassId): Boolean = - classId != lookupClassId - private fun JavaClass.hasMetadataAnnotation(): Boolean = annotations.any { it.classId?.asSingleFqName() == JvmAnnotationNames.METADATA_FQ_NAME } @@ -203,7 +204,7 @@ class JavaSymbolProvider( val classIsAnnotation = javaClass.classKind == ClassKind.ANNOTATION_CLASS return buildJavaClass { source = (javaClass as? JavaElementImpl<*>)?.psi?.toFirPsiSourceElement() - moduleData = this@JavaSymbolProvider.baseModuleData + moduleData = baseModuleData symbol = classSymbol name = javaClass.name val visibility = javaClass.visibility @@ -348,7 +349,7 @@ class JavaSymbolProvider( return when { javaField.isEnumEntry -> buildEnumEntry { source = (javaField as? JavaElementImpl<*>)?.psi?.toFirPsiSourceElement() - moduleData = this@JavaSymbolProvider.baseModuleData + moduleData = baseModuleData symbol = FirEnumEntrySymbol(fieldId) name = fieldName status = FirResolvedDeclarationStatusImpl( @@ -361,17 +362,17 @@ class JavaSymbolProvider( isActual = false isOverride = false } - returnTypeRef = returnType.toFirJavaTypeRef(this@JavaSymbolProvider.session, javaTypeParameterStack) + returnTypeRef = returnType.toFirJavaTypeRef(session, javaTypeParameterStack) resolvePhase = FirResolvePhase.ANALYZED_DEPENDENCIES origin = FirDeclarationOrigin.Java // TODO: check if this works properly with annotations that take the enum class as an argument - annotations.addFromJava(this@JavaSymbolProvider.session, javaField, javaTypeParameterStack) + annotations.addFromJava(session, javaField, javaTypeParameterStack) }.apply { containingClassForStaticMemberAttr = ConeClassLikeLookupTagImpl(classId) } else -> buildJavaField { source = (javaField as? JavaElementImpl<*>)?.psi?.toFirPsiSourceElement() - moduleData = this@JavaSymbolProvider.baseModuleData + moduleData = baseModuleData symbol = FirFieldSymbol(fieldId) name = fieldName status = FirResolvedDeclarationStatusImpl( @@ -386,7 +387,7 @@ class JavaSymbolProvider( } visibility = javaField.visibility modality = javaField.modality - returnTypeRef = returnType.toFirJavaTypeRef(this@JavaSymbolProvider.session, javaTypeParameterStack) + returnTypeRef = returnType.toFirJavaTypeRef(session, javaTypeParameterStack) isVar = !javaField.isFinal isStatic = javaField.isStatic annotationBuilder = { javaField.convertAnnotationsToFir(session, javaTypeParameterStack) } @@ -419,17 +420,15 @@ class JavaSymbolProvider( val methodSymbol = FirNamedFunctionSymbol(methodId) val returnType = javaMethod.returnType return buildJavaMethod { - moduleData = this@JavaSymbolProvider.baseModuleData + moduleData = baseModuleData source = (javaMethod as? JavaElementImpl<*>)?.psi?.toFirPsiSourceElement() symbol = methodSymbol name = methodName - returnTypeRef = returnType.toFirJavaTypeRef(this@JavaSymbolProvider.session, javaTypeParameterStack) + returnTypeRef = returnType.toFirJavaTypeRef(session, javaTypeParameterStack) isStatic = javaMethod.isStatic typeParameters += javaMethod.typeParameters.convertTypeParameters(javaTypeParameterStack) for ((index, valueParameter) in javaMethod.valueParameters.withIndex()) { - valueParameters += valueParameter.toFirValueParameter( - this@JavaSymbolProvider.session, moduleData, index, javaTypeParameterStack, - ) + valueParameters += valueParameter.toFirValueParameter(session, moduleData, index, javaTypeParameterStack) } annotationBuilder = { javaMethod.convertAnnotationsToFir(session, javaTypeParameterStack) } status = FirResolvedDeclarationStatusImpl( @@ -465,7 +464,7 @@ class JavaSymbolProvider( buildJavaValueParameter { source = (javaMethod as? JavaElementImpl<*>)?.psi ?.toFirPsiSourceElement(FirFakeSourceElementKind.ImplicitJavaAnnotationConstructor) - moduleData = this@JavaSymbolProvider.baseModuleData + moduleData = baseModuleData returnTypeRef = firJavaMethod.returnTypeRef name = javaMethod.name isVararg = javaMethod.returnType is JavaArrayType && javaMethod.name == VALUE_METHOD_NAME @@ -483,7 +482,7 @@ class JavaSymbolProvider( val constructorSymbol = FirConstructorSymbol(constructorId) return buildJavaConstructor { source = (javaConstructor as? JavaElementImpl<*>)?.psi?.toFirPsiSourceElement() - moduleData = this@JavaSymbolProvider.baseModuleData + moduleData = baseModuleData symbol = constructorSymbol isInner = javaClass.outerClass != null && !javaClass.isStatic val isThisInner = this.isInner @@ -509,9 +508,7 @@ class JavaSymbolProvider( this.typeParameters += javaConstructor.typeParameters.convertTypeParameters(javaTypeParameterStack) annotationBuilder = { javaConstructor.convertAnnotationsToFir(session, javaTypeParameterStack) } for ((index, valueParameter) in javaConstructor.valueParameters.withIndex()) { - valueParameters += valueParameter.toFirValueParameter( - this@JavaSymbolProvider.session, moduleData, index, javaTypeParameterStack, - ) + valueParameters += valueParameter.toFirValueParameter(session, moduleData, index, javaTypeParameterStack) } } else { annotationBuilder = { emptyList() } @@ -529,7 +526,7 @@ class JavaSymbolProvider( ): FirJavaConstructor { return buildJavaConstructor { source = classSource - moduleData = this@JavaSymbolProvider.baseModuleData + moduleData = baseModuleData symbol = FirConstructorSymbol(constructorId) status = FirResolvedDeclarationStatusImpl(Visibilities.Public, Modality.FINAL, EffectiveVisibility.Public) returnTypeRef = buildResolvedTypeRef { diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaUtils.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaUtils.kt index 1312b6e257a..8afb6404138 100644 --- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaUtils.kt +++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaUtils.kt @@ -152,7 +152,7 @@ private fun fillAnnotationArgumentMapping( ?.declarations ?.firstIsInstanceOrNull() annotationArguments.associateTo(destination) { argument -> - val name = argument.name ?: JavaSymbolProvider.VALUE_METHOD_NAME + val name = argument.name ?: JavaClassConverter.VALUE_METHOD_NAME val parameter = annotationConstructor?.valueParameters?.find { it.name == name } name to argument.toFirExpression(session, javaTypeParameterStack, parameter?.returnTypeRef) } diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/deserialization/KotlinDeserializedJvmSymbolsProvider.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/deserialization/KotlinDeserializedJvmSymbolsProvider.kt index bc44dce1286..65afaefc057 100644 --- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/deserialization/KotlinDeserializedJvmSymbolsProvider.kt +++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/deserialization/KotlinDeserializedJvmSymbolsProvider.kt @@ -12,7 +12,7 @@ import org.jetbrains.kotlin.fir.ThreadSafeMutableState import org.jetbrains.kotlin.fir.declarations.getDeprecationInfos import org.jetbrains.kotlin.fir.deserialization.* import org.jetbrains.kotlin.fir.expressions.FirAnnotation -import org.jetbrains.kotlin.fir.java.JavaSymbolProvider +import org.jetbrains.kotlin.fir.java.JavaClassConverter import org.jetbrains.kotlin.fir.languageVersionSettings import org.jetbrains.kotlin.fir.scopes.FirKotlinScopeProvider import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol @@ -31,8 +31,11 @@ import org.jetbrains.kotlin.serialization.deserialization.IncompatibleVersionErr import java.nio.file.Path import java.nio.file.Paths +// This symbol provider loads JVM classes, reading extra info from Kotlin `@Metadata` annotations +// if present. Use it for library and incremental compilation sessions. For source sessions use +// `JavaSymbolProviderWrapper`, as Kotlin classes should be parsed first. @ThreadSafeMutableState -open class KotlinDeserializedJvmSymbolsProvider( +class KotlinDeserializedJvmSymbolsProvider( session: FirSession, moduleDataProvider: ModuleDataProvider, kotlinScopeProvider: FirKotlinScopeProvider, @@ -40,13 +43,13 @@ open class KotlinDeserializedJvmSymbolsProvider( private val kotlinClassFinder: KotlinClassFinder, javaClassFinder: JavaClassFinder ) : AbstractFirDeserializedSymbolsProvider(session, moduleDataProvider, kotlinScopeProvider) { - private val javaSymbolProvider = JavaSymbolProvider(session, moduleDataProvider.allModuleData.last(), javaClassFinder) + private val javaClassConverter = JavaClassConverter(session, moduleDataProvider.allModuleData.last(), javaClassFinder) private val annotationsLoader = AnnotationsLoader(session, kotlinClassFinder) override fun computePackagePartsInfos(packageFqName: FqName): List { return packagePartProvider.findPackageParts(packageFqName.asString()).mapNotNull { partName -> val classId = ClassId.topLevel(JvmClassName.byInternalName(partName).fqNameForTopLevelClassMaybeWithDollars) - if (!javaSymbolProvider.hasTopLevelClassOf(classId)) return@mapNotNull null + if (!javaClassConverter.hasTopLevelClassOf(classId)) return@mapNotNull null val (kotlinJvmBinaryClass, byteContent) = kotlinClassFinder.findKotlinClassOrContent(classId) as? KotlinClassFinder.Result.KotlinClass ?: return@mapNotNull null @@ -89,10 +92,12 @@ open class KotlinDeserializedJvmSymbolsProvider( get() = classHeader.isPreRelease override fun shouldLoadParentsFirst(classId: ClassId): Boolean = - javaSymbolProvider.hasTopLevelClassOf(classId) + javaClassConverter.hasTopLevelClassOf(classId) override fun extractClassMetadata(classId: ClassId, parentContext: FirDeserializationContext?): ClassMetadataFindResult? { - if (!javaSymbolProvider.hasTopLevelClassOf(classId)) return null + // Kotlin classes are annotated Java classes, so this check also looks for them. + if (!javaClassConverter.hasTopLevelClassOf(classId)) return null + val result = try { kotlinClassFinder.findKotlinClassOrContent(classId) } catch (e: ProcessCanceledException) { @@ -102,12 +107,12 @@ open class KotlinDeserializedJvmSymbolsProvider( is KotlinClassFinder.Result.KotlinClass -> result is KotlinClassFinder.Result.ClassFileContent -> { val javaClass = try { - javaSymbolProvider.findClass(classId, result.content) ?: return null + javaClassConverter.findClass(classId, result.content) ?: return null } catch (e: ProcessCanceledException) { return null } return ClassMetadataFindResult.NoMetadata { symbol -> - javaSymbolProvider.convertJavaClassToFir(symbol, classId.outerClassId?.let(::getClass), javaClass) + javaClassConverter.convertJavaClassToFir(symbol, classId.outerClassId?.let(::getClass), javaClass) } } null -> return ClassMetadataFindResult.ShouldDeserializeViaParent @@ -130,7 +135,7 @@ open class KotlinDeserializedJvmSymbolsProvider( } override fun getPackage(fqName: FqName): FqName? = - javaSymbolProvider.getPackage(fqName) + javaClassConverter.getPackage(fqName) private fun loadAnnotationsFromClassFile( kotlinClass: KotlinClassFinder.Result.KotlinClass,