diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/BoxJsTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/BoxJsTestGenerated.java index 89bae4d7a3f..e88c70b095b 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/BoxJsTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/BoxJsTestGenerated.java @@ -1400,6 +1400,12 @@ public class BoxJsTestGenerated extends AbstractBoxJsTest { doTest(fileName); } + @TestMetadata("propertySideEffect.kt") + public void testPropertySideEffect() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/box/dynamic/propertySideEffect.kt"); + doTest(fileName); + } + @TestMetadata("setByBrackets.kt") public void testSetByBrackets() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/box/dynamic/setByBrackets.kt"); diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/utils/JsDescriptorUtils.java b/js/js.translator/src/org/jetbrains/kotlin/js/translate/utils/JsDescriptorUtils.java index 3cd515d4a34..73d2617b6fa 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/utils/JsDescriptorUtils.java +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/utils/JsDescriptorUtils.java @@ -30,6 +30,7 @@ import org.jetbrains.kotlin.js.translate.context.TranslationContext; import org.jetbrains.kotlin.name.Name; import org.jetbrains.kotlin.psi.KtExpression; import org.jetbrains.kotlin.resolve.DescriptorUtils; +import org.jetbrains.kotlin.resolve.calls.tasks.DynamicCallsKt; import org.jetbrains.kotlin.resolve.scopes.receivers.ImplicitReceiver; import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue; import org.jetbrains.kotlin.types.KotlinType; @@ -137,8 +138,8 @@ public final class JsDescriptorUtils { } public static boolean sideEffectsPossibleOnRead(@NotNull PropertyDescriptor property) { - return !isDefaultAccessor(property.getGetter()) || ModalityKt.isOverridableOrOverrides(property) || - isStaticInitializationPossible(property); + return DynamicCallsKt.isDynamic(property) || !isDefaultAccessor(property.getGetter()) || + ModalityKt.isOverridableOrOverrides(property) || isStaticInitializationPossible(property); } private static boolean isStaticInitializationPossible(PropertyDescriptor property) { diff --git a/js/js.translator/testData/box/dynamic/propertySideEffect.js b/js/js.translator/testData/box/dynamic/propertySideEffect.js new file mode 100644 index 00000000000..974c6c3d536 --- /dev/null +++ b/js/js.translator/testData/box/dynamic/propertySideEffect.js @@ -0,0 +1,10 @@ +var log = ""; + +function C() { +} +Object.defineProperty(C.prototype, "foo", { + "get" : function () { + log += "foo called"; + return "OK" + } +}); \ No newline at end of file diff --git a/js/js.translator/testData/box/dynamic/propertySideEffect.kt b/js/js.translator/testData/box/dynamic/propertySideEffect.kt new file mode 100644 index 00000000000..afb9a518c7b --- /dev/null +++ b/js/js.translator/testData/box/dynamic/propertySideEffect.kt @@ -0,0 +1,13 @@ +external class C + +inline val C.foo: String + get() = asDynamic().foo + +external val log: String + +fun box(): String { + val c = C() + c.foo + if (log != "foo called") return "fail: $log" + return "OK" +} \ No newline at end of file