fix another type inference problem with external structures
This commit is contained in:
parent
7af6d3925e
commit
90e46a3fff
@ -21,7 +21,7 @@ import org.jetbrains.kotlin.gradle.ExperimentalWasmDsl
|
|||||||
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
|
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
|
||||||
|
|
||||||
group = "net.sergeych"
|
group = "net.sergeych"
|
||||||
version = "1.5.6"
|
version = "1.5.7-SNAPSHOT"
|
||||||
|
|
||||||
// Removed legacy buildscript classpath declarations; plugins are applied via the plugins DSL below
|
// Removed legacy buildscript classpath declarations; plugins are applied via the plugins DSL below
|
||||||
|
|
||||||
|
|||||||
@ -6702,7 +6702,19 @@ class Compiler(
|
|||||||
private fun inferCallReturnTypeDecl(ref: CallRef): TypeDecl? {
|
private fun inferCallReturnTypeDecl(ref: CallRef): TypeDecl? {
|
||||||
callReturnTypeDeclByRef[ref]?.let { return it }
|
callReturnTypeDeclByRef[ref]?.let { return it }
|
||||||
val targetDecl = (resolveReceiverTypeDecl(ref.target) ?: seedTypeDeclFromRef(ref.target)) as? TypeDecl.Function
|
val targetDecl = (resolveReceiverTypeDecl(ref.target) ?: seedTypeDeclFromRef(ref.target)) as? TypeDecl.Function
|
||||||
|
?: run {
|
||||||
|
val targetName = when (val target = ref.target) {
|
||||||
|
is LocalVarRef -> target.name
|
||||||
|
is FastLocalVarRef -> target.name
|
||||||
|
is LocalSlotRef -> target.name
|
||||||
|
else -> null
|
||||||
|
} ?: return null
|
||||||
|
val declaredReturn = callableReturnTypeDeclByName[targetName]
|
||||||
|
?: (seedTypeDeclByName(targetName) as? TypeDecl.Function)?.returnType
|
||||||
?: return null
|
?: return null
|
||||||
|
callReturnTypeDeclByRef[ref] = declaredReturn
|
||||||
|
return declaredReturn
|
||||||
|
}
|
||||||
val bindings = mutableMapOf<String, TypeDecl>()
|
val bindings = mutableMapOf<String, TypeDecl>()
|
||||||
val paramList = mutableListOf<TypeDecl>()
|
val paramList = mutableListOf<TypeDecl>()
|
||||||
targetDecl.receiver?.let { paramList += it }
|
targetDecl.receiver?.let { paramList += it }
|
||||||
|
|||||||
@ -19,13 +19,10 @@ package net.sergeych.lyng
|
|||||||
|
|
||||||
import kotlinx.coroutines.test.runTest
|
import kotlinx.coroutines.test.runTest
|
||||||
import net.sergeych.lyng.bridge.bind
|
import net.sergeych.lyng.bridge.bind
|
||||||
import net.sergeych.lyng.obj.ObjRecord
|
|
||||||
import net.sergeych.lyng.bridge.data
|
|
||||||
import net.sergeych.lyng.bridge.bindGlobalVar
|
import net.sergeych.lyng.bridge.bindGlobalVar
|
||||||
|
import net.sergeych.lyng.bridge.data
|
||||||
import net.sergeych.lyng.bridge.globalBinder
|
import net.sergeych.lyng.bridge.globalBinder
|
||||||
import net.sergeych.lyng.obj.ObjFalse
|
import net.sergeych.lyng.obj.*
|
||||||
import net.sergeych.lyng.obj.ObjInstance
|
|
||||||
import net.sergeych.lyng.obj.ObjTrue
|
|
||||||
import kotlin.test.Test
|
import kotlin.test.Test
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
@ -138,12 +135,65 @@ class GlobalPropertyCaptureRegressionTest {
|
|||||||
|
|
||||||
assertEquals(77.0, x, "bound extern var should stay live after extern class property branch in child scope")
|
assertEquals(77.0, x, "bound extern var should stay live after extern class property branch in child scope")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun externPropertyOnExternFunctionResultCanAssignExternGlobalVar() = runTest {
|
||||||
|
val base = Script.newScope() as ModuleScope
|
||||||
|
var x = 0L
|
||||||
|
|
||||||
|
base.eval(
|
||||||
|
"""
|
||||||
|
extern var X: Int
|
||||||
|
|
||||||
|
class InputResult {
|
||||||
|
extern val value: Int?
|
||||||
|
}
|
||||||
|
""".trimIndent()
|
||||||
|
)
|
||||||
|
|
||||||
|
base.bind("InputResult") {
|
||||||
|
addVal("value") {
|
||||||
|
ObjInt.of(thisObjData<InputPayload>().value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
base.globalBinder().bindGlobalVar(
|
||||||
|
name = "X",
|
||||||
|
get = { x },
|
||||||
|
set = { x = it }
|
||||||
|
)
|
||||||
|
|
||||||
|
base.globalBinder().bindGlobalFunRaw("input") { _, _ ->
|
||||||
|
val instance = base.requireClass("InputResult").callOn(base.createChildScope()) as ObjInstance
|
||||||
|
instance.data = InputPayload(101L)
|
||||||
|
instance
|
||||||
|
}
|
||||||
|
|
||||||
|
val child = base.createChildScope()
|
||||||
|
child.eval(
|
||||||
|
"""
|
||||||
|
extern fun input(): InputResult
|
||||||
|
|
||||||
|
fun main() {
|
||||||
|
X = input().value
|
||||||
|
}
|
||||||
|
""".trimIndent()
|
||||||
|
)
|
||||||
|
|
||||||
|
child.eval("main()")
|
||||||
|
|
||||||
|
assertEquals(101L, x, "extern property read directly from extern function result should assign live extern var")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private data class ChoicePayload(
|
private data class ChoicePayload(
|
||||||
val isSkip: Boolean,
|
val isSkip: Boolean,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
private data class InputPayload(
|
||||||
|
val value: Long,
|
||||||
|
)
|
||||||
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
private fun <T> ScopeFacade.thisObjData(): T {
|
private fun <T> ScopeFacade.thisObjData(): T {
|
||||||
val instance = thisObj as? ObjInstance ?: raiseClassCastError("Expected result object instance")
|
val instance = thisObj as? ObjInstance ?: raiseClassCastError("Expected result object instance")
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user