Prohibit explicit super call for enum ctrs
This commit is contained in:
@@ -160,6 +160,7 @@ public interface Errors {
|
||||
DiagnosticFactory0<JetDelegatorToSuperCall> SUPERTYPE_INITIALIZED_WITHOUT_PRIMARY_CONSTRUCTOR = DiagnosticFactory0.create(ERROR);
|
||||
DiagnosticFactory0<JetConstructorDelegationCall> PRIMARY_CONSTRUCTOR_DELEGATION_CALL_EXPECTED = DiagnosticFactory0.create(ERROR);
|
||||
DiagnosticFactory0<PsiElement> INIT_KEYWORD_BEFORE_CLASS_INITIALIZER_EXPECTED = DiagnosticFactory0.create(WARNING);
|
||||
DiagnosticFactory0<JetConstructorDelegationCall> DELEGATION_SUPER_CALL_IN_ENUM_CONSTRUCTOR = DiagnosticFactory0.create(ERROR);
|
||||
|
||||
// Trait-specific
|
||||
|
||||
|
||||
+1
@@ -417,6 +417,7 @@ public class DefaultErrorMessages {
|
||||
MAP.put(SECONDARY_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(DELEGATION_SUPER_CALL_IN_ENUM_CONSTRUCTOR, "Call to super is not allowed in enum constructor");
|
||||
|
||||
MAP.put(INIT_KEYWORD_BEFORE_CLASS_INITIALIZER_EXPECTED, "Expecting 'init' keyword before class initializer");
|
||||
|
||||
|
||||
+4
@@ -28,4 +28,8 @@ public class JetConstructorDelegationReferenceExpression extends JetExpressionIm
|
||||
public boolean isThis() {
|
||||
return findChildByType(JetTokens.THIS_KEYWORD) != null;
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return getFirstChild() == null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -171,6 +171,10 @@ public class BodyResolver {
|
||||
if (call == null || call.getCalleeExpression() == null) return;
|
||||
JetType superClassType = DescriptorUtils.getSuperClassType(descriptor.getContainingDeclaration());
|
||||
|
||||
if (descriptor.getContainingDeclaration().getKind() == ClassKind.ENUM_CLASS && call.getCalleeExpression().isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
OverloadResolutionResults<?> results = callResolver.resolveFunctionCall(
|
||||
trace, scope,
|
||||
CallMaker.makeCall(ReceiverValue.NO_RECEIVER, null, call),
|
||||
|
||||
@@ -568,8 +568,7 @@ public class DeclarationsChecker {
|
||||
|
||||
List<JetDelegationSpecifier> delegationSpecifiers = enumEntry.getDelegationSpecifiers();
|
||||
ConstructorDescriptor constructor = enumClass.getUnsubstitutedPrimaryConstructor();
|
||||
assert constructor != null;
|
||||
if (!constructor.getValueParameters().isEmpty() && delegationSpecifiers.isEmpty()) {
|
||||
if ((constructor == null || !constructor.getValueParameters().isEmpty()) && delegationSpecifiers.isEmpty()) {
|
||||
trace.report(ENUM_ENTRY_SHOULD_BE_INITIALIZED.on(enumEntry, enumClass));
|
||||
}
|
||||
|
||||
|
||||
@@ -52,9 +52,7 @@ import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static org.jetbrains.kotlin.diagnostics.Errors.EXPECTED_PRIMARY_CONSTRUCTOR_DELEGATION_CALL;
|
||||
import static org.jetbrains.kotlin.diagnostics.Errors.NOT_A_CLASS;
|
||||
import static org.jetbrains.kotlin.diagnostics.Errors.NO_CONSTRUCTOR;
|
||||
import static org.jetbrains.kotlin.diagnostics.Errors.*;
|
||||
import static org.jetbrains.kotlin.resolve.bindingContextUtil.BindingContextUtilPackage.recordScopeAndDataFlowInfo;
|
||||
import static org.jetbrains.kotlin.resolve.calls.CallResolverUtil.ResolveArgumentsMode.RESOLVE_FUNCTION_ARGUMENTS;
|
||||
import static org.jetbrains.kotlin.resolve.calls.CallResolverUtil.ResolveArgumentsMode.SHAPE_FUNCTION_ARGUMENTS;
|
||||
@@ -297,6 +295,10 @@ public class CallResolver {
|
||||
@NotNull JetConstructorDelegationReferenceExpression calleeExpression
|
||||
) {
|
||||
ClassDescriptor currentClassDescriptor = getClassDescriptorByConstructorContext(context);
|
||||
if (currentClassDescriptor.getKind() == ClassKind.ENUM_CLASS && !calleeExpression.isThis()) {
|
||||
context.trace.report(DELEGATION_SUPER_CALL_IN_ENUM_CONSTRUCTOR.on((JetConstructorDelegationCall) calleeExpression.getParent()));
|
||||
return checkArgumentTypesAndFail(context);
|
||||
}
|
||||
|
||||
ClassDescriptor delegateClassDescriptor = calleeExpression.isThis() ? currentClassDescriptor :
|
||||
DescriptorUtilPackage.getSuperClassOrAny(currentClassDescriptor);
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||
enum class A {
|
||||
W: A(1) X: A(1, 2) Y: A(3.0) Z: A("") E: A()
|
||||
|
||||
constructor() {}
|
||||
constructor(x: Int) {}
|
||||
constructor(x: Int, y: Int): this(x+y) {}
|
||||
constructor(x: Double): this(x.toInt(), 1) {}
|
||||
constructor(x: String): <!DELEGATION_SUPER_CALL_IN_ENUM_CONSTRUCTOR!>super(x, 1)<!> {}
|
||||
}
|
||||
|
||||
enum class B(x: Int) {
|
||||
W: B(1) X: B(1, 2) Y: B(3.0) Z: B("")
|
||||
|
||||
constructor(x: Int, y: Int): this(x+y) {}
|
||||
constructor(x: Double): this(x.toInt(), 1) {}
|
||||
constructor(x: String): <!DELEGATION_SUPER_CALL_IN_ENUM_CONSTRUCTOR!>super(x, 1)<!> {}
|
||||
}
|
||||
|
||||
enum class C {
|
||||
EMPTY: C() // may be we should avoid explicit call here
|
||||
constructor() {}
|
||||
}
|
||||
|
||||
enum class D(val prop: Int) {
|
||||
X: D(123) {
|
||||
override fun f() = 1
|
||||
}
|
||||
Y: D() {
|
||||
override fun f() = prop
|
||||
}
|
||||
Z: D("abc") {
|
||||
override fun f() = prop
|
||||
}
|
||||
|
||||
constructor(): this(1) {}
|
||||
constructor(x: String): this(x.length()) {}
|
||||
|
||||
abstract fun f(): Int
|
||||
}
|
||||
@@ -0,0 +1,204 @@
|
||||
package
|
||||
|
||||
internal final enum class A : kotlin.Enum<A> {
|
||||
public enum entry W : A {
|
||||
private constructor W()
|
||||
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: A): kotlin.Int
|
||||
public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public final override /*1*/ /*fake_override*/ fun name(): kotlin.String
|
||||
public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public enum entry X : A {
|
||||
private constructor X()
|
||||
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: A): kotlin.Int
|
||||
public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public final override /*1*/ /*fake_override*/ fun name(): kotlin.String
|
||||
public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public enum entry Y : A {
|
||||
private constructor Y()
|
||||
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: A): kotlin.Int
|
||||
public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public final override /*1*/ /*fake_override*/ fun name(): kotlin.String
|
||||
public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public enum entry Z : A {
|
||||
private constructor Z()
|
||||
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: A): kotlin.Int
|
||||
public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public final override /*1*/ /*fake_override*/ fun name(): kotlin.String
|
||||
public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public enum entry E : A {
|
||||
private constructor E()
|
||||
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: A): kotlin.Int
|
||||
public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public final override /*1*/ /*fake_override*/ fun name(): kotlin.String
|
||||
public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
private constructor A()
|
||||
private constructor A(/*0*/ x: kotlin.Double)
|
||||
private constructor A(/*0*/ x: kotlin.Int)
|
||||
private constructor A(/*0*/ x: kotlin.Int, /*1*/ y: kotlin.Int)
|
||||
private constructor A(/*0*/ x: kotlin.String)
|
||||
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: A): kotlin.Int
|
||||
public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public final override /*1*/ /*fake_override*/ fun name(): kotlin.String
|
||||
public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
|
||||
// Static members
|
||||
public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): A
|
||||
public final /*synthesized*/ fun values(): kotlin.Array<A>
|
||||
}
|
||||
|
||||
internal final enum class B : kotlin.Enum<B> {
|
||||
public enum entry W : B {
|
||||
private constructor W()
|
||||
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: B): kotlin.Int
|
||||
public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public final override /*1*/ /*fake_override*/ fun name(): kotlin.String
|
||||
public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public enum entry X : B {
|
||||
private constructor X()
|
||||
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: B): kotlin.Int
|
||||
public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public final override /*1*/ /*fake_override*/ fun name(): kotlin.String
|
||||
public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public enum entry Y : B {
|
||||
private constructor Y()
|
||||
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: B): kotlin.Int
|
||||
public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public final override /*1*/ /*fake_override*/ fun name(): kotlin.String
|
||||
public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public enum entry Z : B {
|
||||
private constructor Z()
|
||||
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: B): kotlin.Int
|
||||
public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public final override /*1*/ /*fake_override*/ fun name(): kotlin.String
|
||||
public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
private constructor B(/*0*/ x: kotlin.Double)
|
||||
private constructor B(/*0*/ x: kotlin.Int)
|
||||
private constructor B(/*0*/ x: kotlin.Int, /*1*/ y: kotlin.Int)
|
||||
private constructor B(/*0*/ x: kotlin.String)
|
||||
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: B): kotlin.Int
|
||||
public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public final override /*1*/ /*fake_override*/ fun name(): kotlin.String
|
||||
public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
|
||||
// Static members
|
||||
public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): B
|
||||
public final /*synthesized*/ fun values(): kotlin.Array<B>
|
||||
}
|
||||
|
||||
internal final enum class C : kotlin.Enum<C> {
|
||||
public enum entry EMPTY : C {
|
||||
private constructor EMPTY()
|
||||
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: C): kotlin.Int
|
||||
public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public final override /*1*/ /*fake_override*/ fun name(): kotlin.String
|
||||
public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
private constructor C()
|
||||
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: C): kotlin.Int
|
||||
public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public final override /*1*/ /*fake_override*/ fun name(): kotlin.String
|
||||
public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
|
||||
// Static members
|
||||
public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): C
|
||||
public final /*synthesized*/ fun values(): kotlin.Array<C>
|
||||
}
|
||||
|
||||
internal final enum class D : kotlin.Enum<D> {
|
||||
public enum entry X : D {
|
||||
private constructor X()
|
||||
internal final override /*1*/ /*fake_override*/ val prop: kotlin.Int
|
||||
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: D): kotlin.Int
|
||||
public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
internal open override /*1*/ fun f(): kotlin.Int
|
||||
public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public final override /*1*/ /*fake_override*/ fun name(): kotlin.String
|
||||
public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public enum entry Y : D {
|
||||
private constructor Y()
|
||||
internal final override /*1*/ /*fake_override*/ val prop: kotlin.Int
|
||||
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: D): kotlin.Int
|
||||
public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
internal open override /*1*/ fun f(): kotlin.Int
|
||||
public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public final override /*1*/ /*fake_override*/ fun name(): kotlin.String
|
||||
public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public enum entry Z : D {
|
||||
private constructor Z()
|
||||
internal final override /*1*/ /*fake_override*/ val prop: kotlin.Int
|
||||
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: D): kotlin.Int
|
||||
public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
internal open override /*1*/ fun f(): kotlin.Int
|
||||
public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public final override /*1*/ /*fake_override*/ fun name(): kotlin.String
|
||||
public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
private constructor D()
|
||||
private constructor D(/*0*/ prop: kotlin.Int)
|
||||
private constructor D(/*0*/ x: kotlin.String)
|
||||
internal final val prop: kotlin.Int
|
||||
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: D): kotlin.Int
|
||||
public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
internal abstract fun f(): kotlin.Int
|
||||
public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public final override /*1*/ /*fake_override*/ fun name(): kotlin.String
|
||||
public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
|
||||
// Static members
|
||||
public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): D
|
||||
public final /*synthesized*/ fun values(): kotlin.Array<D>
|
||||
}
|
||||
@@ -10469,6 +10469,12 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("enums.kt")
|
||||
public void testEnums() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/secondaryConstructors/enums.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("expectedInitKeywordOnInitializer.kt")
|
||||
public void testExpectedInitKeywordOnInitializer() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/secondaryConstructors/expectedInitKeywordOnInitializer.kt");
|
||||
|
||||
Reference in New Issue
Block a user