提交 08de6d8d 编写于 作者: A Andrey Breslav

KT-1863 Wrong nullability for class derived from java classes.

 #KT-1863 In progress
上级 dcc2728f
......@@ -959,7 +959,7 @@ public class JavaDescriptorResolver {
continue;
}
JetType transform = semanticServices.getTypeTransformer().transformToType(type, typeVariableResolver);
JetType transform = semanticServices.getTypeTransformer().transformToType(type, JavaTypeTransformer.TypeUsage.SUPERTYPE, typeVariableResolver);
result.add(TypeUtils.makeNotNullable(transform));
}
......
......@@ -33,11 +33,9 @@ import org.jetbrains.jet.lang.types.lang.PrimitiveType;
import org.jetbrains.jet.rt.signature.JetSignatureReader;
import javax.inject.Inject;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.*;
import static org.jetbrains.jet.lang.resolve.java.JavaTypeTransformer.TypeUsage.*;
/**
* @author abreslav
......@@ -66,9 +64,11 @@ public class JavaTypeTransformer {
@NotNull
public TypeProjection transformToTypeProjection(@NotNull final PsiType javaType,
private TypeProjection transformToTypeProjection(@NotNull final PsiType javaType,
@NotNull final TypeParameterDescriptor typeParameterDescriptor,
@NotNull final TypeVariableResolver typeVariableByPsiResolver) {
@NotNull final TypeVariableResolver typeVariableByPsiResolver,
@NotNull final TypeUsage howThisTypeIsUsed
) {
TypeProjection result = javaType.accept(new PsiTypeVisitor<TypeProjection>() {
@Override
......@@ -85,12 +85,12 @@ public class JavaTypeTransformer {
PsiType bound = wildcardType.getBound();
assert bound != null;
return new TypeProjection(variance, transformToType(bound, TypeUsage.UPPER_BOUND, typeVariableByPsiResolver));
return new TypeProjection(variance, transformToType(bound, UPPER_BOUND, typeVariableByPsiResolver));
}
@Override
public TypeProjection visitType(PsiType type) {
return new TypeProjection(transformToType(type, TypeUsage.TYPE_ARGUMENT, typeVariableByPsiResolver));
return new TypeProjection(transformToType(type, howThisTypeIsUsed, typeVariableByPsiResolver));
}
});
return result;
......@@ -136,7 +136,7 @@ public class JavaTypeTransformer {
if (psiMethod.isConstructor()) {
Set<JetType> supertypesJet = Sets.newHashSet();
for (PsiClassType supertype : typeParameter.getExtendsListTypes()) {
supertypesJet.add(transformToType(supertype, TypeUsage.UPPER_BOUND, typeVariableResolver));
supertypesJet.add(transformToType(supertype, UPPER_BOUND, typeVariableResolver));
}
return TypeUtils.intersect(JetTypeChecker.INSTANCE, supertypesJet);
}
......@@ -144,20 +144,24 @@ public class JavaTypeTransformer {
TypeParameterDescriptor typeParameterDescriptor = typeVariableResolver.getTypeVariable(typeParameter.getName());
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();
// In Java: ArrayList<T>
// In Kotlin: ArrayList<T>, not ArrayList<T?>
// nullability will be taken care of in individual member signatures
boolean nullable = !EnumSet.of(TYPE_ARGUMENT, UPPER_BOUND, SUPERTYPE_ARGUMENT).contains(howThisTypeIsUsed);
if (nullable) {
return TypeUtils.makeNullable(typeParameterDescriptor.getDefaultType());
}
else {
return TypeUtils.makeNullable(typeParameterDescriptor.getDefaultType());
return typeParameterDescriptor.getDefaultType();
}
}
else {
// 'L extends List<T>' in Java is a List<T> in Kotlin, not a List<T?>
boolean nullable = !EnumSet.of(SUPERTYPE_ARGUMENT, SUPERTYPE).contains(howThisTypeIsUsed);
JetType jetAnalog = getKotlinAnalog(new FqName(psiClass.getQualifiedName()));
if (jetAnalog != null) {
return jetAnalog;
return TypeUtils.makeNullableAsSpecified(jetAnalog, nullable);
}
final ClassDescriptor classData =
......@@ -187,13 +191,15 @@ public class JavaTypeTransformer {
PsiType psiArgument = psiArguments[i];
TypeParameterDescriptor typeParameterDescriptor = parameters.get(i);
arguments.add(transformToTypeProjection(psiArgument, typeParameterDescriptor, typeVariableResolver));
TypeUsage howTheProjectionIsUsed = howThisTypeIsUsed == SUPERTYPE ? SUPERTYPE_ARGUMENT : TYPE_ARGUMENT;
arguments.add(transformToTypeProjection(psiArgument, typeParameterDescriptor, typeVariableResolver, howTheProjectionIsUsed));
}
}
return new JetTypeImpl(
Collections.<AnnotationDescriptor>emptyList(),
classData.getTypeConstructor(),
true,
nullable,
arguments,
classData.getMemberScope(arguments));
}
......@@ -291,6 +297,7 @@ public class JavaTypeTransformer {
MEMBER_SIGNATURE_COVARIANT,
MEMBER_SIGNATURE_CONTRAVARIANT,
MEMBER_SIGNATURE_INVARIANT,
SUPERTYPE
SUPERTYPE,
SUPERTYPE_ARGUMENT
}
}
// FILE: A.java
public class A {}
// FILE: X.java
import org.jetbrains.annotations.NotNull;
public class X<T> {
@NotNull T fooN() {return null;}
void barN(@NotNull T a) {}
}
// FILE: Y.java
public class Y extends X<String> {
}
// FILE: test.kt
fun main() {
Y().fooN() : Any
Y().barN(<!ERROR_COMPILE_TIME_VALUE!>null<!>);
}
// FILE: A.java
public class A {}
// FILE: X.java
import org.jetbrains.annotations.NotNull;
public class X<T> {
@NotNull T fooN() {return null;}
void barN(@NotNull T a) {}
}
// FILE: Y.java
public class Y extends X<A> {
}
// FILE: test.kt
fun main() {
Y().fooN() : Any
Y().barN(<!ERROR_COMPILE_TIME_VALUE!>null<!>);
}
// FILE: A.java
public class A {}
// FILE: X.java
public class X<T> {
T foo() {return null;}
void bar(T a) {}
}
// FILE: Y.java
public class Y extends X<String> {
}
// FILE: test.kt
fun main() {
Y().foo()<!UNSAFE_CALL!>.<!>length
Y().bar(null)
}
// FILE: A.java
public class A {}
// FILE: X.java
public class X<T> {
T foo() {return null;}
void bar(T a) {}
}
// FILE: Y.java
public class Y extends X<A> {
}
// FILE: test.kt
fun main() {
Y().foo()<!UNSAFE_CALL!>.<!>hashCode()
Y().bar(null)
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册