JS: throw exception on access to an uninitialized local variable (KT-20248 fixed)

This commit is contained in:
Anton Bannykh
2017-09-14 19:49:39 +03:00
parent aa442860c2
commit 373bd5ff17
6 changed files with 19 additions and 35 deletions
@@ -1,6 +1,6 @@
// LANGUAGE_VERSION: 1.2
// WITH_RUNTIME
// IGNORE_BACKEND: JS, NATIVE
// IGNORE_BACKEND: NATIVE
import kotlin.UninitializedPropertyAccessException
@@ -1,6 +1,6 @@
// LANGUAGE_VERSION: 1.2
// WITH_RUNTIME
// IGNORE_BACKEND: JS, NATIVE
// IGNORE_BACKEND: NATIVE
import kotlin.UninitializedPropertyAccessException
@@ -1,6 +1,6 @@
// LANGUAGE_VERSION: 1.2
// WITH_RUNTIME
// IGNORE_BACKEND: JS, NATIVE
// IGNORE_BACKEND: NATIVE
import kotlin.UninitializedPropertyAccessException
@@ -1,6 +1,6 @@
// LANGUAGE_VERSION: 1.2
// WITH_RUNTIME
// IGNORE_BACKEND: JS, NATIVE
// IGNORE_BACKEND: NATIVE
import kotlin.UninitializedPropertyAccessException
@@ -15087,49 +15087,25 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
@TestMetadata("uninitializedCapturedMemberAccess.kt")
public void testUninitializedCapturedMemberAccess() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/properties/lateinit/local/uninitializedCapturedMemberAccess.kt");
try {
doTest(fileName);
}
catch (Throwable ignore) {
return;
}
throw new AssertionError("Looks like this test can be unmuted. Remove IGNORE_BACKEND directive for that.");
doTest(fileName);
}
@TestMetadata("uninitializedCapturedRead.kt")
public void testUninitializedCapturedRead() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/properties/lateinit/local/uninitializedCapturedRead.kt");
try {
doTest(fileName);
}
catch (Throwable ignore) {
return;
}
throw new AssertionError("Looks like this test can be unmuted. Remove IGNORE_BACKEND directive for that.");
doTest(fileName);
}
@TestMetadata("uninitializedMemberAccess.kt")
public void testUninitializedMemberAccess() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/properties/lateinit/local/uninitializedMemberAccess.kt");
try {
doTest(fileName);
}
catch (Throwable ignore) {
return;
}
throw new AssertionError("Looks like this test can be unmuted. Remove IGNORE_BACKEND directive for that.");
doTest(fileName);
}
@TestMetadata("uninitializedRead.kt")
public void testUninitializedRead() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/properties/lateinit/local/uninitializedRead.kt");
try {
doTest(fileName);
}
catch (Throwable ignore) {
return;
}
throw new AssertionError("Looks like this test can be unmuted. Remove IGNORE_BACKEND directive for that.");
doTest(fileName);
}
}
@@ -19,10 +19,10 @@ package org.jetbrains.kotlin.js.translate.reference;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.js.backend.ast.JsBinaryOperation;
import org.jetbrains.kotlin.js.backend.ast.JsExpression;
import org.jetbrains.kotlin.js.backend.ast.JsNameRef;
import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor;
import org.jetbrains.kotlin.js.backend.ast.*;
import org.jetbrains.kotlin.js.translate.callTranslator.CallTranslator;
import org.jetbrains.kotlin.js.translate.context.Namer;
import org.jetbrains.kotlin.js.translate.context.TranslationContext;
import org.jetbrains.kotlin.js.translate.general.AbstractTranslator;
import org.jetbrains.kotlin.psi.KtReferenceExpression;
@@ -80,6 +80,14 @@ public class VariableAccessTranslator extends AbstractTranslator implements Acce
}
}
}
else if (original instanceof LocalVariableDescriptor) {
LocalVariableDescriptor originalLocal = (LocalVariableDescriptor) original;
if (originalLocal.isLateInit()) {
JsInvocation throwInvocation = new JsInvocation(Namer.throwUninitializedPropertyAccessExceptionFunRef(),
new JsStringLiteral(originalLocal.getName().asString()));
return new JsConditional(new JsBinaryOperation(JsBinaryOperator.EQ, e, new JsNullLiteral()), throwInvocation, e);
}
}
return e;
}