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 // LANGUAGE_VERSION: 1.2
// WITH_RUNTIME // WITH_RUNTIME
// IGNORE_BACKEND: JS, NATIVE // IGNORE_BACKEND: NATIVE
import kotlin.UninitializedPropertyAccessException import kotlin.UninitializedPropertyAccessException
@@ -1,6 +1,6 @@
// LANGUAGE_VERSION: 1.2 // LANGUAGE_VERSION: 1.2
// WITH_RUNTIME // WITH_RUNTIME
// IGNORE_BACKEND: JS, NATIVE // IGNORE_BACKEND: NATIVE
import kotlin.UninitializedPropertyAccessException import kotlin.UninitializedPropertyAccessException
@@ -1,6 +1,6 @@
// LANGUAGE_VERSION: 1.2 // LANGUAGE_VERSION: 1.2
// WITH_RUNTIME // WITH_RUNTIME
// IGNORE_BACKEND: JS, NATIVE // IGNORE_BACKEND: NATIVE
import kotlin.UninitializedPropertyAccessException import kotlin.UninitializedPropertyAccessException
@@ -1,6 +1,6 @@
// LANGUAGE_VERSION: 1.2 // LANGUAGE_VERSION: 1.2
// WITH_RUNTIME // WITH_RUNTIME
// IGNORE_BACKEND: JS, NATIVE // IGNORE_BACKEND: NATIVE
import kotlin.UninitializedPropertyAccessException import kotlin.UninitializedPropertyAccessException
@@ -15087,49 +15087,25 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
@TestMetadata("uninitializedCapturedMemberAccess.kt") @TestMetadata("uninitializedCapturedMemberAccess.kt")
public void testUninitializedCapturedMemberAccess() throws Exception { public void testUninitializedCapturedMemberAccess() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/properties/lateinit/local/uninitializedCapturedMemberAccess.kt"); String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/properties/lateinit/local/uninitializedCapturedMemberAccess.kt");
try { doTest(fileName);
doTest(fileName);
}
catch (Throwable ignore) {
return;
}
throw new AssertionError("Looks like this test can be unmuted. Remove IGNORE_BACKEND directive for that.");
} }
@TestMetadata("uninitializedCapturedRead.kt") @TestMetadata("uninitializedCapturedRead.kt")
public void testUninitializedCapturedRead() throws Exception { public void testUninitializedCapturedRead() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/properties/lateinit/local/uninitializedCapturedRead.kt"); String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/properties/lateinit/local/uninitializedCapturedRead.kt");
try { doTest(fileName);
doTest(fileName);
}
catch (Throwable ignore) {
return;
}
throw new AssertionError("Looks like this test can be unmuted. Remove IGNORE_BACKEND directive for that.");
} }
@TestMetadata("uninitializedMemberAccess.kt") @TestMetadata("uninitializedMemberAccess.kt")
public void testUninitializedMemberAccess() throws Exception { public void testUninitializedMemberAccess() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/properties/lateinit/local/uninitializedMemberAccess.kt"); String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/properties/lateinit/local/uninitializedMemberAccess.kt");
try { doTest(fileName);
doTest(fileName);
}
catch (Throwable ignore) {
return;
}
throw new AssertionError("Looks like this test can be unmuted. Remove IGNORE_BACKEND directive for that.");
} }
@TestMetadata("uninitializedRead.kt") @TestMetadata("uninitializedRead.kt")
public void testUninitializedRead() throws Exception { public void testUninitializedRead() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/properties/lateinit/local/uninitializedRead.kt"); String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/properties/lateinit/local/uninitializedRead.kt");
try { doTest(fileName);
doTest(fileName);
}
catch (Throwable ignore) {
return;
}
throw new AssertionError("Looks like this test can be unmuted. Remove IGNORE_BACKEND directive for that.");
} }
} }
@@ -19,10 +19,10 @@ package org.jetbrains.kotlin.js.translate.reference;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.descriptors.*; import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.js.backend.ast.JsBinaryOperation; import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor;
import org.jetbrains.kotlin.js.backend.ast.JsExpression; import org.jetbrains.kotlin.js.backend.ast.*;
import org.jetbrains.kotlin.js.backend.ast.JsNameRef;
import org.jetbrains.kotlin.js.translate.callTranslator.CallTranslator; 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.context.TranslationContext;
import org.jetbrains.kotlin.js.translate.general.AbstractTranslator; import org.jetbrains.kotlin.js.translate.general.AbstractTranslator;
import org.jetbrains.kotlin.psi.KtReferenceExpression; 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; return e;
} }