Report errors for type parameters of properties that are not used in receiver types
This commit is contained in:
@@ -269,6 +269,8 @@ public interface Errors {
|
||||
DiagnosticFactory0<JetDeclaration> TYPE_PARAMETERS_NOT_ALLOWED
|
||||
= DiagnosticFactory0.create(ERROR, TYPE_PARAMETERS_OR_DECLARATION_SIGNATURE);
|
||||
|
||||
DiagnosticFactory0<JetTypeParameter> TYPE_PARAMETER_OF_PROPERTY_NOT_USED_IN_RECEIVER = DiagnosticFactory0.create(ERROR);
|
||||
|
||||
DiagnosticFactory0<PsiElement> CYCLIC_GENERIC_UPPER_BOUND = DiagnosticFactory0.create(ERROR);
|
||||
|
||||
DiagnosticFactory0<JetTypeParameter> MISPLACED_TYPE_PARAMETER_CONSTRAINTS = DiagnosticFactory0.create(WARNING);
|
||||
|
||||
+2
@@ -629,6 +629,8 @@ public class DefaultErrorMessages {
|
||||
MAP.put(REIFIED_TYPE_FORBIDDEN_SUBSTITUTION, "Cannot use ''{0}'' as reified type parameter", RENDER_TYPE);
|
||||
MAP.put(TYPE_PARAMETERS_NOT_ALLOWED, "Type parameters are not allowed here");
|
||||
|
||||
MAP.put(TYPE_PARAMETER_OF_PROPERTY_NOT_USED_IN_RECEIVER, "Type parameter of a property must be used in its receiver type");
|
||||
|
||||
MAP.put(SUPERTYPES_FOR_ANNOTATION_CLASS, "Annotation class cannot have supertypes");
|
||||
MAP.put(MISSING_VAL_ON_ANNOTATION_PARAMETER, "'val' keyword is missing on annotation parameter");
|
||||
MAP.put(ANNOTATION_CLASS_CONSTRUCTOR_CALL, "Annotation class cannot be instantiated");
|
||||
|
||||
@@ -20,6 +20,7 @@ import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import kotlin.jvm.functions.Function1;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
|
||||
@@ -471,6 +472,33 @@ public class DeclarationsChecker {
|
||||
checkAccessors(property, propertyDescriptor);
|
||||
checkTypeParameterConstraints(property);
|
||||
checkPropertyExposedType(property, propertyDescriptor);
|
||||
checkPropertyTypeParametersAreUsedInReceiverType(propertyDescriptor);
|
||||
}
|
||||
|
||||
private void checkPropertyTypeParametersAreUsedInReceiverType(@NotNull PropertyDescriptor descriptor) {
|
||||
for (TypeParameterDescriptor typeParameter : descriptor.getTypeParameters()) {
|
||||
if (isTypeParameterUsedInReceiverType(typeParameter, descriptor)) continue;
|
||||
|
||||
PsiElement typeParameterPsi = DescriptorToSourceUtils.getSourceFromDescriptor(typeParameter);
|
||||
if (typeParameterPsi instanceof JetTypeParameter) {
|
||||
trace.report(TYPE_PARAMETER_OF_PROPERTY_NOT_USED_IN_RECEIVER.on((JetTypeParameter) typeParameterPsi));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isTypeParameterUsedInReceiverType(
|
||||
@NotNull final TypeParameterDescriptor parameter,
|
||||
@NotNull PropertyDescriptor descriptor
|
||||
) {
|
||||
ReceiverParameterDescriptor receiverParameter = descriptor.getExtensionReceiverParameter();
|
||||
if (receiverParameter == null) return false;
|
||||
|
||||
return TypeUtils.containsSpecialType(receiverParameter.getType(), new Function1<JetType, Boolean>() {
|
||||
@Override
|
||||
public Boolean invoke(JetType type) {
|
||||
return parameter.equals(type.getConstructor().getDeclarationDescriptor());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void checkPropertyLateInit(@NotNull JetCallableDeclaration property, @NotNull PropertyDescriptor propertyDescriptor) {
|
||||
|
||||
Reference in New Issue
Block a user