K2 Scripting: fix script this receiver handling in IR
also fix accessor lowering
This commit is contained in:
committed by
Space Team
parent
07df03dbec
commit
02e2438d37
@@ -206,7 +206,7 @@ fun FirReference.toSymbolForCall(
|
||||
val property = declarationStorage.getIrPropertySymbol(boundSymbol).owner as? IrProperty
|
||||
property?.let { conversionScope.parentAccessorOfPropertyFromStack(it) }?.symbol
|
||||
}
|
||||
|
||||
is FirScriptSymbol -> declarationStorage.getCachedIrScript(boundSymbol.fir)?.thisReceiver?.symbol
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,10 +21,7 @@ import org.jetbrains.kotlin.fir.backend.generators.OperatorExpressionGenerator
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.declarations.builder.buildProperty
|
||||
import org.jetbrains.kotlin.fir.declarations.impl.FirDeclarationStatusImpl
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.expandedConeType
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.isSealed
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.isSynthetic
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.visibility
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.*
|
||||
import org.jetbrains.kotlin.fir.deserialization.toQualifiedPropertyAccessExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.*
|
||||
import org.jetbrains.kotlin.fir.expressions.impl.FirContractCallBlock
|
||||
@@ -41,10 +38,12 @@ import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.IrStatement
|
||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||
import org.jetbrains.kotlin.ir.builders.*
|
||||
import org.jetbrains.kotlin.ir.builders.declarations.UNDEFINED_PARAMETER_INDEX
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrValueParameterSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.types.*
|
||||
import org.jetbrains.kotlin.ir.types.impl.IrErrorTypeImpl
|
||||
import org.jetbrains.kotlin.ir.util.constructors
|
||||
@@ -208,9 +207,25 @@ class Fir2IrVisitor(
|
||||
return declarationStorage.getCachedIrScript(script)!!.also { irScript ->
|
||||
irScript.parent = conversionScope.parentFromStack()
|
||||
declarationStorage.enterScope(irScript)
|
||||
|
||||
irScript.explicitCallParameters = script.parameters.map { parameter ->
|
||||
declarationStorage.createIrVariable(parameter, irScript)
|
||||
declarationStorage.createIrVariable(parameter, irScript, givenOrigin = IrDeclarationOrigin.SCRIPT_CALL_PARAMETER)
|
||||
}
|
||||
|
||||
irScript.thisReceiver = script.contextReceivers.find { it.customLabelName?.asString() == SCRIPT_SPECIAL_NAME_STRING }?.let { receiver ->
|
||||
receiver.convertWithOffsets { startOffset, endOffset ->
|
||||
irFactory.createValueParameter(
|
||||
startOffset, endOffset, IrDeclarationOrigin.INSTANCE_RECEIVER, SpecialNames.THIS, receiver.typeRef.toIrType(),
|
||||
isAssignable = false, IrValueParameterSymbolImpl(), UNDEFINED_PARAMETER_INDEX,
|
||||
varargElementType = null,
|
||||
isCrossinline = false, isNoinline = false,
|
||||
isHidden = false,
|
||||
).also {
|
||||
it.parent = irScript
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
conversionScope.withParent(irScript) {
|
||||
for (statement in script.statements) {
|
||||
val irStatement = if (statement is FirDeclaration) {
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
/*
|
||||
* 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.declarations.utils
|
||||
|
||||
const val SCRIPT_SPECIAL_NAME_STRING = "<script>"
|
||||
const val SCRIPT_RECEIVER_NAME_PREFIX = "\$script_receiver"
|
||||
+11
-8
@@ -445,9 +445,9 @@ private class ScriptsToClassesLowering(val context: JvmBackendContext, val inner
|
||||
if (initializer != null) {
|
||||
field.initializer = initializer
|
||||
}
|
||||
|
||||
property.addDefaultGetter(this, context.irBuiltIns)
|
||||
}
|
||||
|
||||
property.addDefaultGetter(this, context.irBuiltIns)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -488,11 +488,14 @@ private class ScriptToClassTransformer(
|
||||
}
|
||||
}
|
||||
|
||||
val scriptThisType = IrSimpleTypeImpl(irScriptClass.symbol, false, emptyList(), emptyList())
|
||||
val scriptClassReceiver =
|
||||
irScript.thisReceiver?.transform(this, ScriptToClassTransformerContext(null, null, null, false)) ?: run {
|
||||
irScript.thisReceiver?.let {
|
||||
it.type = scriptThisType
|
||||
it.transform(this, ScriptToClassTransformerContext(null, null, null, false))
|
||||
} ?: run {
|
||||
context.symbolTable.enterScope(irScriptClass)
|
||||
val thisType = IrSimpleTypeImpl(irScriptClass.symbol, false, emptyList(), emptyList())
|
||||
val newReceiver = irScriptClass.createThisReceiverParameter(IrDeclarationOrigin.INSTANCE_RECEIVER, thisType)
|
||||
val newReceiver = irScriptClass.createThisReceiverParameter(IrDeclarationOrigin.INSTANCE_RECEIVER, scriptThisType)
|
||||
context.symbolTable.leaveScope(irScriptClass)
|
||||
newReceiver
|
||||
}
|
||||
@@ -689,14 +692,14 @@ private class ScriptToClassTransformer(
|
||||
return super.visitMemberAccess(expression, data) as IrExpression
|
||||
}
|
||||
|
||||
override fun visitGetField(expression: IrGetField, data: ScriptToClassTransformerContext): IrExpression {
|
||||
if (expression.receiver == null && expression.symbol.owner.needsScriptReceiver()) {
|
||||
override fun visitFieldAccess(expression: IrFieldAccessExpression, data: ScriptToClassTransformerContext): IrExpression {
|
||||
if (expression.receiver == null && expression.symbol.owner.parent.let { it == irScript || it == irScriptClass }) {
|
||||
expression.receiver =
|
||||
getAccessCallForScriptInstance(
|
||||
data, expression.startOffset, expression.endOffset, expression.origin, originalReceiverParameter = null
|
||||
)
|
||||
}
|
||||
return super.visitGetField(expression, data)
|
||||
return super.visitFieldAccess(expression, data)
|
||||
}
|
||||
|
||||
override fun visitConstructorCall(expression: IrConstructorCall, data: ScriptToClassTransformerContext): IrExpression {
|
||||
|
||||
-1
@@ -1,5 +1,4 @@
|
||||
// IGNORE_BACKEND: JS, JS_IR, JS_IR_ES6, NATIVE, WASM
|
||||
// IGNORE_BACKEND_K2: JVM_IR
|
||||
|
||||
// expected: rv: 42
|
||||
|
||||
|
||||
-1
@@ -1,5 +1,4 @@
|
||||
// IGNORE_BACKEND: JS, JS_IR, JS_IR_ES6, NATIVE, WASM
|
||||
// IGNORE_BACKEND_K2: JVM_IR
|
||||
|
||||
// expected: rv: abc
|
||||
|
||||
|
||||
Vendored
-1
@@ -1,6 +1,5 @@
|
||||
// IGNORE_BACKEND: JS, JS_IR, JS_IR_ES6, NATIVE, WASM
|
||||
// IGNORE_BACKEND: JVM
|
||||
// IGNORE_BACKEND_K2: JVM_IR
|
||||
|
||||
// expected: rv: 42
|
||||
|
||||
|
||||
-1
@@ -1,6 +1,5 @@
|
||||
// IGNORE_BACKEND: JS, JS_IR, JS_IR_ES6, NATIVE, WASM
|
||||
// IGNORE_BACKEND: JVM
|
||||
// IGNORE_BACKEND_K2: JVM_IR
|
||||
|
||||
// expected: rv: 42
|
||||
|
||||
|
||||
Vendored
-1
@@ -1,6 +1,5 @@
|
||||
// IGNORE_BACKEND: JS, JS_IR, JS_IR_ES6, NATIVE, WASM
|
||||
// IGNORE_BACKEND: JVM
|
||||
// IGNORE_BACKEND_K2: JVM_IR
|
||||
|
||||
// expected: rv: 42
|
||||
|
||||
|
||||
Vendored
-1
@@ -1,5 +1,4 @@
|
||||
// IGNORE_BACKEND: JS, JS_IR, JS_IR_ES6, NATIVE, WASM
|
||||
// IGNORE_BACKEND_K2: JVM_IR
|
||||
|
||||
// expected: rv: abc!
|
||||
|
||||
|
||||
+7
-3
@@ -16,6 +16,7 @@ import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin
|
||||
import org.jetbrains.kotlin.fir.declarations.builder.*
|
||||
import org.jetbrains.kotlin.fir.declarations.impl.FirDeclarationStatusImpl
|
||||
import org.jetbrains.kotlin.fir.declarations.primaryConstructorIfAny
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.SCRIPT_SPECIAL_NAME_STRING
|
||||
import org.jetbrains.kotlin.fir.moduleData
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.dependenciesSymbolProvider
|
||||
import org.jetbrains.kotlin.fir.symbols.SymbolInternals
|
||||
@@ -52,7 +53,7 @@ class FirScriptConfiguratorExtensionImpl(
|
||||
// TODO: rewrite/extract decision logic for clarity
|
||||
configuration[ScriptCompilationConfiguration.baseClass]?.let { baseClass ->
|
||||
val baseClassFqn = FqName.fromSegments(baseClass.typeName.split("."))
|
||||
contextReceivers.add(buildContextReceiverWithFqName(baseClassFqn))
|
||||
contextReceivers.add(buildContextReceiverWithFqName(baseClassFqn, Name.special(SCRIPT_SPECIAL_NAME_STRING)))
|
||||
|
||||
val baseClassSymbol =
|
||||
session.dependenciesSymbolProvider.getClassLikeSymbolByClassId(ClassId(baseClassFqn.parent(), baseClassFqn.shortName()))
|
||||
@@ -138,16 +139,19 @@ class FirScriptConfiguratorExtensionImpl(
|
||||
configuration?.let { body.invoke(it) }
|
||||
}
|
||||
|
||||
private fun buildContextReceiverWithFqName(baseClassFqn: FqName) =
|
||||
private fun buildContextReceiverWithFqName(classFqn: FqName, customName: Name? = null) =
|
||||
buildContextReceiver {
|
||||
typeRef = buildUserTypeRef {
|
||||
isMarkedNullable = false
|
||||
qualifier.addAll(
|
||||
baseClassFqn.pathSegments().map {
|
||||
classFqn.pathSegments().map {
|
||||
FirQualifierPartImpl(null, it, FirTypeArgumentListImpl(null))
|
||||
}
|
||||
)
|
||||
}
|
||||
if (customName != null) {
|
||||
customLabelName = customName
|
||||
}
|
||||
}
|
||||
|
||||
private val _knownAnnotationsForSamWithReceiver = hashSetOf<String>()
|
||||
|
||||
Reference in New Issue
Block a user