Generate not-null assertions after getting a field
This commit is contained in:
@@ -420,6 +420,14 @@ public class AsmUtil {
|
|||||||
genMethodThrow(mv, STUB_EXCEPTION, STUB_EXCEPTION_MESSAGE);
|
genMethodThrow(mv, STUB_EXCEPTION, STUB_EXCEPTION_MESSAGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void genNotNullAssertionForField(
|
||||||
|
@NotNull InstructionAdapter v,
|
||||||
|
@NotNull GenerationState state,
|
||||||
|
@NotNull PropertyDescriptor descriptor
|
||||||
|
) {
|
||||||
|
genNotNullAssertion(v, state, descriptor, "checkFieldIsNotNull");
|
||||||
|
}
|
||||||
|
|
||||||
public static void genNotNullAssertionForMethod(
|
public static void genNotNullAssertionForMethod(
|
||||||
@NotNull InstructionAdapter v,
|
@NotNull InstructionAdapter v,
|
||||||
@NotNull GenerationState state,
|
@NotNull GenerationState state,
|
||||||
|
|||||||
@@ -982,6 +982,7 @@ public abstract class StackValue {
|
|||||||
if (getter == null) {
|
if (getter == null) {
|
||||||
v.visitFieldInsn(isStatic ? GETSTATIC : GETFIELD, methodOwner.getInternalName(), descriptor.getName().getName(),
|
v.visitFieldInsn(isStatic ? GETSTATIC : GETFIELD, methodOwner.getInternalName(), descriptor.getName().getName(),
|
||||||
this.type.getDescriptor());
|
this.type.getDescriptor());
|
||||||
|
genNotNullAssertionForField(v, state, descriptor);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
v.visitMethodInsn(invokeOpcode, methodOwner.getInternalName(), getter.getName(), getter.getDescriptor());
|
v.visitMethodInsn(invokeOpcode, methodOwner.getInternalName(), getter.getName(), getter.getDescriptor());
|
||||||
|
|||||||
@@ -1,6 +1,13 @@
|
|||||||
import jet.runtime.typeinfo.KotlinSignature;
|
import jet.runtime.typeinfo.KotlinSignature;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
public class A {
|
public class A {
|
||||||
|
@NotNull
|
||||||
|
public final String NULL = null;
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public static final String STATIC_NULL = null;
|
||||||
|
|
||||||
@KotlinSignature("fun foo() : String")
|
@KotlinSignature("fun foo() : String")
|
||||||
public String foo() {
|
public String foo() {
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@@ -49,4 +49,10 @@ fun checkAssertions(val illegalStateExpected: Boolean) {
|
|||||||
|
|
||||||
// prefix expression
|
// prefix expression
|
||||||
check("inc") { var a = A(); ++a }
|
check("inc") { var a = A(); ++a }
|
||||||
|
|
||||||
|
// field
|
||||||
|
check("NULL") { val a = A().NULL }
|
||||||
|
|
||||||
|
// static field
|
||||||
|
check("STATIC_NULL") { val a = A.STATIC_NULL }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,6 +43,14 @@ public class Intrinsics {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void checkFieldIsNotNull(Object value, String className, String fieldName) {
|
||||||
|
if (value == null) {
|
||||||
|
IllegalStateException exception =
|
||||||
|
new IllegalStateException("Field specified as non-null contains null: " + className + "." + fieldName);
|
||||||
|
throw sanitizeStackTrace(exception);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static <T> Class<T> getJavaClass(T self) {
|
public static <T> Class<T> getJavaClass(T self) {
|
||||||
return (Class<T>) self.getClass();
|
return (Class<T>) self.getClass();
|
||||||
}
|
}
|
||||||
@@ -66,7 +74,7 @@ public class Intrinsics {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static final Set<String> METHOD_NAMES_TO_SKIP = new HashSet<String>(Arrays.asList(
|
private static final Set<String> METHOD_NAMES_TO_SKIP = new HashSet<String>(Arrays.asList(
|
||||||
"throwNpe", "checkReturnedValueIsNotNull"
|
"throwNpe", "checkReturnedValueIsNotNull", "checkFieldIsNotNull"
|
||||||
));
|
));
|
||||||
|
|
||||||
private static <T extends Throwable> T sanitizeStackTrace(T throwable) {
|
private static <T extends Throwable> T sanitizeStackTrace(T throwable) {
|
||||||
|
|||||||
Reference in New Issue
Block a user