KT-987 Unboxing nulls
#KT-987 Fixed
This commit is contained in:
@@ -174,7 +174,7 @@
|
||||
<chmod dir="${kotlin-home}/bin" includes="*" perm="755"/>
|
||||
</target>
|
||||
|
||||
<target name="dist" depends="init,jarRT,copyKotlinJars,jarJDKHeaders,jarLang,jar,buildToolsJar"/>
|
||||
<target name="dist" depends="init,copyKotlinJars,jar,buildToolsJar,jarJDKHeaders,jarRT,jarLang"/>
|
||||
|
||||
<target name="doc" depends="dist"/>
|
||||
|
||||
|
||||
+2
-2
@@ -737,11 +737,11 @@ public class JavaDescriptorResolver {
|
||||
typeParameterDescriptor.addUpperBound(JetStandardClasses.getNullableAnyType());
|
||||
}
|
||||
else if (referencedTypes.length == 1) {
|
||||
typeParameterDescriptor.addUpperBound(semanticServices.getTypeTransformer().transformToType(referencedTypes[0], typeVariableByPsiResolver));
|
||||
typeParameterDescriptor.addUpperBound(semanticServices.getTypeTransformer().transformToType(referencedTypes[0], JavaTypeTransformer.TypeUsage.UPPER_BOUND, typeVariableByPsiResolver));
|
||||
}
|
||||
else {
|
||||
for (PsiClassType referencedType : referencedTypes) {
|
||||
typeParameterDescriptor.addUpperBound(semanticServices.getTypeTransformer().transformToType(referencedType, typeVariableByPsiResolver));
|
||||
typeParameterDescriptor.addUpperBound(semanticServices.getTypeTransformer().transformToType(referencedType, JavaTypeTransformer.TypeUsage.UPPER_BOUND, typeVariableByPsiResolver));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+34
-5
@@ -80,12 +80,12 @@ public class JavaTypeTransformer {
|
||||
|
||||
PsiType bound = wildcardType.getBound();
|
||||
assert bound != null;
|
||||
return new TypeProjection(variance, transformToType(bound, typeVariableByPsiResolver));
|
||||
return new TypeProjection(variance, transformToType(bound, TypeUsage.UPPER_BOUND, typeVariableByPsiResolver));
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeProjection visitType(PsiType type) {
|
||||
return new TypeProjection(transformToType(type, typeVariableByPsiResolver));
|
||||
return new TypeProjection(transformToType(type, TypeUsage.TYPE_ARGUMENT, typeVariableByPsiResolver));
|
||||
}
|
||||
});
|
||||
return result;
|
||||
@@ -106,6 +106,12 @@ public class JavaTypeTransformer {
|
||||
|
||||
@NotNull
|
||||
public JetType transformToType(@NotNull PsiType javaType,
|
||||
@NotNull final TypeVariableResolver typeVariableResolver) {
|
||||
return transformToType(javaType, TypeUsage.MEMBER_SIGNATURE_INVARIANT, typeVariableResolver);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public JetType transformToType(@NotNull PsiType javaType, @NotNull final TypeUsage howThisTypeIsUsed,
|
||||
@NotNull final TypeVariableResolver typeVariableResolver) {
|
||||
return javaType.accept(new PsiTypeVisitor<JetType>() {
|
||||
@Override
|
||||
@@ -119,8 +125,16 @@ public class JavaTypeTransformer {
|
||||
if (psiClass instanceof PsiTypeParameter) {
|
||||
PsiTypeParameter typeParameter = (PsiTypeParameter) psiClass;
|
||||
TypeParameterDescriptor typeParameterDescriptor = typeVariableResolver.getTypeVariable(typeParameter.getName());
|
||||
// return TypeUtils.makeNullable(typeParameterDescriptor.getDefaultType());
|
||||
return typeParameterDescriptor.getDefaultType();
|
||||
|
||||
if (howThisTypeIsUsed == TypeUsage.TYPE_ARGUMENT || howThisTypeIsUsed == TypeUsage.UPPER_BOUND) {
|
||||
// In Java: ArrayList<T>
|
||||
// In Kotlin: ArrayList<T>, not ArrayList<T?>
|
||||
// nullability will be taken care of in individual member signatures
|
||||
return typeParameterDescriptor.getDefaultType();
|
||||
}
|
||||
else {
|
||||
return TypeUtils.makeNullable(typeParameterDescriptor.getDefaultType());
|
||||
}
|
||||
}
|
||||
else {
|
||||
JetType jetAnalog = getClassTypesMap().get(psiClass.getQualifiedName());
|
||||
@@ -211,7 +225,8 @@ public class JavaTypeTransformer {
|
||||
classTypesMap = new HashMap<String, JetType>();
|
||||
for (JvmPrimitiveType jvmPrimitiveType : JvmPrimitiveType.values()) {
|
||||
PrimitiveType primitiveType = jvmPrimitiveType.getPrimitiveType();
|
||||
classTypesMap.put(jvmPrimitiveType.getWrapper().getFqName(), JetStandardLibrary.getInstance().getNullablePrimitiveJetType(primitiveType));
|
||||
classTypesMap.put(jvmPrimitiveType.getWrapper().getFqName(), JetStandardLibrary.getInstance().getNullablePrimitiveJetType(
|
||||
primitiveType));
|
||||
}
|
||||
classTypesMap.put("java.lang.Object", JetStandardClasses.getNullableAnyType());
|
||||
classTypesMap.put("java.lang.String", JetStandardLibrary.getInstance().getNullableStringType());
|
||||
@@ -234,4 +249,18 @@ public class JavaTypeTransformer {
|
||||
}
|
||||
return classDescriptorMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* We convert Java types differently, depending on where they occur in the Java code
|
||||
* This enum encodes the kinds of occurrences
|
||||
*/
|
||||
public enum TypeUsage {
|
||||
// Type T occurs somewhere as a generic argument, e.g.: List<T> or List<? extends T>
|
||||
TYPE_ARGUMENT,
|
||||
UPPER_BOUND,
|
||||
MEMBER_SIGNATURE_COVARIANT,
|
||||
MEMBER_SIGNATURE_CONTRAVARIANT,
|
||||
MEMBER_SIGNATURE_INVARIANT,
|
||||
SUPERTYPE
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,7 +61,7 @@ class Luhny() {
|
||||
|
||||
private fun printOneDigit() {
|
||||
while (!buffer.isEmpty()) {
|
||||
val c = buffer.removeFirst()
|
||||
val c = buffer.removeFirst().sure()
|
||||
print(c)
|
||||
if (c.isDigit()) {
|
||||
digits.removeFirst()
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
// FILE: a/Test.java
|
||||
package a;
|
||||
|
||||
public class Test<T> {
|
||||
T t() {return null;}
|
||||
}
|
||||
// FILE: b.kt
|
||||
package a
|
||||
|
||||
fun foo() {
|
||||
// If this fails, it means that we have broken the rule that Java returns are always nullable
|
||||
a.Test<Int>.t() <!UNSAFE_INFIX_CALL!>+<!> 1
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
package test
|
||||
|
||||
final class MethosWithPRefTP() {
|
||||
fun <erased P> f(p0: P) = #()
|
||||
fun <erased P> f(p0: P?) = #()
|
||||
}
|
||||
|
||||
@@ -2,5 +2,5 @@ namespace test
|
||||
|
||||
final class test.MethosWithPRefTP : jet.Any {
|
||||
final /*constructor*/ fun <init>(): test.MethosWithPRefTP
|
||||
final fun </*0*/ P : jet.Any?>f(/*0*/ p0: P): jet.Tuple0
|
||||
final fun </*0*/ P : jet.Any?>f(/*0*/ p0: P?): jet.Tuple0
|
||||
}
|
||||
|
||||
@@ -84,7 +84,7 @@ inline fun FloatArray.copyOf(newLength: Int = this.size) = Arrays.copyOf(this,
|
||||
inline fun DoubleArray.copyOf(newLength: Int = this.size) = Arrays.copyOf(this, newLength).sure()
|
||||
inline fun CharArray.copyOf(newLength: Int = this.size) = Arrays.copyOf(this, newLength).sure()
|
||||
|
||||
inline fun <T> Array<T>.copyOf(newLength: Int = this.size) : Array<T> = Arrays.copyOf(this, newLength).sure()
|
||||
inline fun <T> Array<T>.copyOf(newLength: Int = this.size) : Array<T> = Arrays.copyOf(this as Array<T?>, newLength) as Array<T>
|
||||
|
||||
inline fun BooleanArray.copyOfRange(from: Int, to: Int) = Arrays.copyOfRange(this, from, to).sure()
|
||||
inline fun ByteArray.copyOfRange(from: Int, to: Int) = Arrays.copyOfRange(this, from, to).sure()
|
||||
@@ -95,7 +95,7 @@ inline fun FloatArray.copyOfRange(from: Int, to: Int) = Arrays.copyOfRange(thi
|
||||
inline fun DoubleArray.copyOfRange(from: Int, to: Int) = Arrays.copyOfRange(this, from, to).sure()
|
||||
inline fun CharArray.copyOfRange(from: Int, to: Int) = Arrays.copyOfRange(this, from, to).sure()
|
||||
|
||||
inline fun <T> Array<T>.copyOfRange(from: Int, to: Int) : Array<T> = Arrays.copyOfRange(this, from, to).sure()
|
||||
inline fun <T> Array<T>.copyOfRange(from: Int, to: Int) : Array<T> = Arrays.copyOfRange(this as Array<T?>, from, to) as Array<T>
|
||||
|
||||
inline val ByteArray.inputStream : ByteArrayInputStream
|
||||
get() = ByteArrayInputStream(this)
|
||||
|
||||
@@ -10,7 +10,7 @@ import java.util.TreeSet
|
||||
/**
|
||||
Helper to make jet.Iterator usable in for
|
||||
*/
|
||||
inline fun <T> jet.Iterator<T>.iterator() = this
|
||||
inline fun <T> Iterator<T>.iterator() = this
|
||||
|
||||
/**
|
||||
Helper to make java.util.Iterator usable in for
|
||||
@@ -24,7 +24,7 @@ fun <erased T> java.util.Enumeration<T>.iterator(): Iterator<T> = object: Iterat
|
||||
override val hasNext: Boolean
|
||||
get() = hasMoreElements()
|
||||
|
||||
override fun next() = nextElement()
|
||||
override fun next() = nextElement().sure()
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
Reference in New Issue
Block a user