Introduce warning for secondary constructor in enums without delegation to primary constructors (KT-35870)
This commit is contained in:
@@ -388,6 +388,9 @@ public interface Errors {
|
||||
DiagnosticFactory0<KtConstructorDelegationCall> PRIMARY_CONSTRUCTOR_DELEGATION_CALL_EXPECTED =
|
||||
DiagnosticFactory0.create(ERROR, PositioningStrategies.SECONDARY_CONSTRUCTOR_DELEGATION_CALL);
|
||||
|
||||
DiagnosticFactory0<KtConstructorDelegationCall> PRIMARY_CONSTRUCTOR_DELEGATION_CALL_EXPECTED_IN_ENUM =
|
||||
DiagnosticFactory0.create(WARNING, PositioningStrategies.SECONDARY_CONSTRUCTOR_DELEGATION_CALL);
|
||||
|
||||
DiagnosticFactory0<KtConstructorDelegationReferenceExpression> DELEGATION_SUPER_CALL_IN_ENUM_CONSTRUCTOR =
|
||||
DiagnosticFactory0.create(ERROR);
|
||||
|
||||
|
||||
+1
@@ -634,6 +634,7 @@ public class DefaultErrorMessages {
|
||||
MAP.put(CONSTRUCTOR_IN_OBJECT, "Constructors are not allowed for objects");
|
||||
MAP.put(SUPERTYPE_INITIALIZED_WITHOUT_PRIMARY_CONSTRUCTOR, "Supertype initialization is impossible without primary constructor");
|
||||
MAP.put(PRIMARY_CONSTRUCTOR_DELEGATION_CALL_EXPECTED, "Primary constructor call expected");
|
||||
MAP.put(PRIMARY_CONSTRUCTOR_DELEGATION_CALL_EXPECTED_IN_ENUM, "Primary constructor call expected. It's going to be an error in 1.5.");
|
||||
MAP.put(DELEGATION_SUPER_CALL_IN_ENUM_CONSTRUCTOR, "Call to super is not allowed in enum constructor");
|
||||
MAP.put(PRIMARY_CONSTRUCTOR_REQUIRED_FOR_DATA_CLASS, "Primary constructor required for data class");
|
||||
MAP.put(EXPLICIT_DELEGATION_CALL_REQUIRED,
|
||||
|
||||
@@ -17,6 +17,7 @@ import org.jetbrains.kotlin.config.LanguageFeature;
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings;
|
||||
import org.jetbrains.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations;
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticFactory0;
|
||||
import org.jetbrains.kotlin.name.Name;
|
||||
import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus;
|
||||
import org.jetbrains.kotlin.psi.*;
|
||||
@@ -334,8 +335,12 @@ public class CallResolver {
|
||||
KtConstructorDelegationCall delegationCall = (KtConstructorDelegationCall) context.call.getCallElement();
|
||||
DeclarationDescriptor container = context.scope.getOwnerDescriptor();
|
||||
assert container instanceof ConstructorDescriptor : "Trying to resolve JetConstructorDelegationCall not in constructor. scope.ownerDescriptor = " + container;
|
||||
return (OverloadResolutionResults) resolveConstructorDelegationCall(context, delegationCall, (KtConstructorDelegationReferenceExpression) calleeExpression,
|
||||
(ClassConstructorDescriptor) container);
|
||||
return (OverloadResolutionResults) resolveConstructorDelegationCall(
|
||||
context,
|
||||
delegationCall,
|
||||
(KtConstructorDelegationReferenceExpression) calleeExpression,
|
||||
(ClassDescriptor) container.getContainingDeclaration()
|
||||
);
|
||||
}
|
||||
else if (calleeExpression == null) {
|
||||
return checkArgumentTypesAndFail(context);
|
||||
@@ -433,18 +438,28 @@ public class CallResolver {
|
||||
dataFlowValueFactory,
|
||||
InferenceSession.Companion.getDefault());
|
||||
|
||||
if (call.getCalleeExpression() == null) return checkArgumentTypesAndFail(context);
|
||||
KtConstructorDelegationReferenceExpression calleeExpression = call.getCalleeExpression();
|
||||
|
||||
if (calleeExpression == null) return checkArgumentTypesAndFail(context);
|
||||
|
||||
ClassDescriptor currentClassDescriptor = constructorDescriptor.getContainingDeclaration();
|
||||
|
||||
if (constructorDescriptor.getConstructedClass().getKind() == ClassKind.ENUM_CLASS && call.isImplicit()) {
|
||||
if (currentClassDescriptor.getUnsubstitutedPrimaryConstructor() != null) {
|
||||
DiagnosticFactory0<KtConstructorDelegationCall> warningOrError;
|
||||
|
||||
if (languageVersionSettings.supportsFeature(LanguageFeature.RequiredPrimaryConstructorDelegationCallInEnums)) {
|
||||
warningOrError = PRIMARY_CONSTRUCTOR_DELEGATION_CALL_EXPECTED; // error
|
||||
} else {
|
||||
warningOrError = PRIMARY_CONSTRUCTOR_DELEGATION_CALL_EXPECTED_IN_ENUM; // warning
|
||||
}
|
||||
|
||||
context.trace.report(warningOrError.on((KtConstructorDelegationCall) calleeExpression.getParent()));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
return resolveConstructorDelegationCall(
|
||||
context,
|
||||
call,
|
||||
call.getCalleeExpression(),
|
||||
constructorDescriptor
|
||||
);
|
||||
return resolveConstructorDelegationCall(context, call, call.getCalleeExpression(), currentClassDescriptor);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -452,12 +467,10 @@ public class CallResolver {
|
||||
@NotNull BasicCallResolutionContext context,
|
||||
@NotNull KtConstructorDelegationCall call,
|
||||
@NotNull KtConstructorDelegationReferenceExpression calleeExpression,
|
||||
@NotNull ClassConstructorDescriptor calleeConstructor
|
||||
@NotNull ClassDescriptor currentClassDescriptor
|
||||
) {
|
||||
context.trace.record(BindingContext.LEXICAL_SCOPE, call, context.scope);
|
||||
|
||||
ClassDescriptor currentClassDescriptor = calleeConstructor.getContainingDeclaration();
|
||||
|
||||
boolean isThisCall = calleeExpression.isThis();
|
||||
if (currentClassDescriptor.getKind() == ClassKind.ENUM_CLASS && !isThisCall) {
|
||||
context.trace.report(DELEGATION_SUPER_CALL_IN_ENUM_CONSTRUCTOR.on(calleeExpression));
|
||||
@@ -484,9 +497,8 @@ public class CallResolver {
|
||||
}
|
||||
|
||||
|
||||
KotlinType superType = isThisCall ?
|
||||
calleeConstructor.getContainingDeclaration().getDefaultType() :
|
||||
DescriptorUtils.getSuperClassType(currentClassDescriptor);
|
||||
KotlinType superType =
|
||||
isThisCall ? currentClassDescriptor.getDefaultType() : DescriptorUtils.getSuperClassType(currentClassDescriptor);
|
||||
|
||||
Pair<Collection<ResolutionCandidate<ConstructorDescriptor>>, BasicCallResolutionContext> candidatesAndContext =
|
||||
prepareCandidatesAndContextForConstructorCall(superType, context, syntheticScopes);
|
||||
|
||||
Reference in New Issue
Block a user