K2 Scripting: add support for result field
This commit is contained in:
committed by
Space Team
parent
6c7751b0af
commit
d24fc3b581
+1
-1
@@ -101,7 +101,7 @@ internal tailrec fun FirDeclaration.ktSymbolOrigin(): KtSymbolOrigin = when (ori
|
|||||||
FirDeclarationOrigin.DynamicScope -> errorWithAttachment("Invalid FirDeclarationOrigin ${origin::class.simpleName}") {
|
FirDeclarationOrigin.DynamicScope -> errorWithAttachment("Invalid FirDeclarationOrigin ${origin::class.simpleName}") {
|
||||||
withFirEntry("firToGetOrigin", this@ktSymbolOrigin)
|
withFirEntry("firToGetOrigin", this@ktSymbolOrigin)
|
||||||
}
|
}
|
||||||
FirDeclarationOrigin.ScriptCustomization -> KtSymbolOrigin.PLUGIN
|
is FirDeclarationOrigin.ScriptCustomization -> KtSymbolOrigin.PLUGIN
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun KtClassLikeSymbol.getSymbolKind(): KtSymbolKind {
|
internal fun KtClassLikeSymbol.getSymbolKind(): KtSymbolKind {
|
||||||
|
|||||||
+2
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.diagnostics.reportOn
|
|||||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration
|
import org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirProperty
|
import org.jetbrains.kotlin.fir.declarations.FirProperty
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
|
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
|
||||||
import org.jetbrains.kotlin.fir.declarations.utils.isOverride
|
import org.jetbrains.kotlin.fir.declarations.utils.isOverride
|
||||||
@@ -22,6 +23,7 @@ object FirImplicitNothingReturnTypeChecker : FirCallableDeclarationChecker() {
|
|||||||
if (declaration is FirProperty && declaration.isLocal) return
|
if (declaration is FirProperty && declaration.isLocal) return
|
||||||
if (declaration.isOverride) return
|
if (declaration.isOverride) return
|
||||||
if (declaration.symbol.hasExplicitReturnType) return
|
if (declaration.symbol.hasExplicitReturnType) return
|
||||||
|
if (declaration.origin == FirDeclarationOrigin.ScriptCustomization.ResultProperty) return
|
||||||
if (declaration.returnTypeRef.coneType.isNothing) {
|
if (declaration.returnTypeRef.coneType.isNothing) {
|
||||||
val factory = when (declaration) {
|
val factory = when (declaration) {
|
||||||
is FirSimpleFunction -> FirErrors.IMPLICIT_NOTHING_RETURN_TYPE
|
is FirSimpleFunction -> FirErrors.IMPLICIT_NOTHING_RETURN_TYPE
|
||||||
|
|||||||
@@ -859,6 +859,7 @@ class Fir2IrDeclarationStorage(
|
|||||||
isLateInit -> setter?.visibility ?: status.visibility
|
isLateInit -> setter?.visibility ?: status.visibility
|
||||||
isConst -> status.visibility
|
isConst -> status.visibility
|
||||||
hasJvmFieldAnnotation(session) -> status.visibility
|
hasJvmFieldAnnotation(session) -> status.visibility
|
||||||
|
origin == FirDeclarationOrigin.ScriptCustomization.ResultProperty -> status.visibility
|
||||||
else -> Visibilities.Private
|
else -> Visibilities.Private
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -208,6 +208,7 @@ class Fir2IrVisitor(
|
|||||||
return irClass
|
return irClass
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@OptIn(UnexpandedTypeCheck::class)
|
||||||
override fun visitScript(script: FirScript, data: Any?): IrElement {
|
override fun visitScript(script: FirScript, data: Any?): IrElement {
|
||||||
return declarationStorage.getCachedIrScript(script)!!.also { irScript ->
|
return declarationStorage.getCachedIrScript(script)!!.also { irScript ->
|
||||||
irScript.parent = conversionScope.parentFromStack()
|
irScript.parent = conversionScope.parentFromStack()
|
||||||
@@ -246,6 +247,17 @@ class Fir2IrVisitor(
|
|||||||
for (statement in script.statements) {
|
for (statement in script.statements) {
|
||||||
val irStatement = if (statement is FirDeclaration) {
|
val irStatement = if (statement is FirDeclaration) {
|
||||||
when {
|
when {
|
||||||
|
statement is FirProperty && statement.origin == FirDeclarationOrigin.ScriptCustomization.ResultProperty -> {
|
||||||
|
// Generating the result property only for expressions with a meaningful result type
|
||||||
|
// otherwise skip the property and convert the expression into the statement
|
||||||
|
if (statement.returnTypeRef.let { (it.isUnit || it.isNothing || it.isNullableNothing) } == true) {
|
||||||
|
statement.initializer!!.toIrStatement()
|
||||||
|
} else {
|
||||||
|
(statement.accept(this@Fir2IrVisitor, null) as? IrDeclaration)?.also {
|
||||||
|
irScript.resultProperty = (it as? IrProperty)?.symbol
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
statement is FirVariable && statement.isDestructuringDeclarationContainerVariable == true -> {
|
statement is FirVariable && statement.isDestructuringDeclarationContainerVariable == true -> {
|
||||||
statement.convertWithOffsets { startOffset, endOffset ->
|
statement.convertWithOffsets { startOffset, endOffset ->
|
||||||
IrCompositeImpl(
|
IrCompositeImpl(
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ abstract class FirScript : FirDeclaration() {
|
|||||||
abstract override val symbol: FirScriptSymbol
|
abstract override val symbol: FirScriptSymbol
|
||||||
abstract val parameters: List<FirVariable>
|
abstract val parameters: List<FirVariable>
|
||||||
abstract val contextReceivers: List<FirContextReceiver>
|
abstract val contextReceivers: List<FirContextReceiver>
|
||||||
|
abstract val resultPropertyName: Name?
|
||||||
|
|
||||||
override fun <R, D> accept(visitor: FirVisitor<R, D>, data: D): R = visitor.visitScript(this, data)
|
override fun <R, D> accept(visitor: FirVisitor<R, D>, data: D): R = visitor.visitScript(this, data)
|
||||||
|
|
||||||
|
|||||||
+3
@@ -48,6 +48,7 @@ class FirScriptBuilder : FirAnnotationContainerBuilder {
|
|||||||
lateinit var symbol: FirScriptSymbol
|
lateinit var symbol: FirScriptSymbol
|
||||||
val parameters: MutableList<FirVariable> = mutableListOf()
|
val parameters: MutableList<FirVariable> = mutableListOf()
|
||||||
val contextReceivers: MutableList<FirContextReceiver> = mutableListOf()
|
val contextReceivers: MutableList<FirContextReceiver> = mutableListOf()
|
||||||
|
var resultPropertyName: Name? = null
|
||||||
|
|
||||||
override fun build(): FirScript {
|
override fun build(): FirScript {
|
||||||
return FirScriptImpl(
|
return FirScriptImpl(
|
||||||
@@ -62,6 +63,7 @@ class FirScriptBuilder : FirAnnotationContainerBuilder {
|
|||||||
symbol,
|
symbol,
|
||||||
parameters,
|
parameters,
|
||||||
contextReceivers.toMutableOrEmpty(),
|
contextReceivers.toMutableOrEmpty(),
|
||||||
|
resultPropertyName,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -92,5 +94,6 @@ inline fun buildScriptCopy(original: FirScript, init: FirScriptBuilder.() -> Uni
|
|||||||
copyBuilder.symbol = original.symbol
|
copyBuilder.symbol = original.symbol
|
||||||
copyBuilder.parameters.addAll(original.parameters)
|
copyBuilder.parameters.addAll(original.parameters)
|
||||||
copyBuilder.contextReceivers.addAll(original.contextReceivers)
|
copyBuilder.contextReceivers.addAll(original.contextReceivers)
|
||||||
|
copyBuilder.resultPropertyName = original.resultPropertyName
|
||||||
return copyBuilder.apply(init).build()
|
return copyBuilder.apply(init).build()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ internal class FirScriptImpl(
|
|||||||
override val symbol: FirScriptSymbol,
|
override val symbol: FirScriptSymbol,
|
||||||
override val parameters: MutableList<FirVariable>,
|
override val parameters: MutableList<FirVariable>,
|
||||||
override var contextReceivers: MutableOrEmptyList<FirContextReceiver>,
|
override var contextReceivers: MutableOrEmptyList<FirContextReceiver>,
|
||||||
|
override val resultPropertyName: Name?,
|
||||||
) : FirScript() {
|
) : FirScript() {
|
||||||
init {
|
init {
|
||||||
symbol.bind(this)
|
symbol.bind(this)
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
package org.jetbrains.kotlin.fir.declarations
|
package org.jetbrains.kotlin.fir.declarations
|
||||||
|
|
||||||
import org.jetbrains.kotlin.GeneratedDeclarationKey
|
import org.jetbrains.kotlin.GeneratedDeclarationKey
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.utils.FirScriptCustomizationKind
|
||||||
|
|
||||||
sealed class FirDeclarationOrigin(
|
sealed class FirDeclarationOrigin(
|
||||||
private val displayName: String? = null,
|
private val displayName: String? = null,
|
||||||
@@ -36,7 +37,10 @@ sealed class FirDeclarationOrigin(
|
|||||||
object Delegated : FirDeclarationOrigin()
|
object Delegated : FirDeclarationOrigin()
|
||||||
object RenamedForOverride : FirDeclarationOrigin()
|
object RenamedForOverride : FirDeclarationOrigin()
|
||||||
object WrappedIntegerOperator : FirDeclarationOrigin()
|
object WrappedIntegerOperator : FirDeclarationOrigin()
|
||||||
object ScriptCustomization : FirDeclarationOrigin()
|
sealed class ScriptCustomization(val kind: FirScriptCustomizationKind) : FirDeclarationOrigin() {
|
||||||
|
object Default : ScriptCustomization(FirScriptCustomizationKind.DEFAULT)
|
||||||
|
object ResultProperty : ScriptCustomization(FirScriptCustomizationKind.RESULT_PROPERTY)
|
||||||
|
}
|
||||||
class Plugin(val key: GeneratedDeclarationKey) : FirDeclarationOrigin(displayName = "Plugin[$key]", generated = true)
|
class Plugin(val key: GeneratedDeclarationKey) : FirDeclarationOrigin(displayName = "Plugin[$key]", generated = true)
|
||||||
|
|
||||||
override fun toString(): String {
|
override fun toString(): String {
|
||||||
|
|||||||
@@ -7,3 +7,8 @@ package org.jetbrains.kotlin.fir.declarations.utils
|
|||||||
|
|
||||||
const val SCRIPT_SPECIAL_NAME_STRING = "<script>"
|
const val SCRIPT_SPECIAL_NAME_STRING = "<script>"
|
||||||
const val SCRIPT_RECEIVER_NAME_PREFIX = "\$script_receiver"
|
const val SCRIPT_RECEIVER_NAME_PREFIX = "\$script_receiver"
|
||||||
|
|
||||||
|
enum class FirScriptCustomizationKind {
|
||||||
|
DEFAULT,
|
||||||
|
RESULT_PROPERTY
|
||||||
|
}
|
||||||
+1
@@ -493,6 +493,7 @@ object NodeConfigurator : AbstractFieldConfigurator<FirTreeBuilder>(FirTreeBuild
|
|||||||
+symbol("FirScriptSymbol")
|
+symbol("FirScriptSymbol")
|
||||||
+FieldList("parameters", variable, withReplace = false)
|
+FieldList("parameters", variable, withReplace = false)
|
||||||
+fieldList(contextReceiver, useMutableOrEmpty = true)
|
+fieldList(contextReceiver, useMutableOrEmpty = true)
|
||||||
|
+field("resultPropertyName", nameType, nullable = true)
|
||||||
}
|
}
|
||||||
|
|
||||||
codeFragment.configure {
|
codeFragment.configure {
|
||||||
|
|||||||
+1
-2
@@ -20,7 +20,6 @@ import kotlin.script.experimental.host.toScriptSource
|
|||||||
import kotlin.script.experimental.host.with
|
import kotlin.script.experimental.host.with
|
||||||
import kotlin.script.experimental.jvm.*
|
import kotlin.script.experimental.jvm.*
|
||||||
import kotlin.script.experimental.jvm.impl.KJvmCompiledScript
|
import kotlin.script.experimental.jvm.impl.KJvmCompiledScript
|
||||||
import kotlin.script.experimental.jvm.loadDependencies
|
|
||||||
import kotlin.script.experimental.jvm.util.KotlinJars
|
import kotlin.script.experimental.jvm.util.KotlinJars
|
||||||
import kotlin.script.experimental.jvm.util.classpathFromClass
|
import kotlin.script.experimental.jvm.util.classpathFromClass
|
||||||
import kotlin.script.experimental.jvmhost.BasicJvmScriptingHost
|
import kotlin.script.experimental.jvmhost.BasicJvmScriptingHost
|
||||||
@@ -181,7 +180,7 @@ class CachingTest : TestCase() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testLocalDependencyWithExternalLoadAndCache() = expectTestToFailOnK2 {
|
fun testLocalDependencyWithExternalLoadAndCache() {
|
||||||
withTempDir("scriptingTestDepDir") { depDir ->
|
withTempDir("scriptingTestDepDir") { depDir ->
|
||||||
val standardJars = KotlinJars.kotlinScriptStandardJars
|
val standardJars = KotlinJars.kotlinScriptStandardJars
|
||||||
val outJar = makeDependenciesJar(depDir, standardJars)
|
val outJar = makeDependenciesJar(depDir, standardJars)
|
||||||
|
|||||||
+2
-2
@@ -13,7 +13,7 @@ import kotlin.test.assertTrue
|
|||||||
class CapturingTest {
|
class CapturingTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testScriptWithImplicitReceiverAndSimpleCapturing() = expectTestToFailOnK2 {
|
fun testScriptWithImplicitReceiverAndSimpleCapturing() {
|
||||||
// Reproducing (a bit extended) scenario from KT-53947: without the fix, in the presence of the implicit receiver
|
// Reproducing (a bit extended) scenario from KT-53947: without the fix, in the presence of the implicit receiver
|
||||||
// of the same type as the receiver in the `apply` function body, the lowering was incorrectly substituting
|
// of the same type as the receiver in the `apply` function body, the lowering was incorrectly substituting
|
||||||
// the correct receiver with the accessor to the implicit one
|
// the correct receiver with the accessor to the implicit one
|
||||||
@@ -36,7 +36,7 @@ class CapturingTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testScriptWithImplicitReceiverAndNoCapturing() = expectTestToFailOnK2 {
|
fun testScriptWithImplicitReceiverAndNoCapturing() {
|
||||||
// Reproducing (a bit extended) scenario from KT-53947: without the fix, in the presence of the implicit receiver
|
// Reproducing (a bit extended) scenario from KT-53947: without the fix, in the presence of the implicit receiver
|
||||||
// of the same type as the receiver in the `C2.apply` function body, the lowering was incorrectly substituting
|
// of the same type as the receiver in the `C2.apply` function body, the lowering was incorrectly substituting
|
||||||
// the correct receiver with the accessor to the implicit one
|
// the correct receiver with the accessor to the implicit one
|
||||||
|
|||||||
+2
-2
@@ -49,7 +49,7 @@ class ResolveDependenciesTest : TestCase() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testResolveClassFromClasspath() = expectTestToFailOnK2 {
|
fun testResolveClassFromClasspath() {
|
||||||
runScriptAndCheckResult(classAccessScript, configurationWithDependenciesFromClasspath, null, 42)
|
runScriptAndCheckResult(classAccessScript, configurationWithDependenciesFromClasspath, null, 42)
|
||||||
runScriptAndCheckResult(classImportScript, configurationWithDependenciesFromClasspath, null, 42)
|
runScriptAndCheckResult(classImportScript, configurationWithDependenciesFromClasspath, null, 42)
|
||||||
}
|
}
|
||||||
@@ -76,7 +76,7 @@ class ResolveDependenciesTest : TestCase() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testResolveFunAndValFromClasspath() = expectTestToFailOnK2 {
|
fun testResolveFunAndValFromClasspath() {
|
||||||
runScriptAndCheckResult(funAndValAccessScript, configurationWithDependenciesFromClasspath, null, 42)
|
runScriptAndCheckResult(funAndValAccessScript, configurationWithDependenciesFromClasspath, null, 42)
|
||||||
runScriptAndCheckResult(funAndValImportScript, configurationWithDependenciesFromClasspath, null, 42)
|
runScriptAndCheckResult(funAndValImportScript, configurationWithDependenciesFromClasspath, null, 42)
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-3
@@ -65,13 +65,14 @@ class ScriptingHostTest : TestCase() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testValueResult() = expectTestToFailOnK2 {
|
fun testValueResult() {
|
||||||
val evalScriptWithResult = evalScriptWithResult("42")
|
val evalScriptWithResult = evalScriptWithResult("42")
|
||||||
val resVal = evalScriptWithResult as ResultValue.Value
|
val resVal = evalScriptWithResult as ResultValue.Value
|
||||||
Assert.assertEquals(42, resVal.value)
|
Assert.assertEquals(42, resVal.value)
|
||||||
Assert.assertEquals("\$\$result", resVal.name)
|
Assert.assertEquals("\$\$result", resVal.name)
|
||||||
Assert.assertEquals("kotlin.Int", resVal.type)
|
Assert.assertEquals("kotlin.Int", resVal.type)
|
||||||
val resField = resVal.scriptInstance!!::class.java.getDeclaredField("\$\$result")
|
val resField = resVal.scriptInstance!!::class.java.getDeclaredField("\$\$result")
|
||||||
|
resField.setAccessible(true)
|
||||||
Assert.assertEquals(42, resField.get(resVal.scriptInstance!!))
|
Assert.assertEquals(42, resField.get(resVal.scriptInstance!!))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -91,7 +92,7 @@ class ScriptingHostTest : TestCase() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testCustomResultField() = expectTestToFailOnK2 {
|
fun testCustomResultField() {
|
||||||
val resVal = evalScriptWithResult("42") {
|
val resVal = evalScriptWithResult("42") {
|
||||||
resultField("outcome")
|
resultField("outcome")
|
||||||
} as ResultValue.Value
|
} as ResultValue.Value
|
||||||
@@ -245,7 +246,7 @@ class ScriptingHostTest : TestCase() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testProvidedPropertiesNullability() = expectTestToFailOnK2 {
|
fun testProvidedPropertiesNullability() {
|
||||||
val stringType = KotlinType(String::class)
|
val stringType = KotlinType(String::class)
|
||||||
val definition = createJvmScriptDefinitionFromTemplate<SimpleScriptTemplate>(
|
val definition = createJvmScriptDefinitionFromTemplate<SimpleScriptTemplate>(
|
||||||
compilation = {
|
compilation = {
|
||||||
|
|||||||
+1
-1
@@ -120,7 +120,7 @@ class MainKtsIT {
|
|||||||
|
|
||||||
@OptIn(ExperimentalPathApi::class)
|
@OptIn(ExperimentalPathApi::class)
|
||||||
@Test
|
@Test
|
||||||
fun testCacheWithFileLocation() = expectTestToFailOnK2 {
|
fun testCacheWithFileLocation() {
|
||||||
val scriptPath = File("$TEST_DATA_ROOT/script-file-location-default.main.kts").absolutePath
|
val scriptPath = File("$TEST_DATA_ROOT/script-file-location-default.main.kts").absolutePath
|
||||||
val cache = createTempDirectory("main.kts.test")
|
val cache = createTempDirectory("main.kts.test")
|
||||||
val expectedTestOutput = listOf(Regex.escape(scriptPath))
|
val expectedTestOutput = listOf(Regex.escape(scriptPath))
|
||||||
|
|||||||
+3
-3
@@ -78,7 +78,7 @@ class MainKtsTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testResolveRuntimeDeps() = expectTestToFailOnK2 {
|
fun testResolveRuntimeDeps() {
|
||||||
val resOk = evalFile(File("$TEST_DATA_ROOT/resolve-with-runtime.main.kts"))
|
val resOk = evalFile(File("$TEST_DATA_ROOT/resolve-with-runtime.main.kts"))
|
||||||
assertSucceeded(resOk)
|
assertSucceeded(resOk)
|
||||||
|
|
||||||
@@ -179,7 +179,7 @@ class MainKtsTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testScriptFileLocationDefaultVariable() = expectTestToFailOnK2 {
|
fun testScriptFileLocationDefaultVariable() {
|
||||||
val resOk = evalFile(File("$TEST_DATA_ROOT/script-file-location-default.main.kts"))
|
val resOk = evalFile(File("$TEST_DATA_ROOT/script-file-location-default.main.kts"))
|
||||||
assertSucceeded(resOk)
|
assertSucceeded(resOk)
|
||||||
val resultValue = resOk.valueOrThrow().returnValue
|
val resultValue = resOk.valueOrThrow().returnValue
|
||||||
@@ -192,7 +192,7 @@ class MainKtsTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testScriptFileLocationCustomizedVariable() = expectTestToFailOnK2 {
|
fun testScriptFileLocationCustomizedVariable() {
|
||||||
val resOk = evalFile(File("$TEST_DATA_ROOT/script-file-location-customized.main.kts"))
|
val resOk = evalFile(File("$TEST_DATA_ROOT/script-file-location-customized.main.kts"))
|
||||||
assertSucceeded(resOk)
|
assertSucceeded(resOk)
|
||||||
val resultValue = resOk.valueOrThrow().returnValue
|
val resultValue = resOk.valueOrThrow().returnValue
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ dependencies {
|
|||||||
compileOnly(project(":compiler:plugin-api"))
|
compileOnly(project(":compiler:plugin-api"))
|
||||||
compileOnly(project(":compiler:fir:entrypoint"))
|
compileOnly(project(":compiler:fir:entrypoint"))
|
||||||
compileOnly(project(":compiler:fir:raw-fir:raw-fir.common"))
|
compileOnly(project(":compiler:fir:raw-fir:raw-fir.common"))
|
||||||
|
compileOnly(project(":compiler:fir:tree"))
|
||||||
compileOnly(project(":compiler:cli"))
|
compileOnly(project(":compiler:cli"))
|
||||||
compileOnly(project(":core:descriptors.runtime"))
|
compileOnly(project(":core:descriptors.runtime"))
|
||||||
compileOnly(project(":compiler:ir.tree"))
|
compileOnly(project(":compiler:ir.tree"))
|
||||||
|
|||||||
+36
-3
@@ -16,8 +16,10 @@ import org.jetbrains.kotlin.fir.builder.FirScriptConfiguratorExtension.Factory
|
|||||||
import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin
|
import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin
|
||||||
import org.jetbrains.kotlin.fir.declarations.builder.*
|
import org.jetbrains.kotlin.fir.declarations.builder.*
|
||||||
import org.jetbrains.kotlin.fir.declarations.impl.FirDeclarationStatusImpl
|
import org.jetbrains.kotlin.fir.declarations.impl.FirDeclarationStatusImpl
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertyGetter
|
||||||
import org.jetbrains.kotlin.fir.declarations.primaryConstructorIfAny
|
import org.jetbrains.kotlin.fir.declarations.primaryConstructorIfAny
|
||||||
import org.jetbrains.kotlin.fir.declarations.utils.SCRIPT_SPECIAL_NAME_STRING
|
import org.jetbrains.kotlin.fir.declarations.utils.SCRIPT_SPECIAL_NAME_STRING
|
||||||
|
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||||
import org.jetbrains.kotlin.fir.moduleData
|
import org.jetbrains.kotlin.fir.moduleData
|
||||||
import org.jetbrains.kotlin.fir.resolve.providers.dependenciesSymbolProvider
|
import org.jetbrains.kotlin.fir.resolve.providers.dependenciesSymbolProvider
|
||||||
import org.jetbrains.kotlin.fir.symbols.SymbolInternals
|
import org.jetbrains.kotlin.fir.symbols.SymbolInternals
|
||||||
@@ -67,7 +69,7 @@ class FirScriptConfiguratorExtensionImpl(
|
|||||||
parameters.add(
|
parameters.add(
|
||||||
buildProperty {
|
buildProperty {
|
||||||
moduleData = session.moduleData
|
moduleData = session.moduleData
|
||||||
origin = FirDeclarationOrigin.ScriptCustomization
|
origin = FirDeclarationOrigin.ScriptCustomization.Default
|
||||||
// TODO: copy type parameters?
|
// TODO: copy type parameters?
|
||||||
returnTypeRef = baseCtorParameter.returnTypeRef
|
returnTypeRef = baseCtorParameter.returnTypeRef
|
||||||
name = baseCtorParameter.name
|
name = baseCtorParameter.name
|
||||||
@@ -83,7 +85,7 @@ class FirScriptConfiguratorExtensionImpl(
|
|||||||
configuration[ScriptCompilationConfiguration.implicitReceivers]?.forEach { implicitReceiver ->
|
configuration[ScriptCompilationConfiguration.implicitReceivers]?.forEach { implicitReceiver ->
|
||||||
contextReceivers.add(buildContextReceiverWithFqName(FqName.fromSegments(implicitReceiver.typeName.split("."))))
|
contextReceivers.add(buildContextReceiverWithFqName(FqName.fromSegments(implicitReceiver.typeName.split("."))))
|
||||||
}
|
}
|
||||||
configuration[ScriptCompilationConfiguration.providedProperties]?.forEach { propertyName, propertyType ->
|
configuration[ScriptCompilationConfiguration.providedProperties]?.forEach { (propertyName, propertyType) ->
|
||||||
val typeRef = buildUserTypeRef {
|
val typeRef = buildUserTypeRef {
|
||||||
isMarkedNullable = propertyType.isNullable
|
isMarkedNullable = propertyType.isNullable
|
||||||
propertyType.typeName.split(".").forEach {
|
propertyType.typeName.split(".").forEach {
|
||||||
@@ -93,7 +95,7 @@ class FirScriptConfiguratorExtensionImpl(
|
|||||||
parameters.add(
|
parameters.add(
|
||||||
buildProperty {
|
buildProperty {
|
||||||
moduleData = session.moduleData
|
moduleData = session.moduleData
|
||||||
origin = FirDeclarationOrigin.ScriptCustomization
|
origin = FirDeclarationOrigin.ScriptCustomization.Default
|
||||||
returnTypeRef = typeRef
|
returnTypeRef = typeRef
|
||||||
name = Name.identifier(propertyName)
|
name = Name.identifier(propertyName)
|
||||||
symbol = FirPropertySymbol(name)
|
symbol = FirPropertySymbol(name)
|
||||||
@@ -125,6 +127,37 @@ class FirScriptConfiguratorExtensionImpl(
|
|||||||
configuration[ScriptCompilationConfiguration.annotationsForSamWithReceivers]?.forEach {
|
configuration[ScriptCompilationConfiguration.annotationsForSamWithReceivers]?.forEach {
|
||||||
_knownAnnotationsForSamWithReceiver.add(it.typeName)
|
_knownAnnotationsForSamWithReceiver.add(it.typeName)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
configuration[ScriptCompilationConfiguration.resultField]?.takeIf { it.isNotBlank() }?.let { resultFieldName ->
|
||||||
|
val lastExpression = statements.lastOrNull()
|
||||||
|
if (lastExpression != null && lastExpression is FirExpression) {
|
||||||
|
statements.removeAt(statements.size - 1)
|
||||||
|
statements.add(
|
||||||
|
buildProperty {
|
||||||
|
this.name = Name.identifier(resultFieldName)
|
||||||
|
this.symbol = FirPropertySymbol(this.name)
|
||||||
|
source = lastExpression.source
|
||||||
|
moduleData = session.moduleData
|
||||||
|
origin = FirDeclarationOrigin.ScriptCustomization.ResultProperty
|
||||||
|
initializer = lastExpression
|
||||||
|
returnTypeRef = lastExpression.typeRef
|
||||||
|
getter = FirDefaultPropertyGetter(
|
||||||
|
lastExpression.source,
|
||||||
|
session.moduleData,
|
||||||
|
FirDeclarationOrigin.ScriptCustomization.ResultProperty,
|
||||||
|
lastExpression.typeRef,
|
||||||
|
Visibilities.Public,
|
||||||
|
this.symbol,
|
||||||
|
)
|
||||||
|
status = FirDeclarationStatusImpl(Visibilities.Public, Modality.FINAL)
|
||||||
|
isLocal = false
|
||||||
|
isVar = false
|
||||||
|
}.also {
|
||||||
|
resultPropertyName = it.name
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun KtSourceFile.asString() = path ?: name
|
private fun KtSourceFile.asString() = path ?: name
|
||||||
|
|||||||
+3
-4
@@ -26,12 +26,12 @@ class ScriptingWithCliCompilerTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testResultValue() = expectTestToFailOnK2 {
|
fun testResultValue() {
|
||||||
runWithK2JVMCompiler("$TEST_DATA_DIR/integration/intResult.kts", listOf("10"))
|
runWithK2JVMCompiler("$TEST_DATA_DIR/integration/intResult.kts", listOf("10"))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testResultValueViaKotlinc() = expectTestToFailOnK2 {
|
fun testResultValueViaKotlinc() {
|
||||||
runWithKotlinc("$TEST_DATA_DIR/integration/intResult.kts", listOf("10"))
|
runWithKotlinc("$TEST_DATA_DIR/integration/intResult.kts", listOf("10"))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -132,14 +132,13 @@ class ScriptingWithCliCompilerTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testExpressionWithComma() = expectTestToFailOnK2 {
|
fun testExpressionWithComma() {
|
||||||
runWithK2JVMCompiler(
|
runWithK2JVMCompiler(
|
||||||
arrayOf(
|
arrayOf(
|
||||||
"-expression",
|
"-expression",
|
||||||
"listOf(1,2)"
|
"listOf(1,2)"
|
||||||
),
|
),
|
||||||
listOf("\\[1, 2\\]"),
|
listOf("\\[1, 2\\]"),
|
||||||
expectErrorOnK2 = true
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-3
@@ -1,6 +1,5 @@
|
|||||||
import junit.framework.TestCase
|
import junit.framework.TestCase
|
||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
import org.jetbrains.kotlin.scripting.compiler.plugin.expectTestToFailOnK2
|
|
||||||
import org.jetbrains.kotlin.scripting.compiler.plugin.impl.ScriptJvmCompilerIsolated
|
import org.jetbrains.kotlin.scripting.compiler.plugin.impl.ScriptJvmCompilerIsolated
|
||||||
import org.jetbrains.kotlin.scripting.compiler.test.assertEqualsTrimmed
|
import org.jetbrains.kotlin.scripting.compiler.test.assertEqualsTrimmed
|
||||||
import java.io.ByteArrayOutputStream
|
import java.io.ByteArrayOutputStream
|
||||||
@@ -19,7 +18,7 @@ import kotlin.script.experimental.jvm.util.renderError
|
|||||||
|
|
||||||
class ScriptEvaluationTest : TestCase() {
|
class ScriptEvaluationTest : TestCase() {
|
||||||
|
|
||||||
fun testExceptionWithCause() = expectTestToFailOnK2 {
|
fun testExceptionWithCause() {
|
||||||
checkEvaluateAsError(
|
checkEvaluateAsError(
|
||||||
"""
|
"""
|
||||||
try {
|
try {
|
||||||
@@ -38,7 +37,7 @@ class ScriptEvaluationTest : TestCase() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// KT-19423
|
// KT-19423
|
||||||
fun testClassCapturingScriptInstance() = expectTestToFailOnK2 {
|
fun testClassCapturingScriptInstance() {
|
||||||
val res = checkEvaluate(
|
val res = checkEvaluate(
|
||||||
"""
|
"""
|
||||||
val used = "abc"
|
val used = "abc"
|
||||||
|
|||||||
Reference in New Issue
Block a user