Supported cases with two superclasses when they have different variances.
This commit is contained in:
+112
-102
@@ -35,7 +35,6 @@ import org.jetbrains.jet.lang.resolve.name.FqName;
|
|||||||
import org.jetbrains.jet.lang.resolve.name.FqNameUnsafe;
|
import org.jetbrains.jet.lang.resolve.name.FqNameUnsafe;
|
||||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
||||||
import org.jetbrains.jet.lang.types.*;
|
import org.jetbrains.jet.lang.types.*;
|
||||||
import org.jetbrains.jet.lang.types.checker.TypeCheckingProcedure;
|
|
||||||
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
|
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
@@ -88,7 +87,7 @@ public class SignaturesPropagationData {
|
|||||||
public List<FunctionDescriptor> getSuperFunctions() {
|
public List<FunctionDescriptor> getSuperFunctions() {
|
||||||
return superFunctions;
|
return superFunctions;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void reportError(String error) {
|
private void reportError(String error) {
|
||||||
signatureErrors.add(error);
|
signatureErrors.add(error);
|
||||||
}
|
}
|
||||||
@@ -96,15 +95,15 @@ public class SignaturesPropagationData {
|
|||||||
private JetType modifyReturnTypeAccordingToSuperMethods(
|
private JetType modifyReturnTypeAccordingToSuperMethods(
|
||||||
@NotNull JetType autoType // type built by JavaTypeTransformer
|
@NotNull JetType autoType // type built by JavaTypeTransformer
|
||||||
) {
|
) {
|
||||||
List<JetType> typesFromSuperMethods = ContainerUtil.map(superFunctions,
|
List<TypeAndVariance> typesFromSuperMethods = ContainerUtil.map(superFunctions,
|
||||||
new Function<FunctionDescriptor, JetType>() {
|
new Function<FunctionDescriptor, TypeAndVariance>() {
|
||||||
@Override
|
@Override
|
||||||
public JetType fun(FunctionDescriptor superFunction) {
|
public TypeAndVariance fun(FunctionDescriptor superFunction) {
|
||||||
return superFunction.getReturnType();
|
return new TypeAndVariance(superFunction.getReturnType(), Variance.OUT_VARIANCE);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return modifyTypeAccordingToSuperMethods(autoType, typesFromSuperMethods, true);
|
return modifyTypeAccordingToSuperMethods(autoType, typesFromSuperMethods);
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<TypeParameterDescriptor> modifyTypeParametersAccordingToSuperMethods(List<TypeParameterDescriptor> autoTypeParameters) {
|
private List<TypeParameterDescriptor> modifyTypeParametersAccordingToSuperMethods(List<TypeParameterDescriptor> autoTypeParameters) {
|
||||||
@@ -120,14 +119,14 @@ public class SignaturesPropagationData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (JetType autoUpperBound : autoParameter.getUpperBounds()) {
|
for (JetType autoUpperBound : autoParameter.getUpperBounds()) {
|
||||||
List<JetType> upperBoundsFromSuperFunctions = Lists.newArrayList();
|
List<TypeAndVariance> upperBoundsFromSuperFunctions = Lists.newArrayList();
|
||||||
|
|
||||||
for (Iterator<JetType> iterator : upperBoundFromSuperFunctionsIterators) {
|
for (Iterator<JetType> iterator : upperBoundFromSuperFunctionsIterators) {
|
||||||
assert iterator.hasNext();
|
assert iterator.hasNext();
|
||||||
upperBoundsFromSuperFunctions.add(iterator.next());
|
upperBoundsFromSuperFunctions.add(new TypeAndVariance(iterator.next(), Variance.INVARIANT));
|
||||||
}
|
}
|
||||||
|
|
||||||
JetType modifiedUpperBound = modifyTypeAccordingToSuperMethods(autoUpperBound, upperBoundsFromSuperFunctions, false);
|
JetType modifiedUpperBound = modifyTypeAccordingToSuperMethods(autoUpperBound, upperBoundsFromSuperFunctions);
|
||||||
modifiedTypeParameter.addUpperBound(modifiedUpperBound);
|
modifiedTypeParameter.addUpperBound(modifiedUpperBound);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -152,18 +151,18 @@ public class SignaturesPropagationData {
|
|||||||
|
|
||||||
for (final ValueParameterDescriptor originalParam : parameters.getDescriptors()) {
|
for (final ValueParameterDescriptor originalParam : parameters.getDescriptors()) {
|
||||||
final int index = originalParam.getIndex();
|
final int index = originalParam.getIndex();
|
||||||
List<JetType> typesFromSuperMethods = ContainerUtil.map(superFunctions,
|
List<TypeAndVariance> typesFromSuperMethods = ContainerUtil.map(superFunctions,
|
||||||
new Function<FunctionDescriptor, JetType>() {
|
new Function<FunctionDescriptor, TypeAndVariance>() {
|
||||||
@Override
|
@Override
|
||||||
public JetType fun(FunctionDescriptor superFunction) {
|
public TypeAndVariance fun(FunctionDescriptor superFunction) {
|
||||||
return superFunction.getValueParameters().get(index).getType();
|
return new TypeAndVariance(superFunction.getValueParameters().get(index).getType(), Variance.INVARIANT);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
VarargCheckResult varargCheckResult =
|
VarargCheckResult varargCheckResult =
|
||||||
checkVarargInSuperFunctions(originalParam);
|
checkVarargInSuperFunctions(originalParam);
|
||||||
|
|
||||||
JetType altType = modifyTypeAccordingToSuperMethods(varargCheckResult.parameterType, typesFromSuperMethods, false);
|
JetType altType = modifyTypeAccordingToSuperMethods(varargCheckResult.parameterType, typesFromSuperMethods);
|
||||||
|
|
||||||
resultParameters.add(new ValueParameterDescriptorImpl(
|
resultParameters.add(new ValueParameterDescriptorImpl(
|
||||||
originalParam.getContainingDeclaration(),
|
originalParam.getContainingDeclaration(),
|
||||||
@@ -274,15 +273,14 @@ public class SignaturesPropagationData {
|
|||||||
@NotNull
|
@NotNull
|
||||||
private JetType modifyTypeAccordingToSuperMethods(
|
private JetType modifyTypeAccordingToSuperMethods(
|
||||||
@NotNull JetType autoType,
|
@NotNull JetType autoType,
|
||||||
@NotNull List<JetType> typesFromSuper,
|
@NotNull List<TypeAndVariance> typesFromSuper
|
||||||
boolean covariantPosition
|
|
||||||
) {
|
) {
|
||||||
if (ErrorUtils.isErrorType(autoType)) {
|
if (ErrorUtils.isErrorType(autoType)) {
|
||||||
return autoType;
|
return autoType;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean resultNullable = typeMustBeNullable(autoType, typesFromSuper, covariantPosition);
|
boolean resultNullable = typeMustBeNullable(autoType, typesFromSuper);
|
||||||
ClassifierDescriptor resultClassifier = modifyTypeClassifier(autoType, typesFromSuper, covariantPosition);
|
ClassifierDescriptor resultClassifier = modifyTypeClassifier(autoType, typesFromSuper);
|
||||||
List<TypeProjection> resultArguments = getTypeArgsOfType(autoType, resultClassifier, typesFromSuper);
|
List<TypeProjection> resultArguments = getTypeArgsOfType(autoType, resultClassifier, typesFromSuper);
|
||||||
JetScope resultScope;
|
JetScope resultScope;
|
||||||
if (resultClassifier instanceof ClassDescriptor) {
|
if (resultClassifier instanceof ClassDescriptor) {
|
||||||
@@ -303,7 +301,7 @@ public class SignaturesPropagationData {
|
|||||||
private List<TypeProjection> getTypeArgsOfType(
|
private List<TypeProjection> getTypeArgsOfType(
|
||||||
@NotNull JetType autoType,
|
@NotNull JetType autoType,
|
||||||
@NotNull ClassifierDescriptor classifier,
|
@NotNull ClassifierDescriptor classifier,
|
||||||
@NotNull List<JetType> typesFromSuper
|
@NotNull List<TypeAndVariance> typesFromSuper
|
||||||
) {
|
) {
|
||||||
List<TypeProjection> autoArguments = autoType.getArguments();
|
List<TypeProjection> autoArguments = autoType.getArguments();
|
||||||
|
|
||||||
@@ -313,22 +311,18 @@ public class SignaturesPropagationData {
|
|||||||
return autoArguments;
|
return autoArguments;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<List<TypeProjection>> typeArgumentsFromSuper = calculateTypeArgumentsFromSuper((ClassDescriptor) classifier, typesFromSuper);
|
List<List<TypeProjectionAndVariance>> typeArgumentsFromSuper = calculateTypeArgumentsFromSuper((ClassDescriptor) classifier, typesFromSuper);
|
||||||
|
|
||||||
// Modify type arguments using info from typesFromSuper
|
// Modify type arguments using info from typesFromSuper
|
||||||
List<TypeProjection> resultArguments = Lists.newArrayList();
|
List<TypeProjection> resultArguments = Lists.newArrayList();
|
||||||
for (TypeParameterDescriptor parameter : classifier.getTypeConstructor().getParameters()) {
|
for (TypeParameterDescriptor parameter : classifier.getTypeConstructor().getParameters()) {
|
||||||
TypeProjection argument = autoArguments.get(parameter.getIndex());
|
TypeProjection argument = autoArguments.get(parameter.getIndex());
|
||||||
|
|
||||||
TypeCheckingProcedure.EnrichedProjectionKind effectiveProjectionKind =
|
|
||||||
TypeCheckingProcedure.getEffectiveProjectionKind(parameter, argument);
|
|
||||||
|
|
||||||
JetType argumentType = argument.getType();
|
JetType argumentType = argument.getType();
|
||||||
List<TypeProjection> projectionsFromSuper = typeArgumentsFromSuper.get(parameter.getIndex());
|
List<TypeProjectionAndVariance> projectionsFromSuper = typeArgumentsFromSuper.get(parameter.getIndex());
|
||||||
List<JetType> argTypesFromSuper = getTypes(projectionsFromSuper);
|
List<TypeAndVariance> argTypesFromSuper = getTypes(projectionsFromSuper);
|
||||||
boolean covariantPosition = effectiveProjectionKind == TypeCheckingProcedure.EnrichedProjectionKind.OUT;
|
|
||||||
|
|
||||||
JetType type = modifyTypeAccordingToSuperMethods(argumentType, argTypesFromSuper, covariantPosition);
|
JetType type = modifyTypeAccordingToSuperMethods(argumentType, argTypesFromSuper);
|
||||||
Variance projectionKind = calculateArgumentProjectionKindFromSuper(argument, projectionsFromSuper);
|
Variance projectionKind = calculateArgumentProjectionKindFromSuper(argument, projectionsFromSuper);
|
||||||
|
|
||||||
resultArguments.add(new TypeProjection(projectionKind, type));
|
resultArguments.add(new TypeProjection(projectionKind, type));
|
||||||
@@ -338,11 +332,11 @@ public class SignaturesPropagationData {
|
|||||||
|
|
||||||
private Variance calculateArgumentProjectionKindFromSuper(
|
private Variance calculateArgumentProjectionKindFromSuper(
|
||||||
@NotNull TypeProjection argument,
|
@NotNull TypeProjection argument,
|
||||||
@NotNull List<TypeProjection> projectionsFromSuper
|
@NotNull List<TypeProjectionAndVariance> projectionsFromSuper
|
||||||
) {
|
) {
|
||||||
Set<Variance> projectionKindsInSuper = Sets.newLinkedHashSet();
|
Set<Variance> projectionKindsInSuper = Sets.newLinkedHashSet();
|
||||||
for (TypeProjection projection : projectionsFromSuper) {
|
for (TypeProjectionAndVariance projectionAndVariance : projectionsFromSuper) {
|
||||||
projectionKindsInSuper.add(projection.getProjectionKind());
|
projectionKindsInSuper.add(projectionAndVariance.typeProjection.getProjectionKind());
|
||||||
}
|
}
|
||||||
|
|
||||||
Variance defaultProjectionKind = argument.getProjectionKind();
|
Variance defaultProjectionKind = argument.getProjectionKind();
|
||||||
@@ -367,10 +361,10 @@ public class SignaturesPropagationData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private static List<JetType> getTypes(@NotNull List<TypeProjection> projections) {
|
private static List<TypeAndVariance> getTypes(@NotNull List<TypeProjectionAndVariance> projections) {
|
||||||
List<JetType> types = Lists.newArrayList();
|
List<TypeAndVariance> types = Lists.newArrayList();
|
||||||
for (TypeProjection projection : projections) {
|
for (TypeProjectionAndVariance projection : projections) {
|
||||||
types.add(projection.getType());
|
types.add(new TypeAndVariance(projection.typeProjection.getType(), projection.varianceOfParameter));
|
||||||
}
|
}
|
||||||
return types;
|
return types;
|
||||||
}
|
}
|
||||||
@@ -380,9 +374,9 @@ public class SignaturesPropagationData {
|
|||||||
// - Foo<A, B> is a subtype of Bar<A, List<B>>, Baz<Boolean, A>
|
// - Foo<A, B> is a subtype of Bar<A, List<B>>, Baz<Boolean, A>
|
||||||
// - input: klass = Foo, typesFromSuper = [Bar<String, List<Int>>, Baz<Boolean, CharSequence>]
|
// - input: klass = Foo, typesFromSuper = [Bar<String, List<Int>>, Baz<Boolean, CharSequence>]
|
||||||
// - output[0] = [String, CharSequence], output[1] = []
|
// - output[0] = [String, CharSequence], output[1] = []
|
||||||
private static List<List<TypeProjection>> calculateTypeArgumentsFromSuper(
|
private static List<List<TypeProjectionAndVariance>> calculateTypeArgumentsFromSuper(
|
||||||
@NotNull ClassDescriptor klass,
|
@NotNull ClassDescriptor klass,
|
||||||
@NotNull Collection<JetType> typesFromSuper
|
@NotNull Collection<TypeAndVariance> typesFromSuper
|
||||||
) {
|
) {
|
||||||
// For each superclass of klass and its parameters, hold their mapping to klass' parameters
|
// For each superclass of klass and its parameters, hold their mapping to klass' parameters
|
||||||
// #0 of Bar -> A
|
// #0 of Bar -> A
|
||||||
@@ -395,15 +389,15 @@ public class SignaturesPropagationData {
|
|||||||
TypeUtils.makeUnsubstitutedType(klass, JetScope.EMPTY));
|
TypeUtils.makeUnsubstitutedType(klass, JetScope.EMPTY));
|
||||||
|
|
||||||
// for each parameter of klass, hold arguments in corresponding supertypes
|
// for each parameter of klass, hold arguments in corresponding supertypes
|
||||||
List<List<TypeProjection>> parameterToArgumentsFromSuper = Lists.newArrayList();
|
List<List<TypeProjectionAndVariance>> parameterToArgumentsFromSuper = Lists.newArrayList();
|
||||||
for (TypeParameterDescriptor ignored : klass.getTypeConstructor().getParameters()) {
|
for (TypeParameterDescriptor ignored : klass.getTypeConstructor().getParameters()) {
|
||||||
parameterToArgumentsFromSuper.add(new ArrayList<TypeProjection>());
|
parameterToArgumentsFromSuper.add(new ArrayList<TypeProjectionAndVariance>());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enumerate all types from super and all its parameters
|
// Enumerate all types from super and all its parameters
|
||||||
for (JetType typeFromSuper : typesFromSuper) {
|
for (TypeAndVariance typeFromSuper : typesFromSuper) {
|
||||||
for (TypeParameterDescriptor parameter : typeFromSuper.getConstructor().getParameters()) {
|
for (TypeParameterDescriptor parameter : typeFromSuper.type.getConstructor().getParameters()) {
|
||||||
TypeProjection argument = typeFromSuper.getArguments().get(parameter.getIndex());
|
TypeProjection argument = typeFromSuper.type.getArguments().get(parameter.getIndex());
|
||||||
|
|
||||||
// for given example, this block is executed four times:
|
// for given example, this block is executed four times:
|
||||||
// 1. typeFromSuper = Bar<String, List<Int>>, parameter = "#0 of Bar", argument = String
|
// 1. typeFromSuper = Bar<String, List<Int>>, parameter = "#0 of Bar", argument = String
|
||||||
@@ -422,7 +416,7 @@ public class SignaturesPropagationData {
|
|||||||
// this condition is true for 1 and 4, false for 2 and 3
|
// this condition is true for 1 and 4, false for 2 and 3
|
||||||
if (classifier instanceof TypeParameterDescriptor && classifier.getContainingDeclaration() == klass) {
|
if (classifier instanceof TypeParameterDescriptor && classifier.getContainingDeclaration() == klass) {
|
||||||
int parameterIndex = ((TypeParameterDescriptor) classifier).getIndex();
|
int parameterIndex = ((TypeParameterDescriptor) classifier).getIndex();
|
||||||
parameterToArgumentsFromSuper.get(parameterIndex).add(argument);
|
parameterToArgumentsFromSuper.get(parameterIndex).add(new TypeProjectionAndVariance(argument, parameter.getVariance()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -432,51 +426,42 @@ public class SignaturesPropagationData {
|
|||||||
|
|
||||||
private boolean typeMustBeNullable(
|
private boolean typeMustBeNullable(
|
||||||
@NotNull JetType autoType,
|
@NotNull JetType autoType,
|
||||||
@NotNull List<JetType> typesFromSuper,
|
@NotNull List<TypeAndVariance> typesFromSuper
|
||||||
boolean covariantPosition
|
|
||||||
) {
|
) {
|
||||||
if (typesFromSuper.isEmpty()) {
|
boolean someSupersNotCovariantNullable = false;
|
||||||
return autoType.isNullable();
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean someSupersNullable = false;
|
|
||||||
boolean someSupersNotNull = false;
|
boolean someSupersNotNull = false;
|
||||||
for (JetType typeFromSuper : typesFromSuper) {
|
for (TypeAndVariance typeFromSuper : typesFromSuper) {
|
||||||
if (typeFromSuper.isNullable()) {
|
if (typeFromSuper.type.isNullable() && typeFromSuper.varianceOfParameter != Variance.OUT_VARIANCE) {
|
||||||
someSupersNullable = true;
|
someSupersNotCovariantNullable = true;
|
||||||
}
|
}
|
||||||
else {
|
else if (!typeFromSuper.type.isNullable()) {
|
||||||
someSupersNotNull = true;
|
someSupersNotNull = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (someSupersNotNull && someSupersNullable) {
|
|
||||||
//noinspection IfStatementWithIdenticalBranches
|
if (someSupersNotCovariantNullable == someSupersNotNull) {
|
||||||
if (covariantPosition) {
|
if (someSupersNotCovariantNullable) {
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
reportError("Incompatible types in superclasses: " + typesFromSuper);
|
reportError("Incompatible types in superclasses: " + typesFromSuper);
|
||||||
}
|
}
|
||||||
|
return autoType.isNullable();
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
assert someSupersNotNull || someSupersNullable; // we have at least one type, which is either not-null or nullable
|
if (someSupersNotCovariantNullable) {
|
||||||
|
if (!autoType.isNullable()) {
|
||||||
// This check may seem like voodoo magic, but it's not.
|
reportError("In superclass type is nullable: " + typesFromSuper + ", in subclass it is not: " + autoType);
|
||||||
// We want to handle case when parameter of super method is nullable, but parameter of sub method claims to be not null:
|
}
|
||||||
// of course, it is an error in annotations, and parameter of sub method should be nullable.
|
return true;
|
||||||
if (!covariantPosition && someSupersNullable && !autoType.isNullable()) {
|
}
|
||||||
reportError("In superclass type is nullable: " + typesFromSuper + ", in subclass it is not: " + autoType);
|
else { // someSupersNotNull is true here
|
||||||
return true;
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return someSupersNullable && autoType.isNullable();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private ClassifierDescriptor modifyTypeClassifier(
|
private ClassifierDescriptor modifyTypeClassifier(
|
||||||
@NotNull JetType autoType,
|
@NotNull JetType autoType,
|
||||||
@NotNull List<JetType> typesFromSuper,
|
@NotNull List<TypeAndVariance> typesFromSuper
|
||||||
boolean covariantPosition
|
|
||||||
) {
|
) {
|
||||||
ClassifierDescriptor classifier = autoType.getConstructor().getDeclarationDescriptor();
|
ClassifierDescriptor classifier = autoType.getConstructor().getDeclarationDescriptor();
|
||||||
if (!(classifier instanceof ClassDescriptor)) {
|
if (!(classifier instanceof ClassDescriptor)) {
|
||||||
@@ -487,14 +472,15 @@ public class SignaturesPropagationData {
|
|||||||
}
|
}
|
||||||
return classifier;
|
return classifier;
|
||||||
}
|
}
|
||||||
ClassDescriptor clazz = (ClassDescriptor) classifier;
|
ClassDescriptor klass = (ClassDescriptor) classifier;
|
||||||
|
|
||||||
CollectionClassMapping collectionMapping = CollectionClassMapping.getInstance();
|
CollectionClassMapping collectionMapping = CollectionClassMapping.getInstance();
|
||||||
|
|
||||||
boolean someSupersMutable = false;
|
boolean someSupersMutable = false;
|
||||||
boolean someSupersReadOnly = false;
|
boolean someSupersCovariantReadOnly = false;
|
||||||
for (JetType typeFromSuper : typesFromSuper) {
|
boolean someSupersNotCovariantReadOnly = false;
|
||||||
ClassifierDescriptor classifierFromSuper = typeFromSuper.getConstructor().getDeclarationDescriptor();
|
for (TypeAndVariance typeFromSuper : typesFromSuper) {
|
||||||
|
ClassifierDescriptor classifierFromSuper = typeFromSuper.type.getConstructor().getDeclarationDescriptor();
|
||||||
if (classifierFromSuper instanceof ClassDescriptor) {
|
if (classifierFromSuper instanceof ClassDescriptor) {
|
||||||
ClassDescriptor classFromSuper = (ClassDescriptor) classifierFromSuper;
|
ClassDescriptor classFromSuper = (ClassDescriptor) classifierFromSuper;
|
||||||
|
|
||||||
@@ -502,35 +488,31 @@ public class SignaturesPropagationData {
|
|||||||
someSupersMutable = true;
|
someSupersMutable = true;
|
||||||
}
|
}
|
||||||
else if (collectionMapping.isReadOnlyCollection(classFromSuper)) {
|
else if (collectionMapping.isReadOnlyCollection(classFromSuper)) {
|
||||||
someSupersReadOnly = true;
|
if (typeFromSuper.varianceOfParameter == Variance.OUT_VARIANCE) {
|
||||||
|
someSupersCovariantReadOnly = true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
someSupersNotCovariantReadOnly = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (covariantPosition) {
|
if (someSupersMutable && someSupersNotCovariantReadOnly) {
|
||||||
if (collectionMapping.isMutableCollection(clazz)) {
|
reportError("Incompatible types in superclasses: " + typesFromSuper);
|
||||||
if (someSupersReadOnly && !someSupersMutable) {
|
return classifier;
|
||||||
return collectionMapping.convertMutableToReadOnly(clazz);
|
}
|
||||||
}
|
else if (someSupersMutable) {
|
||||||
|
if (collectionMapping.isReadOnlyCollection(klass)) {
|
||||||
|
return collectionMapping.convertReadOnlyToMutable(klass);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else if (someSupersNotCovariantReadOnly || someSupersCovariantReadOnly) {
|
||||||
if (someSupersMutable == someSupersReadOnly) {
|
if (collectionMapping.isMutableCollection(klass)) {
|
||||||
//noinspection ConstantConditions
|
return collectionMapping.convertMutableToReadOnly(klass);
|
||||||
if (someSupersMutable && someSupersReadOnly) {
|
|
||||||
reportError("Incompatible types in superclasses: " + typesFromSuper);
|
|
||||||
}
|
|
||||||
return classifier;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (someSupersMutable && collectionMapping.isReadOnlyCollection(clazz)) {
|
|
||||||
return collectionMapping.convertReadOnlyToMutable(clazz);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (someSupersReadOnly && collectionMapping.isMutableCollection(clazz)) {
|
|
||||||
return collectionMapping.convertMutableToReadOnly(clazz);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return classifier;
|
return classifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -543,9 +525,37 @@ public class SignaturesPropagationData {
|
|||||||
public final JetType parameterType;
|
public final JetType parameterType;
|
||||||
public final boolean isVararg;
|
public final boolean isVararg;
|
||||||
|
|
||||||
private VarargCheckResult(JetType parameterType, boolean isVararg) {
|
public VarargCheckResult(JetType parameterType, boolean isVararg) {
|
||||||
this.parameterType = parameterType;
|
this.parameterType = parameterType;
|
||||||
this.isVararg = isVararg;
|
this.isVararg = isVararg;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static class TypeProjectionAndVariance {
|
||||||
|
public final TypeProjection typeProjection;
|
||||||
|
public final Variance varianceOfParameter;
|
||||||
|
|
||||||
|
public TypeProjectionAndVariance(TypeProjection typeProjection, Variance varianceOfParameter) {
|
||||||
|
this.typeProjection = typeProjection;
|
||||||
|
this.varianceOfParameter = varianceOfParameter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
return typeProjection.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class TypeAndVariance {
|
||||||
|
public final JetType type;
|
||||||
|
public final Variance varianceOfParameter;
|
||||||
|
|
||||||
|
public TypeAndVariance(JetType type, Variance varianceOfParameter) {
|
||||||
|
this.type = type;
|
||||||
|
this.varianceOfParameter = varianceOfParameter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
return type.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+22
@@ -0,0 +1,22 @@
|
|||||||
|
package test;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import jet.runtime.typeinfo.KotlinSignature;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
public interface TwoSuperclassesInvariantAndCovariantInferMutability {
|
||||||
|
|
||||||
|
public interface Super1 {
|
||||||
|
@KotlinSignature("fun foo(): List<List<String>>")
|
||||||
|
public List<List<String>> foo();
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface Super2 {
|
||||||
|
@KotlinSignature("fun foo(): MutableList<MutableList<String>>")
|
||||||
|
public List<List<String>> foo();
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface Sub extends Super1, Super2 {
|
||||||
|
public List<List<String>> foo();
|
||||||
|
}
|
||||||
|
}
|
||||||
+16
@@ -0,0 +1,16 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
public trait TwoSuperclassesInvariantAndCovariantInferMutability: Object {
|
||||||
|
|
||||||
|
public trait Super1: Object {
|
||||||
|
public fun foo(): List<List<String>>
|
||||||
|
}
|
||||||
|
|
||||||
|
public trait Super2: Object {
|
||||||
|
public fun foo(): MutableList<MutableList<String>>
|
||||||
|
}
|
||||||
|
|
||||||
|
public trait Sub: Super1, Super2 {
|
||||||
|
override fun foo(): MutableList<MutableList<String>>
|
||||||
|
}
|
||||||
|
}
|
||||||
+13
@@ -0,0 +1,13 @@
|
|||||||
|
namespace test
|
||||||
|
|
||||||
|
public abstract trait test.TwoSuperclassesInvariantAndCovariantInferMutability : java.lang.Object {
|
||||||
|
public abstract trait test.TwoSuperclassesInvariantAndCovariantInferMutability.Sub : test.TwoSuperclassesInvariantAndCovariantInferMutability.Super1, test.TwoSuperclassesInvariantAndCovariantInferMutability.Super2 {
|
||||||
|
public abstract override /*2*/ fun foo(): jet.MutableList<jet.MutableList<jet.String>>
|
||||||
|
}
|
||||||
|
public abstract trait test.TwoSuperclassesInvariantAndCovariantInferMutability.Super1 : java.lang.Object {
|
||||||
|
public abstract fun foo(): jet.List<jet.List<jet.String>>
|
||||||
|
}
|
||||||
|
public abstract trait test.TwoSuperclassesInvariantAndCovariantInferMutability.Super2 : java.lang.Object {
|
||||||
|
public abstract fun foo(): jet.MutableList<jet.MutableList<jet.String>>
|
||||||
|
}
|
||||||
|
}
|
||||||
+22
@@ -0,0 +1,22 @@
|
|||||||
|
package test;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import jet.runtime.typeinfo.KotlinSignature;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
public interface TwoSuperclassesInvariantAndCovariantInferNullability {
|
||||||
|
|
||||||
|
public interface Super1 {
|
||||||
|
@KotlinSignature("fun foo(): List<String?>")
|
||||||
|
public List<String> foo();
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface Super2 {
|
||||||
|
@KotlinSignature("fun foo(): MutableList<String>")
|
||||||
|
public List<String> foo();
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface Sub extends Super1, Super2 {
|
||||||
|
public List<String> foo();
|
||||||
|
}
|
||||||
|
}
|
||||||
+16
@@ -0,0 +1,16 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
public trait TwoSuperclassesInvariantAndCovariantInferNullability: Object {
|
||||||
|
|
||||||
|
public trait Super1: Object {
|
||||||
|
public fun foo(): List<String?>
|
||||||
|
}
|
||||||
|
|
||||||
|
public trait Super2: Object {
|
||||||
|
public fun foo(): MutableList<String>
|
||||||
|
}
|
||||||
|
|
||||||
|
public trait Sub: Super1, Super2 {
|
||||||
|
override fun foo(): MutableList<String>
|
||||||
|
}
|
||||||
|
}
|
||||||
+13
@@ -0,0 +1,13 @@
|
|||||||
|
namespace test
|
||||||
|
|
||||||
|
public abstract trait test.TwoSuperclassesInvariantAndCovariantInferNullability : java.lang.Object {
|
||||||
|
public abstract trait test.TwoSuperclassesInvariantAndCovariantInferNullability.Sub : test.TwoSuperclassesInvariantAndCovariantInferNullability.Super1, test.TwoSuperclassesInvariantAndCovariantInferNullability.Super2 {
|
||||||
|
public abstract override /*2*/ fun foo(): jet.MutableList<jet.String>
|
||||||
|
}
|
||||||
|
public abstract trait test.TwoSuperclassesInvariantAndCovariantInferNullability.Super1 : java.lang.Object {
|
||||||
|
public abstract fun foo(): jet.List<jet.String?>
|
||||||
|
}
|
||||||
|
public abstract trait test.TwoSuperclassesInvariantAndCovariantInferNullability.Super2 : java.lang.Object {
|
||||||
|
public abstract fun foo(): jet.MutableList<jet.String>
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -664,6 +664,16 @@ public class LoadJavaTestGenerated extends AbstractLoadJavaTest {
|
|||||||
doTest("compiler/testData/loadJava/kotlinSignature/propagation/return/TwoSuperclassesConflictingProjectionKinds.java");
|
doTest("compiler/testData/loadJava/kotlinSignature/propagation/return/TwoSuperclassesConflictingProjectionKinds.java");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("TwoSuperclassesInvariantAndCovariantInferMutability.java")
|
||||||
|
public void testTwoSuperclassesInvariantAndCovariantInferMutability() throws Exception {
|
||||||
|
doTest("compiler/testData/loadJava/kotlinSignature/propagation/return/TwoSuperclassesInvariantAndCovariantInferMutability.java");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("TwoSuperclassesInvariantAndCovariantInferNullability.java")
|
||||||
|
public void testTwoSuperclassesInvariantAndCovariantInferNullability() throws Exception {
|
||||||
|
doTest("compiler/testData/loadJava/kotlinSignature/propagation/return/TwoSuperclassesInvariantAndCovariantInferNullability.java");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("TwoSuperclassesMutableAndNot.java")
|
@TestMetadata("TwoSuperclassesMutableAndNot.java")
|
||||||
public void testTwoSuperclassesMutableAndNot() throws Exception {
|
public void testTwoSuperclassesMutableAndNot() throws Exception {
|
||||||
doTest("compiler/testData/loadJava/kotlinSignature/propagation/return/TwoSuperclassesMutableAndNot.java");
|
doTest("compiler/testData/loadJava/kotlinSignature/propagation/return/TwoSuperclassesMutableAndNot.java");
|
||||||
|
|||||||
+10
@@ -1554,6 +1554,16 @@ public class LazyResolveNamespaceComparingTestGenerated extends AbstractLazyReso
|
|||||||
doTestSinglePackage("compiler/testData/loadJava/kotlinSignature/propagation/return/TwoSuperclassesConflictingProjectionKinds.kt");
|
doTestSinglePackage("compiler/testData/loadJava/kotlinSignature/propagation/return/TwoSuperclassesConflictingProjectionKinds.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("TwoSuperclassesInvariantAndCovariantInferMutability.kt")
|
||||||
|
public void testTwoSuperclassesInvariantAndCovariantInferMutability() throws Exception {
|
||||||
|
doTestSinglePackage("compiler/testData/loadJava/kotlinSignature/propagation/return/TwoSuperclassesInvariantAndCovariantInferMutability.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("TwoSuperclassesInvariantAndCovariantInferNullability.kt")
|
||||||
|
public void testTwoSuperclassesInvariantAndCovariantInferNullability() throws Exception {
|
||||||
|
doTestSinglePackage("compiler/testData/loadJava/kotlinSignature/propagation/return/TwoSuperclassesInvariantAndCovariantInferNullability.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("TwoSuperclassesMutableAndNot.kt")
|
@TestMetadata("TwoSuperclassesMutableAndNot.kt")
|
||||||
public void testTwoSuperclassesMutableAndNot() throws Exception {
|
public void testTwoSuperclassesMutableAndNot() throws Exception {
|
||||||
doTestSinglePackage("compiler/testData/loadJava/kotlinSignature/propagation/return/TwoSuperclassesMutableAndNot.kt");
|
doTestSinglePackage("compiler/testData/loadJava/kotlinSignature/propagation/return/TwoSuperclassesMutableAndNot.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user