[FIR2IR] Extract special symbol provider to make JVM extension

This commit is contained in:
Mikhail Glukhikh
2020-11-10 11:26:39 +03:00
parent bc47a30dd3
commit d4f08018ce
7 changed files with 94 additions and 38 deletions
@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.fir.analysis.collectors.FirDiagnosticsCollector
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnostic
import org.jetbrains.kotlin.fir.backend.Fir2IrConverter
import org.jetbrains.kotlin.fir.backend.Fir2IrResult
import org.jetbrains.kotlin.fir.backend.jvm.Fir2IrJvmSpecialAnnotationSymbolProvider
import org.jetbrains.kotlin.fir.backend.jvm.FirJvmKotlinMangler
import org.jetbrains.kotlin.fir.backend.jvm.FirJvmVisibilityConverter
import org.jetbrains.kotlin.fir.builder.RawFirBuilder
@@ -71,7 +72,8 @@ class FirAnalyzerFacade(val session: FirSession, val languageVersionSettings: La
session, scopeSession!!, firFiles!!,
languageVersionSettings, signaturer,
JvmGeneratorExtensions(generateFacades), FirJvmKotlinMangler(session), IrFactoryImpl,
FirJvmVisibilityConverter
FirJvmVisibilityConverter,
Fir2IrJvmSpecialAnnotationSymbolProvider()
)
}
}
@@ -0,0 +1,45 @@
/*
* Copyright 2010-2020 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.backend.jvm
import org.jetbrains.kotlin.backend.common.ir.createImplicitParameterDeclarationWithWrappedDescriptor
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.fir.backend.Fir2IrSpecialSymbolProvider
import org.jetbrains.kotlin.ir.builders.declarations.addConstructor
import org.jetbrains.kotlin.ir.builders.declarations.buildClass
import org.jetbrains.kotlin.ir.declarations.impl.IrExternalPackageFragmentImpl
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
import org.jetbrains.kotlin.ir.symbols.impl.DescriptorlessExternalPackageFragmentSymbol
import org.jetbrains.kotlin.load.java.JvmAnnotationNames
import org.jetbrains.kotlin.name.ClassId
class Fir2IrJvmSpecialAnnotationSymbolProvider : Fir2IrSpecialSymbolProvider() {
private val kotlinJvmInternalPackage by lazy {
IrExternalPackageFragmentImpl(
DescriptorlessExternalPackageFragmentSymbol(),
ENHANCED_NULLABILITY_ID.packageFqName
)
}
override fun getClassSymbolById(id: ClassId): IrClassSymbol? {
if (id != ENHANCED_NULLABILITY_ID) return null
return components.irFactory.buildClass {
kind = ClassKind.ANNOTATION_CLASS
name = ENHANCED_NULLABILITY_ID.shortClassName
}.apply {
createImplicitParameterDeclarationWithWrappedDescriptor()
this.parent = kotlinJvmInternalPackage
addConstructor {
isPrimary = true
}
}.symbol
}
companion object {
private val ENHANCED_NULLABILITY_ID = ClassId.topLevel(JvmAnnotationNames.ENHANCED_NULLABILITY_ANNOTATION)
}
}
@@ -5,55 +5,42 @@
package org.jetbrains.kotlin.fir.backend
import org.jetbrains.kotlin.backend.common.ir.createImplicitParameterDeclarationWithWrappedDescriptor
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.fir.resolve.firSymbolProvider
import org.jetbrains.kotlin.fir.types.CompilerConeAttributes
import org.jetbrains.kotlin.ir.builders.declarations.addConstructor
import org.jetbrains.kotlin.ir.builders.declarations.buildClass
import org.jetbrains.kotlin.ir.declarations.IrConstructor
import org.jetbrains.kotlin.ir.declarations.impl.IrExternalPackageFragmentImpl
import org.jetbrains.kotlin.ir.expressions.IrConstructorCall
import org.jetbrains.kotlin.ir.expressions.impl.IrConstructorCallImpl
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
import org.jetbrains.kotlin.ir.symbols.impl.DescriptorlessExternalPackageFragmentSymbol
import org.jetbrains.kotlin.ir.types.defaultType
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstance
class Fir2IrBuiltIns(private val components: Fir2IrComponents) : Fir2IrComponents by components {
class Fir2IrBuiltIns(
private val components: Fir2IrComponents,
private val provider: Fir2IrSpecialSymbolProvider?
) : Fir2IrComponents by components {
init {
provider?.initComponents(components)
}
private val extensionFunctionTypeAnnotationSymbol by lazy {
annotationSymbolById(CompilerConeAttributes.ExtensionFunctionType.ANNOTATION_CLASS_ID)
}
internal fun extensionFunctionTypeAnnotationConstructorCall() =
extensionFunctionTypeAnnotationSymbol.toConstructorCall()
private val kotlinJvmInternalPackage =
IrExternalPackageFragmentImpl(
DescriptorlessExternalPackageFragmentSymbol(),
CompilerConeAttributes.EnhancedNullability.ANNOTATION_CLASS_ID.packageFqName
)
internal fun extensionFunctionTypeAnnotationConstructorCall(): IrConstructorCall =
extensionFunctionTypeAnnotationSymbol!!.toConstructorCall()
private val enhancedNullabilityAnnotationSymbol by lazy {
irFactory.buildClass {
kind = ClassKind.ANNOTATION_CLASS
name = CompilerConeAttributes.EnhancedNullability.ANNOTATION_CLASS_ID.shortClassName
}.apply {
createImplicitParameterDeclarationWithWrappedDescriptor()
this.parent = kotlinJvmInternalPackage
addConstructor {
isPrimary = true
}
}.symbol
annotationSymbolById(CompilerConeAttributes.EnhancedNullability.ANNOTATION_CLASS_ID)
}
internal fun enhancedNullabilityAnnotationConstructorCall() =
enhancedNullabilityAnnotationSymbol.toConstructorCall()
internal fun enhancedNullabilityAnnotationConstructorCall(): IrConstructorCall? =
enhancedNullabilityAnnotationSymbol?.toConstructorCall()
private fun annotationSymbolById(id: ClassId): IrClassSymbol =
session.firSymbolProvider.getClassLikeSymbolByFqName(id)!!.toSymbol(
private fun annotationSymbolById(id: ClassId): IrClassSymbol? =
provider?.getClassSymbolById(id) ?: session.firSymbolProvider.getClassLikeSymbolByFqName(id)?.toSymbol(
session, classifierStorage, ConversionTypeContext.DEFAULT
) as IrClassSymbol
) as? IrClassSymbol
private fun IrClassSymbol.toConstructorCall(): IrConstructorCallImpl =
IrConstructorCallImpl.fromSymbolOwner(defaultType, owner.declarations.firstIsInstance<IrConstructor>().symbol)
@@ -251,7 +251,8 @@ class Fir2IrConverter(
generatorExtensions: GeneratorExtensions,
mangler: FirMangler,
irFactory: IrFactory,
visibilityConverter: Fir2IrVisibilityConverter
visibilityConverter: Fir2IrVisibilityConverter,
specialSymbolProvider: Fir2IrSpecialSymbolProvider?
): Fir2IrResult {
val moduleDescriptor = FirModuleDescriptor(session)
val symbolTable = SymbolTable(signaturer, irFactory)
@@ -274,7 +275,7 @@ class Fir2IrConverter(
val fir2irVisitor = Fir2IrVisitor(converter, components, conversionScope)
val declarationStorage = Fir2IrDeclarationStorage(components, fir2irVisitor, moduleDescriptor)
val typeConverter = Fir2IrTypeConverter(components)
val builtIns = Fir2IrBuiltIns(components)
val builtIns = Fir2IrBuiltIns(components, specialSymbolProvider)
components.declarationStorage = declarationStorage
components.classifierStorage = classifierStorage
components.typeConverter = typeConverter
@@ -0,0 +1,19 @@
/*
* Copyright 2010-2020 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.backend
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
import org.jetbrains.kotlin.name.ClassId
abstract class Fir2IrSpecialSymbolProvider {
protected lateinit var components: Fir2IrComponents
fun initComponents(components: Fir2IrComponents) {
this.components = components
}
abstract fun getClassSymbolById(id: ClassId): IrClassSymbol?
}
@@ -91,7 +91,9 @@ class Fir2IrTypeConverter(
else mutableListOf(builtIns.extensionFunctionTypeAnnotationConstructorCall())
typeAnnotations += with(annotationGenerator) { annotations.toIrAnnotations() }
if (hasEnhancedNullability) {
typeAnnotations += builtIns.enhancedNullabilityAnnotationConstructorCall()
builtIns.enhancedNullabilityAnnotationConstructorCall()?.let {
typeAnnotations += it
}
}
IrSimpleTypeImpl(
irSymbol, !typeContext.definitelyNotNull && this.isMarkedNullable,
+4 -4
View File
@@ -22,9 +22,9 @@ FILE fqName:<root> fileName:/kt43217.kt
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun get (): kotlin.Double [operator] declared in <root>.A.b.<no name provided>'
CONST Double type=kotlin.Double value=0.0
FUN FAKE_OVERRIDE name:isEqualTo visibility:public modality:OPEN <> ($this:<root>.DoubleExpression, value:kotlin.Double) returnType:kotlin.Any [fake_override]
FUN FAKE_OVERRIDE name:isEqualTo visibility:public modality:OPEN <> ($this:<root>.DoubleExpression, value:kotlin.Double) returnType:@[EnhancedNullability] kotlin.Any [fake_override]
overridden:
public open fun isEqualTo (value: kotlin.Double): kotlin.Any declared in <root>.DoubleExpression
public open fun isEqualTo (value: kotlin.Double): @[EnhancedNullability] kotlin.Any declared in <root>.DoubleExpression
$this: VALUE_PARAMETER name:<this> type:<root>.DoubleExpression
VALUE_PARAMETER name:value index:0 type:kotlin.Double
FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator]
@@ -74,9 +74,9 @@ FILE fqName:<root> fileName:/kt43217.kt
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun get (): kotlin.Double [operator] declared in <root>.C'
CONST Double type=kotlin.Double value=0.0
FUN FAKE_OVERRIDE name:isEqualTo visibility:public modality:OPEN <> ($this:<root>.DoubleExpression, value:kotlin.Double) returnType:kotlin.Any [fake_override]
FUN FAKE_OVERRIDE name:isEqualTo visibility:public modality:OPEN <> ($this:<root>.DoubleExpression, value:kotlin.Double) returnType:@[EnhancedNullability] kotlin.Any [fake_override]
overridden:
public open fun isEqualTo (value: kotlin.Double): kotlin.Any declared in <root>.DoubleExpression
public open fun isEqualTo (value: kotlin.Double): @[EnhancedNullability] kotlin.Any declared in <root>.DoubleExpression
$this: VALUE_PARAMETER name:<this> type:<root>.DoubleExpression
VALUE_PARAMETER name:value index:0 type:kotlin.Double
FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator]