From cc9a7480a2262f157669f6cbf7b2349e114bca08 Mon Sep 17 00:00:00 2001 From: Ilya Chernikov Date: Wed, 16 Nov 2022 11:06:18 +0100 Subject: [PATCH] K2 Scripting: add FIR2IR conversion for FirScript --- .../kotlin/fir/backend/Fir2IrConverter.kt | 4 ++++ .../fir/backend/Fir2IrDeclarationStorage.kt | 21 +++++++++++++++++++ .../kotlin/fir/backend/Fir2IrVisitor.kt | 19 +++++++++++++++++ .../kotlin/fir/backend/FirMetadataSource.kt | 2 ++ .../signaturer/FirBasedSignatureComposer.kt | 10 +++++++++ .../kotlin/fir/symbols/Fir2IrSymbols.kt | 3 +++ .../kotlin/fir/FirVisibilityChecker.kt | 1 + .../psi2ir/generators/ScriptGenerator.kt | 2 +- .../ir/declarations/impl/IrScriptImpl.kt | 4 ++-- .../ir/util/DeepCopyIrTreeWithSymbols.kt | 2 ++ .../jetbrains/kotlin/ir/util/SymbolTable.kt | 16 +++++++++++++- 11 files changed, 80 insertions(+), 4 deletions(-) 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 44fc8a02ec5..c0c75cd2057 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 @@ -356,6 +356,10 @@ class Fir2IrConverter( is FirRegularClass -> { processClassMembers(declaration) } + is FirScript -> { + assert(parent is IrFile) + declarationStorage.getOrCreateIrScript(declaration) + } is FirSimpleFunction -> { declarationStorage.getOrCreateIrFunction( declaration, parent, isLocal = isLocal diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrDeclarationStorage.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrDeclarationStorage.kt index 4bb03c2a8e4..5bda0330da5 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrDeclarationStorage.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrDeclarationStorage.kt @@ -39,6 +39,7 @@ import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET import org.jetbrains.kotlin.ir.builders.declarations.UNDEFINED_PARAMETER_INDEX import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin.GeneratedByPlugin +import org.jetbrains.kotlin.ir.declarations.impl.IrScriptImpl import org.jetbrains.kotlin.ir.declarations.impl.IrVariableImpl import org.jetbrains.kotlin.ir.declarations.lazy.IrLazyClass import org.jetbrains.kotlin.ir.expressions.IrExpression @@ -73,6 +74,8 @@ class Fir2IrDeclarationStorage( private val fileCache = ConcurrentHashMap() + private val scriptCache = ConcurrentHashMap() + private val functionCache = ConcurrentHashMap() private val constructorCache = ConcurrentHashMap() @@ -1530,6 +1533,24 @@ class Fir2IrDeclarationStorage( return getIrPropertyForwardedSymbol(firVariableSymbol.fir) } + fun getCachedIrScript(script: FirScript): IrScript? = scriptCache[script] + + fun getOrCreateIrScript(script: FirScript): IrScript = + getCachedIrScript(script) ?: script.convertWithOffsets { startOffset, endOffset -> + val signature = signatureComposer.composeSignature(script)!! + symbolTable.declareScript(signature, { Fir2IrScriptSymbol(signature) }) { symbol -> + IrScriptImpl(symbol, script.name, irFactory, startOffset, endOffset).also { irScript -> + irScript.metadata = FirMetadataSource.Script(script) + irScript.explicitCallParameters = emptyList() + irScript.implicitReceiversParameters = emptyList() + irScript.providedProperties = emptyList() + irScript.providedPropertiesParameters = emptyList() + scriptCache[script] = irScript + } + } + } + + private fun getIrPropertyForwardedSymbol(fir: FirVariable): IrSymbol { return when (fir) { is FirProperty -> { 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 00b200f6924..cc39aeeba03 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 @@ -192,6 +192,25 @@ class Fir2IrVisitor( } } + override fun visitScript(script: FirScript, data: Any?): IrElement { + return declarationStorage.getCachedIrScript(script)!!.also { irScript -> + irScript.parent = conversionScope.parentFromStack() + symbolTable.enterScope(irScript) + conversionScope.withParent(irScript) { + for (statement in script.statements) { + if (statement is FirDeclaration) { + val irDeclaration = statement.accept(this@Fir2IrVisitor, null) as IrDeclaration + irScript.statements.add(irDeclaration) + } else { + val irStatement = statement.toIrStatement()!! + irScript.statements.add(irStatement) + } + } + } + symbolTable.leaveScope(irScript) + } + } + override fun visitAnonymousObjectExpression(anonymousObjectExpression: FirAnonymousObjectExpression, data: Any?): IrElement { return visitAnonymousObject(anonymousObjectExpression.anonymousObject, data) } 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 6a45d5b962c..cd44deb5e63 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 @@ -40,4 +40,6 @@ sealed class FirMetadataSource : MetadataSource { class Property(override val fir: FirProperty) : FirMetadataSource(), MetadataSource.Property { override val isConst: Boolean get() = fir.isConst } + + class Script(override val fir: FirScript) : FirMetadataSource(), MetadataSource.Script } 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 26b8384edc9..3ea2fd2d0e6 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 @@ -52,6 +52,9 @@ class FirBasedSignatureComposer(override val mangler: FirMangler) : Fir2IrSignat //platformSpecificClass(descriptor) } + override fun visitScript(script: FirScript, data: Any?) { + } + override fun visitTypeAlias(typeAlias: FirTypeAlias, data: Any?) { setExpected(typeAlias.isExpect) } @@ -140,6 +143,13 @@ class FirBasedSignatureComposer(override val mangler: FirMangler) : Fir2IrSignat builder.hashId, builder.mask ) } + is FirScript -> { + IdSignature.CommonSignature( + declaration.name.asString(), // TODO: find package id + declaration.name.asString(), + builder.hashId, builder.mask + ) + } else -> error("Unsupported FIR declaration in signature composer: ${declaration.render()}") } } diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/symbols/Fir2IrSymbols.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/symbols/Fir2IrSymbols.kt index 4215000a081..4bb918a4d98 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/symbols/Fir2IrSymbols.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/symbols/Fir2IrSymbols.kt @@ -39,3 +39,6 @@ class Fir2IrPropertySymbol( ) : Fir2IrBindableSymbol(signature, containerSource), IrPropertySymbol +class Fir2IrScriptSymbol(signature: IdSignature) : + Fir2IrBindableSymbol(signature), + IrScriptSymbol 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 cf4be4b1e47..3d18ba03270 100644 --- a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/FirVisibilityChecker.kt +++ b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/FirVisibilityChecker.kt @@ -556,6 +556,7 @@ fun FirBasedSymbol<*>.getOwnerLookupTag(): ConeClassLikeLookupTag? { is FirBackingFieldSymbol -> fir.propertySymbol.getOwnerLookupTag() is FirClassLikeSymbol<*> -> getContainingClassLookupTag() is FirCallableSymbol<*> -> containingClassLookupTag() + is FirScriptSymbol -> null else -> error("Unsupported owner search for ${fir.javaClass}: ${fir.render()}") } } diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ScriptGenerator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ScriptGenerator.kt index 3d8bfcecd2f..eff95dee184 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ScriptGenerator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ScriptGenerator.kt @@ -45,7 +45,7 @@ class ScriptGenerator(declarationGenerator: DeclarationGenerator) : DeclarationG fun generateScriptDeclaration(ktScript: KtScript): IrDeclaration? { val descriptor = getOrFail(BindingContext.DECLARATION_TO_DESCRIPTOR, ktScript) as ScriptDescriptor - return context.symbolTable.declareScript(descriptor).buildWithScope { irScript -> + return context.symbolTable.declareScript(ktScript.startOffsetSkippingComments, ktScript.endOffset, descriptor).buildWithScope { irScript -> irScript.metadata = DescriptorMetadataSource.Script(descriptor) diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/impl/IrScriptImpl.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/impl/IrScriptImpl.kt index ce40d959f2e..97e44c067d9 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/impl/IrScriptImpl.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/impl/IrScriptImpl.kt @@ -24,9 +24,9 @@ class IrScriptImpl( override val symbol: IrScriptSymbol, override var name: Name, override val factory: IrFactory, + override val startOffset: Int, + override val endOffset: Int, ) : IrScript() { - override val startOffset: Int get() = UNDEFINED_OFFSET - override val endOffset: Int get() = UNDEFINED_OFFSET override var origin: IrDeclarationOrigin = SCRIPT_ORIGIN private var _parent: IrDeclarationParent? = null diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/DeepCopyIrTreeWithSymbols.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/DeepCopyIrTreeWithSymbols.kt index 275e660bdaf..bb65a57b79a 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/DeepCopyIrTreeWithSymbols.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/DeepCopyIrTreeWithSymbols.kt @@ -127,6 +127,8 @@ open class DeepCopyIrTreeWithSymbols( symbolRemapper.getDeclaredScript(declaration.symbol), declaration.name, declaration.factory, + declaration.startOffset, + declaration.endOffset ).also { scriptCopy -> scriptCopy.thisReceiver = declaration.thisReceiver.transform() declaration.statements.mapTo(scriptCopy.statements) { it.transform() } diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/SymbolTable.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/SymbolTable.kt index 66380f4ae41..3d41b2b844b 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/SymbolTable.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/SymbolTable.kt @@ -429,9 +429,11 @@ open class SymbolTable( @ObsoleteDescriptorBasedAPI fun declareScript( + startOffset: Int, + endOffset: Int, descriptor: ScriptDescriptor, scriptFactory: (IrScriptSymbol) -> IrScript = { symbol: IrScriptSymbol -> - IrScriptImpl(symbol, nameProvider.nameForDeclaration(descriptor), irFactory) + IrScriptImpl(symbol, nameProvider.nameForDeclaration(descriptor), irFactory, startOffset, endOffset) } ): IrScript { return scriptSymbolTable.declare( @@ -441,6 +443,18 @@ open class SymbolTable( ) } + fun declareScript( + sig: IdSignature, + symbolFactory: () -> IrScriptSymbol, + scriptFactory: (IrScriptSymbol) -> IrScript + ): IrScript { + return scriptSymbolTable.declare( + sig, + symbolFactory, + scriptFactory + ) + } + @ObsoleteDescriptorBasedAPI override fun referenceScript(descriptor: ScriptDescriptor): IrScriptSymbol = scriptSymbolTable.referenced(descriptor) { IrScriptSymbolImpl(descriptor) }