Assertions on approximation of platform types to non-null types

- for most expressions (ExpressionCodegen.genQualified)
This commit is contained in:
Andrey Breslav
2014-10-05 22:18:15 +04:00
parent 3d5d3e00e3
commit f1c66fa6b0
11 changed files with 193 additions and 24 deletions
@@ -37,7 +37,9 @@ import org.jetbrains.jet.lang.resolve.java.*;
import org.jetbrains.jet.lang.resolve.java.descriptor.JavaCallableMemberDescriptor;
import org.jetbrains.jet.lang.resolve.kotlin.PackagePartClassUtils;
import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.lang.types.Approximation;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.TypesPackage;
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
import org.jetbrains.jet.lexer.JetTokens;
import org.jetbrains.org.objectweb.asm.*;
@@ -608,12 +610,15 @@ public class AsmUtil {
@NotNull CallableDescriptor descriptor,
@NotNull String assertMethodToCall
) {
// Assertions are generated elsewhere for platform types
if (JavaPackage.getPLATFORM_TYPES()) return;
if (!state.isCallAssertionsEnabled()) return;
if (!isDeclaredInJava(descriptor)) return;
JetType type = descriptor.getReturnType();
if (type == null || isNullableType(type)) return;
if (type == null || isNullableType(TypesPackage.lowerIfFlexible(type))) return;
Type asmType = state.getTypeMapper().mapReturnType(descriptor);
if (asmType.getSort() == Type.OBJECT || asmType.getSort() == Type.ARRAY) {
@@ -625,6 +630,30 @@ public class AsmUtil {
}
}
@NotNull
public static StackValue genNotNullAssertions(
@NotNull GenerationState state,
@NotNull final StackValue stackValue,
@Nullable final Approximation.Info approximationInfo
) {
if (!state.isCallAssertionsEnabled()) return stackValue;
if (approximationInfo == null || !TypesPackage.assertNotNull(approximationInfo)) return stackValue;
return new StackValue(stackValue.type) {
@Override
public void put(Type type, InstructionAdapter v) {
stackValue.put(type, v);
if (type.getSort() == Type.OBJECT || type.getSort() == Type.ARRAY) {
v.dup();
v.visitLdcInsn(approximationInfo.getMessage());
v.invokestatic("kotlin/jvm/internal/Intrinsics", "checkExpressionValueIsNotNull",
"(Ljava/lang/Object;Ljava/lang/String;)V", false);
}
}
};
}
private static boolean isDeclaredInJava(@NotNull CallableDescriptor callableDescriptor) {
CallableDescriptor descriptor = callableDescriptor;
while (true) {
@@ -61,6 +61,7 @@ import org.jetbrains.jet.lang.resolve.java.descriptor.SamConstructorDescriptor;
import org.jetbrains.jet.lang.resolve.java.jvmSignature.JvmMethodSignature;
import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.resolve.scopes.receivers.*;
import org.jetbrains.jet.lang.types.Approximation;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.TypeUtils;
import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
@@ -242,7 +243,14 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
}
}
return selector.accept(visitor, receiver);
StackValue stackValue = selector.accept(visitor, receiver);
Approximation.Info approximationInfo = null;
if (selector instanceof JetExpression) {
approximationInfo = bindingContext.get(BindingContext.EXPRESSION_RESULT_APPROXIMATION, (JetExpression) selector);
}
return genNotNullAssertions(state, stackValue, approximationInfo);
}
catch (ProcessCanceledException e) {
throw e;