JS: add boxing/unboxing to default accessors of non-simple properties
See KT-21421
This commit is contained in:
@@ -833,6 +833,12 @@ public class BoxJsTestGenerated extends AbstractBoxJsTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("defaultAccessors.kt")
|
||||
public void testDefaultAccessors() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/box/coercion/defaultAccessors.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("derivedFunctionReturningChar.kt")
|
||||
public void testDerivedFunctionReturningChar() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/box/coercion/derivedFunctionReturningChar.kt");
|
||||
|
||||
+11
-3
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.descriptors.impl.LocalVariableAccessorDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor
|
||||
import org.jetbrains.kotlin.js.backend.ast.*
|
||||
import org.jetbrains.kotlin.js.backend.ast.metadata.synthetic
|
||||
import org.jetbrains.kotlin.js.backend.ast.metadata.type
|
||||
import org.jetbrains.kotlin.js.translate.callTranslator.CallTranslator
|
||||
import org.jetbrains.kotlin.js.translate.context.Namer
|
||||
import org.jetbrains.kotlin.js.translate.context.Namer.getReceiverParameterName
|
||||
@@ -94,13 +95,14 @@ class DefaultPropertyTranslator(
|
||||
|
||||
assert(!descriptor.isExtension) { "Unexpected extension property $descriptor}" }
|
||||
assert(descriptor is PropertyDescriptor) { "Property descriptor expected: $descriptor" }
|
||||
val result = backingFieldReference(context(), descriptor as PropertyDescriptor)
|
||||
var result: JsExpression = backingFieldReference(context(), descriptor as PropertyDescriptor)
|
||||
if (getterDescriptor is PropertyAccessorDescriptor && getterDescriptor.correspondingProperty.isLateInit) {
|
||||
val throwFunction = context().getReferenceToIntrinsic(Namer.THROW_UNINITIALIZED_PROPERTY_ACCESS_EXCEPTION)
|
||||
function.body.statements += JsIf(JsBinaryOperation(JsBinaryOperator.EQ, result, JsNullLiteral()),
|
||||
JsReturn(JsInvocation(throwFunction,
|
||||
JsStringLiteral(getterDescriptor.correspondingProperty.name.asString()))))
|
||||
}
|
||||
result = TranslationUtils.coerce(context(), result, TranslationUtils.getReturnTypeForCoercion(getterDescriptor))
|
||||
function.body.statements += JsReturn(result).apply { source = descriptor.source.getPsi() }
|
||||
}
|
||||
|
||||
@@ -126,7 +128,8 @@ class DefaultPropertyTranslator(
|
||||
assert(setterDescriptor.valueParameters.size == 1) { "Setter must have 1 parameter" }
|
||||
val correspondingPropertyName = setterDescriptor.correspondingVariable.name.asString()
|
||||
val valueParameter = function.addParameter(correspondingPropertyName).name
|
||||
val withAliased = context().innerContextWithAliased(setterDescriptor.valueParameters[0], valueParameter.makeRef())
|
||||
val parameter = setterDescriptor.valueParameters[0]
|
||||
val withAliased = context().innerContextWithAliased(parameter, valueParameter.makeRef())
|
||||
val delegatedCall = bindingContext()[BindingContext.DELEGATED_PROPERTY_RESOLVED_CALL, setterDescriptor]
|
||||
|
||||
if (delegatedCall != null) {
|
||||
@@ -142,7 +145,12 @@ class DefaultPropertyTranslator(
|
||||
else {
|
||||
assert(!descriptor.isExtension) { "Unexpected extension property $descriptor}" }
|
||||
assert(descriptor is PropertyDescriptor) { "Property descriptor expected: $descriptor" }
|
||||
val assignment = assignmentToBackingField(withAliased, descriptor as PropertyDescriptor, valueParameter.makeRef())
|
||||
var value: JsExpression = valueParameter.makeRef().apply {
|
||||
type = TranslationUtils.getReturnTypeForCoercion(setterDescriptor.correspondingVariable)
|
||||
}
|
||||
value = TranslationUtils.coerce(
|
||||
context(), value, TranslationUtils.getReturnTypeForCoercion(setterDescriptor.correspondingVariable, true))
|
||||
val assignment = assignmentToBackingField(withAliased, descriptor as PropertyDescriptor, value)
|
||||
function.addStatement(assignment.apply { source = descriptor.source.getPsi() }.makeStmt())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
// EXPECTED_REACHABLE_NODES: 1140
|
||||
interface I {
|
||||
val a: Char
|
||||
}
|
||||
|
||||
object X : I {
|
||||
override var a = '#'
|
||||
}
|
||||
|
||||
var result = ""
|
||||
|
||||
object Y : I {
|
||||
override var a = '#'
|
||||
get() {
|
||||
result = jsTypeOf(field.asDynamic())
|
||||
return field
|
||||
}
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val t = jsTypeOf(X.asDynamic().a)
|
||||
if (t != "object") return "fail1: $t"
|
||||
|
||||
Y.a = '@'
|
||||
Y.a
|
||||
if (result != "number") return "fail2: $result"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
Reference in New Issue
Block a user