From 9446118d7f6f162cb6fc3b3b3049e9a4587b12b5 Mon Sep 17 00:00:00 2001 From: Yan Zhulanow Date: Tue, 20 Jun 2023 18:22:08 +0900 Subject: [PATCH] [fir2ir] Support code fragment transformation --- .../fir/backend/jvm/JvmFir2IrExtensions.kt | 7 ++ .../kotlin/fir/backend/CodeFragmentUtils.kt | 36 ++++++ .../fir/backend/Fir2IrClassifierStorage.kt | 44 +++++++ .../kotlin/fir/backend/Fir2IrConverter.kt | 107 +++++++++++++++++- .../kotlin/fir/backend/Fir2IrExtensions.kt | 3 + .../kotlin/fir/backend/Fir2IrVisitor.kt | 18 +++ .../kotlin/fir/backend/FirMetadataSource.kt | 2 + .../generators/CallAndReferenceGenerator.kt | 31 +++++ .../signaturer/FirBasedSignatureComposer.kt | 14 +++ .../kotlin/fir/FirVisibilityChecker.kt | 2 +- .../kotlin/ir/declarations/MetadataSource.kt | 1 + 11 files changed, 261 insertions(+), 4 deletions(-) create mode 100644 compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/CodeFragmentUtils.kt diff --git a/compiler/fir/fir2ir/jvm-backend/src/org/jetbrains/kotlin/fir/backend/jvm/JvmFir2IrExtensions.kt b/compiler/fir/fir2ir/jvm-backend/src/org/jetbrains/kotlin/fir/backend/jvm/JvmFir2IrExtensions.kt index f8d611cb71a..fd69569ef3a 100644 --- a/compiler/fir/fir2ir/jvm-backend/src/org/jetbrains/kotlin/fir/backend/jvm/JvmFir2IrExtensions.kt +++ b/compiler/fir/fir2ir/jvm-backend/src/org/jetbrains/kotlin/fir/backend/jvm/JvmFir2IrExtensions.kt @@ -12,7 +12,10 @@ import org.jetbrains.kotlin.config.JVMConfigurationKeys import org.jetbrains.kotlin.config.JvmSerializeIrMode import org.jetbrains.kotlin.config.languageVersionSettings import org.jetbrains.kotlin.fir.backend.Fir2IrComponents +import org.jetbrains.kotlin.fir.backend.Fir2IrConversionScope import org.jetbrains.kotlin.fir.backend.Fir2IrExtensions +import org.jetbrains.kotlin.fir.backend.InjectedValue +import org.jetbrains.kotlin.fir.references.FirReference import org.jetbrains.kotlin.ir.IrBuiltIns import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.impl.IrExternalPackageFragmentImpl @@ -64,6 +67,10 @@ class JvmFir2IrExtensions( } } + override fun findInjectedValue(calleeReference: FirReference, conversionScope: Fir2IrConversionScope): InjectedValue? { + return null + } + override val irNeedsDeserialization: Boolean = configuration.get(JVMConfigurationKeys.SERIALIZE_IR, JvmSerializeIrMode.NONE) != JvmSerializeIrMode.NONE diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/CodeFragmentUtils.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/CodeFragmentUtils.kt new file mode 100644 index 00000000000..442e339f699 --- /dev/null +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/CodeFragmentUtils.kt @@ -0,0 +1,36 @@ +/* + * Copyright 2010-2023 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.fir.declarations.FirCodeFragment +import org.jetbrains.kotlin.fir.declarations.FirDeclarationDataKey +import org.jetbrains.kotlin.fir.declarations.FirDeclarationDataRegistry +import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol +import org.jetbrains.kotlin.fir.types.FirTypeRef +import org.jetbrains.kotlin.ir.symbols.IrValueParameterSymbol +import org.jetbrains.kotlin.ir.symbols.impl.IrValueParameterSymbolImpl +import org.jetbrains.kotlin.name.ClassId +import org.jetbrains.kotlin.name.Name + +class CodeFragmentConversionData( + val classId: ClassId, + val methodName: Name, + val injectedValues: List +) + +class InjectedValue(val symbol: FirBasedSymbol<*>, val typeRef: FirTypeRef, val isMutated: Boolean) { + val irParameterSymbol: IrValueParameterSymbol = IrValueParameterSymbolImpl() +} + +private object CodeFragmentTowerDataContext : FirDeclarationDataKey() + +private var FirCodeFragment.conversionDataOpt: CodeFragmentConversionData? by FirDeclarationDataRegistry.data(CodeFragmentTowerDataContext) + +var FirCodeFragment.conversionData: CodeFragmentConversionData + get() = conversionDataOpt ?: error("Conversion data is not set") + set(newValue) { + conversionDataOpt = newValue + } \ No newline at end of file diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrClassifierStorage.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrClassifierStorage.kt index c8ec6a5acb5..77d6a64e6cb 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrClassifierStorage.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrClassifierStorage.kt @@ -58,6 +58,8 @@ class Fir2IrClassifierStorage( private val enumEntryCache: MutableMap = commonMemberStorage.enumEntryCache + private val codeFragmentCache: MutableMap = mutableMapOf() + private val fieldsForContextReceivers: MutableMap> = mutableMapOf() private val localStorage: Fir2IrLocalClassStorage = Fir2IrLocalClassStorage( @@ -189,6 +191,10 @@ class Fir2IrClassifierStorage( return localStorage[lookupTag.toSymbol(session)!!.fir as FirClass] } + fun getCachedIrCodeFragment(codeFragment: FirCodeFragment): IrClass? { + return codeFragmentCache[codeFragment] + } + private fun FirRegularClass.enumClassModality(): Modality { return when { declarations.any { it is FirCallableDeclaration && it.modality == Modality.ABSTRACT } -> { @@ -407,6 +413,44 @@ class Fir2IrClassifierStorage( return irAnonymousObject } + fun registerCodeFragmentClass(codeFragment: FirCodeFragment, containingFile: IrFile): IrClass { + val conversionData = codeFragment.conversionData + val signature = signatureComposer.composeSignature(codeFragment) + + val irClass = codeFragment.convertWithOffsets { startOffset, endOffset -> + declareIrClass(signature) { symbol -> + irFactory.createClass( + startOffset, + endOffset, + IrDeclarationOrigin.DEFINED, + conversionData.classId.shortClassName, + DescriptorVisibilities.PUBLIC, + symbol, + ClassKind.CLASS, + Modality.FINAL, + isExternal = false, + isCompanion = false, + isInner = false, + isData = false, + isValue = false, + isExpect = false, + isFun = false + ).apply { + metadata = FirMetadataSource.CodeFragment(codeFragment) + parent = containingFile + typeParameters = emptyList() + thisReceiver = declareThisReceiverParameter( + thisType = IrSimpleTypeImpl(symbol, false, emptyList(), emptyList()), + thisOrigin = IrDeclarationOrigin.INSTANCE_RECEIVER + ) + superTypes = listOf(irBuiltIns.anyType) + } + } + } + codeFragmentCache[codeFragment] = irClass + return irClass + } + private fun getIrAnonymousObjectForEnumEntry(anonymousObject: FirAnonymousObject, name: Name, irParent: IrClass?): IrClass { localStorage[anonymousObject]?.let { return it } val irAnonymousObject = registerIrAnonymousObject(anonymousObject, Visibilities.Private, name, irParent) diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrConverter.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrConverter.kt index 1dc7ec2f465..a7e5f3a5da5 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrConverter.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrConverter.kt @@ -15,22 +15,29 @@ import org.jetbrains.kotlin.builtins.DefaultBuiltIns import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.config.AnalysisFlags import org.jetbrains.kotlin.config.LanguageFeature +import org.jetbrains.kotlin.descriptors.DescriptorVisibilities +import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.fir.* import org.jetbrains.kotlin.fir.backend.generators.* import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.utils.isLocal import org.jetbrains.kotlin.fir.declarations.utils.isSynthetic import org.jetbrains.kotlin.fir.descriptors.FirModuleDescriptor +import org.jetbrains.kotlin.fir.expressions.FirExpression import org.jetbrains.kotlin.fir.extensions.declarationGenerators import org.jetbrains.kotlin.fir.extensions.extensionService import org.jetbrains.kotlin.fir.extensions.generatedMembers import org.jetbrains.kotlin.fir.extensions.generatedNestedClassifiers import org.jetbrains.kotlin.fir.resolve.ScopeSession +import org.jetbrains.kotlin.fir.symbols.Fir2IrConstructorSymbol +import org.jetbrains.kotlin.fir.symbols.Fir2IrSimpleFunctionSymbol import org.jetbrains.kotlin.fir.symbols.lazyDeclarationResolver import org.jetbrains.kotlin.ir.PsiIrFileEntry +import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.impl.IrFileImpl import org.jetbrains.kotlin.ir.declarations.impl.IrModuleFragmentImpl +import org.jetbrains.kotlin.ir.expressions.impl.IrDelegatingConstructorCallImpl import org.jetbrains.kotlin.ir.interpreter.IrInterpreter import org.jetbrains.kotlin.ir.interpreter.IrInterpreterConfiguration import org.jetbrains.kotlin.ir.interpreter.IrInterpreterEnvironment @@ -38,7 +45,10 @@ import org.jetbrains.kotlin.ir.interpreter.checker.EvaluationMode import org.jetbrains.kotlin.ir.interpreter.transformer.transformConst import org.jetbrains.kotlin.ir.util.KotlinMangler import org.jetbrains.kotlin.ir.util.NaiveSourceBasedFileEntryImpl +import org.jetbrains.kotlin.ir.util.defaultType +import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.psi.KtFile +import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstance class Fir2IrConverter( private val moduleDescriptor: FirModuleDescriptor, @@ -146,9 +156,11 @@ class Fir2IrConverter( moduleFragment ) declarationStorage.registerFile(file, irFile) - file.declarations.forEach { - if (it is FirRegularClass) { - registerClassAndNestedClasses(it, irFile) + for (declaration in file.declarations) { + when (declaration) { + is FirRegularClass -> registerClassAndNestedClasses(declaration, irFile) + is FirCodeFragment -> classifierStorage.registerCodeFragmentClass(declaration, irFile) + else -> {} } } moduleFragment.files += irFile @@ -227,6 +239,92 @@ class Fir2IrConverter( return irClass } + private fun processCodeFragmentMembers( + codeFragment: FirCodeFragment, + irClass: IrClass = classifierStorage.getCachedIrCodeFragment(codeFragment)!! + ): IrClass { + val conversionData = codeFragment.conversionData + + declarationStorage.enterScope(irClass) + + val signature = irClass.symbol.signature!! + + val irPrimaryConstructor = symbolTable.declareConstructor(signature, { Fir2IrConstructorSymbol(signature) }) { irSymbol -> + irFactory.createConstructor( + UNDEFINED_OFFSET, UNDEFINED_OFFSET, + IrDeclarationOrigin.DEFINED, + Name.special(""), + irClass.visibility, + isInline = false, + isExpect = false, + irClass.defaultType, + irSymbol, + isExternal = false, + isPrimary = true + ).apply { + parent = irClass + body = irFactory.createBlockBody(UNDEFINED_OFFSET, UNDEFINED_OFFSET).apply { + statements += IrDelegatingConstructorCallImpl.fromSymbolOwner( + UNDEFINED_OFFSET, UNDEFINED_OFFSET, + irBuiltIns.unitType, + irBuiltIns.anyClass.owner.declarations.firstIsInstance().symbol + ) + } + } + } + + val irFragmentFunction = symbolTable.declareSimpleFunction(signature, { Fir2IrSimpleFunctionSymbol(signature) }) { irSymbol -> + val lastStatement = codeFragment.block.statements.lastOrNull() + val returnType = (lastStatement as? FirExpression)?.typeRef?.toIrType(typeConverter) ?: irBuiltIns.unitType + + irFactory.createSimpleFunction( + UNDEFINED_OFFSET, UNDEFINED_OFFSET, + IrDeclarationOrigin.DEFINED, + conversionData.methodName, + DescriptorVisibilities.PUBLIC, + isInline = false, + isExpect = false, + returnType, + Modality.FINAL, + irSymbol, + isTailrec = false, + isSuspend = false, + isOperator = false, + isInfix = false, + isExternal = false, + containerSource = null, + isFakeOverride = false + ).apply fragmentFunction@{ + parent = irClass + valueParameters = conversionData.injectedValues.mapIndexed { index, injectedValue -> + val isMutated = injectedValue.isMutated + + irFactory.createValueParameter( + UNDEFINED_OFFSET, UNDEFINED_OFFSET, + if (isMutated) IrDeclarationOrigin.SHARED_VARIABLE_IN_EVALUATOR_FRAGMENT else IrDeclarationOrigin.DEFINED, + Name.identifier("p$index"), + injectedValue.typeRef.toIrType(typeConverter), + isAssignable = isMutated, + injectedValue.irParameterSymbol, + index, + varargElementType = null, + isCrossinline = false, + isNoinline = false, + isHidden = false + ).apply { + parent = this@fragmentFunction + } + } + } + } + + irClass.declarations.add(irPrimaryConstructor) + irClass.declarations.add(irFragmentFunction) + + declarationStorage.leaveScope(irClass) + return irClass + } + private fun bindFakeOverridesInFile(file: FirFile) { val irFile = declarationStorage.getIrFile(file) for (irDeclaration in irFile.declarations) { @@ -393,6 +491,9 @@ class Fir2IrConverter( // DO NOTHING null } + is FirCodeFragment -> { + processCodeFragmentMembers(declaration) + } else -> { error("Unexpected member: ${declaration::class}") } diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrExtensions.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrExtensions.kt index c4c3c0c5a11..4d0fcceaf34 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrExtensions.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrExtensions.kt @@ -5,6 +5,7 @@ package org.jetbrains.kotlin.fir.backend +import org.jetbrains.kotlin.fir.references.FirReference import org.jetbrains.kotlin.ir.declarations.IrClass import org.jetbrains.kotlin.ir.declarations.IrMemberWithContainerSource import org.jetbrains.kotlin.ir.util.SymbolTable @@ -15,6 +16,7 @@ interface Fir2IrExtensions { fun generateOrGetFacadeClass(declaration: IrMemberWithContainerSource, components: Fir2IrComponents): IrClass? fun deserializeToplevelClass(irClass: IrClass, components: Fir2IrComponents): Boolean fun registerDeclarations(symbolTable: SymbolTable) + fun findInjectedValue(calleeReference: FirReference, conversionScope: Fir2IrConversionScope): InjectedValue? object Default : Fir2IrExtensions { override val irNeedsDeserialization: Boolean @@ -23,5 +25,6 @@ interface Fir2IrExtensions { override fun generateOrGetFacadeClass(declaration: IrMemberWithContainerSource, components: Fir2IrComponents): IrClass? = null override fun deserializeToplevelClass(irClass: IrClass, components: Fir2IrComponents): Boolean = false override fun registerDeclarations(symbolTable: SymbolTable) {} + override fun findInjectedValue(calleeReference: FirReference, conversionScope: Fir2IrConversionScope) = null } } \ No newline at end of file diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrVisitor.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrVisitor.kt index 3defeb9a5df..b24965ef0c9 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrVisitor.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrVisitor.kt @@ -58,6 +58,7 @@ import org.jetbrains.kotlin.psi.KtBinaryExpression import org.jetbrains.kotlin.psi.KtForExpression import org.jetbrains.kotlin.types.Variance import org.jetbrains.kotlin.util.OperatorNameConventions +import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstance import org.jetbrains.kotlin.utils.addToStdlib.runUnless class Fir2IrVisitor( @@ -316,6 +317,20 @@ class Fir2IrVisitor( } } + override fun visitCodeFragment(codeFragment: FirCodeFragment, data: Any?): IrElement { + val irClass = classifierStorage.getCachedIrCodeFragment(codeFragment)!! + val irFunction = irClass.declarations.firstIsInstance() + + declarationStorage.enterScope(irFunction) + conversionScope.withParent(irFunction) { + val irBlock = codeFragment.block.convertToIrBlock(forceUnitType = false) + irFunction.body = irFactory.createExpressionBody(irBlock) + } + declarationStorage.leaveScope(irFunction) + + return irFunction + } + override fun visitAnonymousObjectExpression(anonymousObjectExpression: FirAnonymousObjectExpression, data: Any?): IrElement { return visitAnonymousObject(anonymousObjectExpression.anonymousObject, data) } @@ -639,6 +654,9 @@ class Fir2IrVisitor( data: Any? ): IrElement = whileAnalysing(session, thisReceiverExpression) { val calleeReference = thisReceiverExpression.calleeReference + + callGenerator.injectGetValueCall(thisReceiverExpression, calleeReference)?.let { return it } + val boundSymbol = calleeReference.boundSymbol when (boundSymbol) { is FirClassSymbol -> { diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/FirMetadataSource.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/FirMetadataSource.kt index 195166ec3e2..d8d5290c6d5 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/FirMetadataSource.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/FirMetadataSource.kt @@ -46,4 +46,6 @@ sealed class FirMetadataSource : MetadataSource { } class Script(override val fir: FirScript) : FirMetadataSource(), MetadataSource.Script + + class CodeFragment(override val fir: FirCodeFragment) : FirMetadataSource(), MetadataSource.CodeFragment } diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/CallAndReferenceGenerator.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/CallAndReferenceGenerator.kt index 1fae5532ee9..ef44ad74aa7 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/CallAndReferenceGenerator.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/CallAndReferenceGenerator.kt @@ -9,6 +9,7 @@ import com.intellij.openapi.progress.ProcessCanceledException import org.jetbrains.kotlin.KtFakeSourceElementKind import org.jetbrains.kotlin.builtins.StandardNames import org.jetbrains.kotlin.config.LanguageFeature +import org.jetbrains.kotlin.fir.FirElement import org.jetbrains.kotlin.fir.backend.* import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.utils.isMethodOfAny @@ -341,6 +342,19 @@ class CallAndReferenceGenerator( .applyCallArguments((qualifiedAccess as? FirCall)?.takeIf { !noArguments }) } + internal fun injectGetValueCall(element: FirElement, calleeReference: FirReference): IrExpression? { + val injectedValue = extensions.findInjectedValue(calleeReference, conversionScope) + if (injectedValue != null) { + return element.convertWithOffsets { startOffset, endOffset -> + val type = injectedValue.typeRef.toIrType() + val origin = calleeReference.statementOrigin() + IrGetValueImpl(startOffset, endOffset, type, injectedValue.irParameterSymbol, origin) + } + } + + return null + } + fun convertToIrCall( qualifiedAccess: FirQualifiedAccessExpression, typeRef: FirTypeRef, @@ -350,6 +364,8 @@ class CallAndReferenceGenerator( noArguments: Boolean = false ): IrExpression { try { + injectGetValueCall(qualifiedAccess, qualifiedAccess.calleeReference)?.let { return it } + val type = typeRef.toIrType() val samConstructorCall = qualifiedAccess.tryConvertToSamConstructorCall(type) if (samConstructorCall != null) return samConstructorCall @@ -535,12 +551,27 @@ class CallAndReferenceGenerator( ?: error("No receiver for dynamic call") } + private fun injectSetValueCall(element: FirElement, calleeReference: FirReference, assignedValue: IrExpression): IrExpression? { + val injectedValue = extensions.findInjectedValue(calleeReference, conversionScope) + if (injectedValue != null) { + return element.convertWithOffsets { startOffset, endOffset -> + val type = irBuiltIns.unitType + val origin = calleeReference.statementOrigin() + IrSetValueImpl(startOffset, endOffset, type, injectedValue.irParameterSymbol, assignedValue, origin) + } + } + + return null + } + fun convertToIrSetCall(variableAssignment: FirVariableAssignment, explicitReceiverExpression: IrExpression?): IrExpression { try { val type = irBuiltIns.unitType val calleeReference = variableAssignment.calleeReference ?: error("Reference not resolvable") val assignedValue = visitor.convertToIrExpression(variableAssignment.rValue) + injectSetValueCall(variableAssignment, calleeReference, assignedValue)?.let { return it } + val firSymbol = calleeReference.toResolvedBaseSymbol() val isDynamicAccess = firSymbol?.origin == FirDeclarationOrigin.DynamicScope diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/signaturer/FirBasedSignatureComposer.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/signaturer/FirBasedSignatureComposer.kt index 979504d5d0e..1f4b29dc4a7 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/signaturer/FirBasedSignatureComposer.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/signaturer/FirBasedSignatureComposer.kt @@ -9,6 +9,7 @@ import org.jetbrains.kotlin.backend.common.serialization.mangle.MangleConstant import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.fir.* import org.jetbrains.kotlin.fir.backend.FirMangler +import org.jetbrains.kotlin.fir.backend.conversionData import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertyGetter import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertySetter @@ -47,6 +48,10 @@ class FirBasedSignatureComposer(val mangler: FirMangler) { return composeSignatureImpl(declaration, containingClass = null, forceExpect = false) } + fun composeSignature(declaration: FirCodeFragment): IdSignature? { + return composeSignatureImpl(declaration, containingClass = null, forceExpect = false) + } + fun composeTypeParameterSignature( index: Int, containerSignature: IdSignature? @@ -174,6 +179,12 @@ class FirBasedSignatureComposer(val mangler: FirMangler) { description = builder.description, ) } + is FirCodeFragment -> { + val conversionData = declaration.conversionData + val packageFqName = conversionData.classId.packageFqName.asString() + val classFqName = conversionData.classId.relativeClassName.asString() + IdSignature.CommonSignature(packageFqName, classFqName, builder.hashId, builder.mask, description = null) + } else -> error("Unsupported FIR declaration in signature composer: ${declaration.render()}") } } @@ -206,6 +217,9 @@ class FirBasedSignatureComposer(val mangler: FirMangler) { override fun visitScript(script: FirScript, data: Any?) { } + override fun visitCodeFragment(codeFragment: FirCodeFragment, data: Any?) { + } + override fun visitTypeAlias(typeAlias: FirTypeAlias, data: Any?) { setExpected(typeAlias.isExpect) } diff --git a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/FirVisibilityChecker.kt b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/FirVisibilityChecker.kt index 3be93da6f4f..52475fea46d 100644 --- a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/FirVisibilityChecker.kt +++ b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/FirVisibilityChecker.kt @@ -469,7 +469,7 @@ fun FirBasedSymbol<*>.getOwnerLookupTag(): ConeClassLikeLookupTag? { is FirBackingFieldSymbol -> fir.propertySymbol.getOwnerLookupTag() is FirClassLikeSymbol<*> -> getContainingClassLookupTag() is FirCallableSymbol<*> -> containingClassLookupTag() - is FirScriptSymbol -> null + is FirScriptSymbol, is FirCodeFragmentSymbol -> null else -> errorWithAttachment("Unsupported owner search for ${fir::class.java}") { withFirEntry("ownerDeclaration", fir) } diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/MetadataSource.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/MetadataSource.kt index c09ce0e3015..d82beec510d 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/MetadataSource.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/MetadataSource.kt @@ -18,6 +18,7 @@ interface MetadataSource { var serializedIr: ByteArray? } interface Script : MetadataSource + interface CodeFragment : MetadataSource interface Function : MetadataSource interface Property : MetadataSource { val isConst: Boolean