From 4ca127ecb3a7974e7e5bff56973bf8c11d1b0f1d Mon Sep 17 00:00:00 2001 From: Yan Zhulanow Date: Fri, 4 Sep 2015 17:13:55 +0300 Subject: [PATCH] Create custom exception for lateinit --- .../jetbrains/kotlin/codegen/StackValue.java | 3 ++- .../properties/lateinit/accessorException.kt | 2 +- .../box/properties/lateinit/exceptionField.kt | 2 +- .../properties/lateinit/exceptionGetter.kt | 2 +- .../properties/lateinit/overrideException.kt | 2 +- .../fullJdk/lateinitVisibility.kt | 10 ++++++++-- .../UninitializedPropertyAccessException.kt | 19 +++++++++++++++++++ .../src/kotlin/jvm/internal/Intrinsics.java | 5 +++++ 8 files changed, 38 insertions(+), 7 deletions(-) create mode 100644 core/runtime.jvm/src/kotlin/UninitializedPropertyAccessException.kt diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/StackValue.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/StackValue.java index 76ebb889430..6860e949462 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/StackValue.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/StackValue.java @@ -1042,7 +1042,8 @@ public abstract class StackValue { v.dup(); Label ok = new Label(); v.ifnonnull(ok); - v.invokestatic(IntrinsicMethods.INTRINSICS_CLASS_NAME, "throwNpe", "()V", false); + v.visitLdcInsn(descriptor.getName().asString()); + v.invokestatic(IntrinsicMethods.INTRINSICS_CLASS_NAME, "throwUninitializedPropertyAccessException", "(Ljava/lang/String;)V", false); v.mark(ok); } diff --git a/compiler/testData/codegen/box/properties/lateinit/accessorException.kt b/compiler/testData/codegen/box/properties/lateinit/accessorException.kt index b878c563238..8650a0fad11 100644 --- a/compiler/testData/codegen/box/properties/lateinit/accessorException.kt +++ b/compiler/testData/codegen/box/properties/lateinit/accessorException.kt @@ -3,7 +3,7 @@ public class A { fun getMyStr(): String { try { val a = str - } catch (e: NullPointerException) { + } catch (e: RuntimeException) { return "OK" } diff --git a/compiler/testData/codegen/box/properties/lateinit/exceptionField.kt b/compiler/testData/codegen/box/properties/lateinit/exceptionField.kt index ce5f7e5f9e9..76120e7eff5 100644 --- a/compiler/testData/codegen/box/properties/lateinit/exceptionField.kt +++ b/compiler/testData/codegen/box/properties/lateinit/exceptionField.kt @@ -4,7 +4,7 @@ class A { public fun getMyStr(): String { try { val a = str - } catch (e: NullPointerException) { + } catch (e: RuntimeException) { return "OK" } diff --git a/compiler/testData/codegen/box/properties/lateinit/exceptionGetter.kt b/compiler/testData/codegen/box/properties/lateinit/exceptionGetter.kt index 110502a2e93..35449a38fad 100644 --- a/compiler/testData/codegen/box/properties/lateinit/exceptionGetter.kt +++ b/compiler/testData/codegen/box/properties/lateinit/exceptionGetter.kt @@ -6,7 +6,7 @@ fun box(): String { val a = A() try { a.str - } catch (e: NullPointerException) { + } catch (e: RuntimeException) { return "OK" } return "FAIL" diff --git a/compiler/testData/codegen/box/properties/lateinit/overrideException.kt b/compiler/testData/codegen/box/properties/lateinit/overrideException.kt index 4a822e48fa0..ffc98f1f128 100644 --- a/compiler/testData/codegen/box/properties/lateinit/overrideException.kt +++ b/compiler/testData/codegen/box/properties/lateinit/overrideException.kt @@ -8,7 +8,7 @@ class A : Intf { fun getMyStr(): String { try { val a = str - } catch (e: NullPointerException) { + } catch (e: RuntimeException) { return "OK" } return "FAIL" diff --git a/compiler/testData/codegen/boxWithStdlib/fullJdk/lateinitVisibility.kt b/compiler/testData/codegen/boxWithStdlib/fullJdk/lateinitVisibility.kt index 739e7f46cb6..65b7909ec06 100644 --- a/compiler/testData/codegen/boxWithStdlib/fullJdk/lateinitVisibility.kt +++ b/compiler/testData/codegen/boxWithStdlib/fullJdk/lateinitVisibility.kt @@ -13,9 +13,15 @@ public class A { if (!Modifier.isProtected(clazz.getDeclaredField("protectedField").modifiers)) cond += "NOT_PROTECTED" if (!Modifier.isPublic(clazz.getDeclaredField("publicField").modifiers)) cond += "NOT_PUBLIC" - if (Modifier.isPrivate(clazz.getDeclaredField("privateField").modifiers)) cond += "FINAL" + if (Modifier.isFinal(clazz.getDeclaredField("privateField").modifiers)) cond += "FINAL" - return if (cond.isEmpty()) "OK" else cond.joinToString() + try { + val a = privateField + } catch (e: UninitializedPropertyAccessException) { + return if (cond.isEmpty()) "OK" else cond.joinToString() + } + + return "EXCEPTION WAS NOT CATCHED" } } diff --git a/core/runtime.jvm/src/kotlin/UninitializedPropertyAccessException.kt b/core/runtime.jvm/src/kotlin/UninitializedPropertyAccessException.kt new file mode 100644 index 00000000000..21791444c9d --- /dev/null +++ b/core/runtime.jvm/src/kotlin/UninitializedPropertyAccessException.kt @@ -0,0 +1,19 @@ +/* + * Copyright 2010-2015 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package kotlin + +public class UninitializedPropertyAccessException(name: String): RuntimeException("lateinit property $name has not been initialized") \ No newline at end of file diff --git a/core/runtime.jvm/src/kotlin/jvm/internal/Intrinsics.java b/core/runtime.jvm/src/kotlin/jvm/internal/Intrinsics.java index 63a79af2e1c..ec33fa32a1a 100644 --- a/core/runtime.jvm/src/kotlin/jvm/internal/Intrinsics.java +++ b/core/runtime.jvm/src/kotlin/jvm/internal/Intrinsics.java @@ -17,6 +17,7 @@ package kotlin.jvm.internal; import kotlin.KotlinNullPointerException; +import kotlin.UninitializedPropertyAccessException; import java.util.Arrays; import java.util.List; @@ -34,6 +35,10 @@ public class Intrinsics { throw sanitizeStackTrace(new KotlinNullPointerException()); } + public static void throwUninitializedPropertyAccessException(String propertyName) { + throw sanitizeStackTrace(new UninitializedPropertyAccessException(propertyName)); + } + public static void checkExpressionValueIsNotNull(Object value, String message) { if (value == null) { IllegalStateException exception = new IllegalStateException(message + " must not be null");