Prohibit type parameters for enum classes

#KT-5696 Fixed
This commit is contained in:
Alexander Udalov
2014-10-17 15:01:26 +04:00
parent 63366042ed
commit ae401cac0f
17 changed files with 114 additions and 109 deletions
@@ -178,7 +178,7 @@ public interface Errors {
.create(ERROR, modifierSetPosition(JetTokens.ABSTRACT_KEYWORD));
DiagnosticFactory0<PsiElement> CLASS_IN_SUPERTYPE_FOR_ENUM = DiagnosticFactory0.create(ERROR);
DiagnosticFactory0<JetTypeParameterList> TYPE_PARAMETERS_IN_ENUM = DiagnosticFactory0.create(ERROR);
DiagnosticFactory1<JetClass, ClassDescriptor> ENUM_ENTRY_SHOULD_BE_INITIALIZED = DiagnosticFactory1.create(ERROR, DECLARATION_NAME);
DiagnosticFactory1<JetTypeReference, ClassDescriptor> ENUM_ENTRY_ILLEGAL_TYPE = DiagnosticFactory1.create(ERROR);
DiagnosticFactory1<JetClass, ClassDescriptor> LOCAL_ENUM_NOT_ALLOWED = DiagnosticFactory1.create(ERROR, DECLARATION_NAME);
@@ -102,6 +102,7 @@ public class DefaultErrorMessages {
MAP.put(ILLEGAL_ENUM_ANNOTATION, "Annotation ''enum'' is only applicable for class");
MAP.put(REDUNDANT_MODIFIER_IN_GETTER, "Visibility modifiers are redundant in getter");
MAP.put(TRAIT_CAN_NOT_BE_FINAL, "Trait cannot be final");
MAP.put(TYPE_PARAMETERS_IN_ENUM, "Enum class cannot have type parameters");
MAP.put(TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM,
"Type checking has run into a recursive problem. Easiest workaround: specify types of your declarations explicitly"); // TODO: message
MAP.put(RETURN_NOT_ALLOWED, "'return' is not allowed here");
@@ -114,9 +114,16 @@ public class DescriptorResolver {
BindingTrace trace
) {
// TODO : Where-clause
List<TypeParameterDescriptor> typeParameters = Lists.newArrayList();
List<JetTypeParameter> typeParameters = classElement.getTypeParameters();
List<TypeParameterDescriptor> typeParameterDescriptors = new ArrayList<TypeParameterDescriptor>(typeParameters.size());
if (descriptor.getKind() == ClassKind.ENUM_CLASS) {
JetTypeParameterList typeParameterList = classElement.getTypeParameterList();
if (typeParameterList != null) {
trace.report(TYPE_PARAMETERS_IN_ENUM.on(typeParameterList));
}
}
int index = 0;
for (JetTypeParameter typeParameter : classElement.getTypeParameters()) {
for (JetTypeParameter typeParameter : typeParameters) {
if (!topDownAnalysisParameters.isLazyTopDownAnalysis()) {
// TODO: Support
AnnotationResolver.reportUnsupportedAnnotationForTypeParameter(typeParameter, trace);
@@ -132,10 +139,10 @@ public class DescriptorResolver {
toSourceElement(typeParameter)
);
trace.record(BindingContext.TYPE_PARAMETER, typeParameter, typeParameterDescriptor);
typeParameters.add(typeParameterDescriptor);
typeParameterDescriptors.add(typeParameterDescriptor);
index++;
}
descriptor.setTypeParameterDescriptors(typeParameters);
descriptor.setTypeParameterDescriptors(typeParameterDescriptors);
Modality defaultModality = descriptor.getKind() == ClassKind.TRAIT ? Modality.ABSTRACT : Modality.FINAL;
descriptor.setModality(resolveModalityFromModifiers(classElement, defaultModality));
descriptor.setVisibility(resolveVisibilityFromModifiers(classElement, getDefaultClassVisibility(descriptor)));
@@ -17,14 +17,13 @@
package org.jetbrains.jet.lang.resolve.lazy.data;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.ClassKind;
import org.jetbrains.jet.lang.psi.*;
import java.util.List;
public class JetClassInfo extends JetClassOrObjectInfo<JetClass> {
@NotNull
private final ClassKind kind;
protected JetClassInfo(@NotNull JetClass classOrObject) {
@@ -51,10 +50,10 @@ public class JetClassInfo extends JetClassOrObjectInfo<JetClass> {
return element.getClassObject();
}
@NotNull
@Nullable
@Override
public List<JetTypeParameter> getTypeParameters() {
return element.getTypeParameters();
public JetTypeParameterList getTypeParameterList() {
return element.getTypeParameterList();
}
@NotNull
@@ -27,7 +27,6 @@ import org.jetbrains.jet.lang.resolve.name.FqName;
import java.util.List;
public interface JetClassLikeInfo extends JetDeclarationContainer {
@NotNull
FqName getContainingPackageFqName();
@@ -48,9 +47,8 @@ public interface JetClassLikeInfo extends JetDeclarationContainer {
@Nullable
JetClassOrObject getCorrespondingClassOrObject();
@NotNull
@ReadOnly
List<JetTypeParameter> getTypeParameters();
@Nullable
JetTypeParameterList getTypeParameterList();
@NotNull
@ReadOnly
@@ -17,14 +17,17 @@
package org.jetbrains.jet.lang.resolve.lazy.data;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.ClassKind;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.psi.JetClassObject;
import org.jetbrains.jet.lang.psi.JetObjectDeclaration;
import org.jetbrains.jet.lang.psi.JetParameter;
import org.jetbrains.jet.lang.psi.JetTypeParameterList;
import java.util.Collections;
import java.util.List;
public class JetObjectInfo extends JetClassOrObjectInfo<JetObjectDeclaration> {
@NotNull
private final ClassKind kind;
@@ -38,10 +41,10 @@ public class JetObjectInfo extends JetClassOrObjectInfo<JetObjectDeclaration> {
return null;
}
@NotNull
@Nullable
@Override
public List<JetTypeParameter> getTypeParameters() {
return Collections.emptyList();
public JetTypeParameterList getTypeParameterList() {
return null;
}
@NotNull
@@ -16,16 +16,10 @@
package org.jetbrains.jet.lang.resolve.lazy.data
import org.jetbrains.jet.lang.psi.JetTypeParameter
import org.jetbrains.jet.lang.psi.JetParameter
import org.jetbrains.jet.lang.psi.*
import org.jetbrains.jet.lang.descriptors.ClassKind
import org.jetbrains.jet.lang.psi.JetScript
import org.jetbrains.jet.lang.resolve.ScriptNameUtil
import org.jetbrains.jet.lang.psi.JetNamedFunction
import org.jetbrains.jet.lang.psi.JetDeclaration
import org.jetbrains.jet.lang.psi.JetCallableDeclaration
import org.jetbrains.jet.lang.resolve.name.FqName
import org.jetbrains.jet.lang.psi.JetClassObject
public class JetScriptInfo(
val script: JetScript
@@ -37,7 +31,7 @@ public class JetScriptInfo(
override fun getClassObjects() = listOf<JetClassObject>()
override fun getScopeAnchor() = script
override fun getCorrespondingClassOrObject() = null
override fun getTypeParameters() = listOf<JetTypeParameter>()
override fun getTypeParameterList() = null
override fun getPrimaryConstructorParameters() = listOf<JetParameter>()
override fun getClassKind() = ClassKind.CLASS
override fun getDeclarations() = script.getDeclarations()
@@ -78,10 +78,10 @@ public class SyntheticClassObjectInfo implements JetClassLikeInfo {
return null;
}
@NotNull
@Nullable
@Override
public List<JetTypeParameter> getTypeParameters() {
return Collections.emptyList();
public JetTypeParameterList getTypeParameterList() {
return null;
}
@NotNull
@@ -58,6 +58,7 @@ import org.jetbrains.jet.storage.StorageManager;
import java.util.*;
import static org.jetbrains.jet.lang.diagnostics.Errors.CLASS_OBJECT_NOT_ALLOWED;
import static org.jetbrains.jet.lang.diagnostics.Errors.TYPE_PARAMETERS_IN_ENUM;
import static org.jetbrains.jet.lang.resolve.DescriptorUtils.isSyntheticClassObject;
import static org.jetbrains.jet.lang.resolve.ModifiersChecker.*;
import static org.jetbrains.jet.lang.resolve.name.SpecialNames.getClassObjectName;
@@ -529,8 +530,14 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDes
@Override
public List<TypeParameterDescriptor> invoke() {
JetClassLikeInfo classInfo = declarationProvider.getOwnerInfo();
List<JetTypeParameter> typeParameters = classInfo.getTypeParameters();
JetTypeParameterList typeParameterList = classInfo.getTypeParameterList();
if (typeParameterList == null) return Collections.emptyList();
if (classInfo.getClassKind() == ClassKind.ENUM_CLASS) {
resolveSession.getTrace().report(TYPE_PARAMETERS_IN_ENUM.on(typeParameterList));
}
List<JetTypeParameter> typeParameters = typeParameterList.getParameters();
List<TypeParameterDescriptor> parameters = new ArrayList<TypeParameterDescriptor>(typeParameters.size());
for (int i = 0; i < typeParameters.size(); i++) {
parameters.add(new LazyTypeParameterDescriptor(resolveSession, LazyClassDescriptor.this, typeParameters.get(i), i));
@@ -1,5 +1,7 @@
enum class List<out T>(val size : Int) {
Nil : List<Nothing>(0)
class List<out T>(val size : Int) {
class object {
val Nil = List<Nothing>(0)
}
}
fun List<String>.join() =
@@ -1,40 +1,19 @@
package
package
internal fun List<kotlin.String>.join(): kotlin.String
internal final enum class List</*0*/ out T> : kotlin.Enum<List<T>> {
private constructor List</*0*/ out T>(/*0*/ size: kotlin.Int)
internal final class List</*0*/ out T> {
public constructor List</*0*/ out T>(/*0*/ size: kotlin.Int)
internal final val size: kotlin.Int
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: List<T>): 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 equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
public enum entry Nil : List<kotlin.Nothing> {
private constructor Nil()
internal final override /*1*/ /*fake_override*/ val size: kotlin.Int
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: List<kotlin.Nothing>): 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
internal class object <class-object-for-List> {
private constructor <class-object-for-List>()
internal final val Nil: List<kotlin.Nothing>
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
public class object <class-object-for-Nil> : List.Nil {
private constructor <class-object-for-Nil>()
internal final override /*1*/ /*fake_override*/ val size: kotlin.Int
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: List<kotlin.Nothing>): 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): List<T>
public final /*synthesized*/ fun values(): kotlin.Array<List<T>>
}
}
@@ -0,0 +1,7 @@
// KT-5696 Prohibit type parameters for enum classes
package bug
public enum class Foo<!TYPE_PARAMETERS_IN_ENUM!><T><!> {
A : Foo<String>()
}
@@ -0,0 +1,38 @@
package
package bug {
public final enum class Foo</*0*/ T> : kotlin.Enum<bug.Foo<T>> {
private constructor Foo</*0*/ T>()
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: bug.Foo<T>): 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 A : bug.Foo<kotlin.String> {
private constructor A()
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: bug.Foo<kotlin.String>): 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 class object <class-object-for-A> : bug.Foo.A {
private constructor <class-object-for-A>()
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: bug.Foo<kotlin.String>): 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): bug.Foo<T>
public final /*synthesized*/ fun values(): kotlin.Array<bug.Foo<T>>
}
}
@@ -10,13 +10,6 @@ enum class ProtocolState {
abstract fun signal() : ProtocolState
}
enum class Foo<T> {
<!NO_GENERICS_IN_SUPERTYPE_SPECIFIER!>X<!>
}
fun box() {
val <!UNUSED_VARIABLE!>x<!>: ProtocolState = ProtocolState.WAITING
}
@@ -1,29 +1,7 @@
package
package
internal fun box(): kotlin.Unit
internal final enum class Foo</*0*/ T> : kotlin.Enum<Foo<T>> {
private constructor Foo</*0*/ T>()
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: Foo<T>): 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 {
private constructor X()
public class object <class-object-for-X> : Foo.X {
private constructor <class-object-for-X>()
}
}
// Static members
public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): Foo<T>
public final /*synthesized*/ fun values(): kotlin.Array<Foo<T>>
}
internal final enum class ProtocolState : kotlin.Enum<ProtocolState> {
private constructor ProtocolState()
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: ProtocolState): kotlin.Int
@@ -33,7 +11,7 @@ internal final enum class ProtocolState : kotlin.Enum<ProtocolState> {
public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int
internal abstract fun signal(): ProtocolState
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
public enum entry TALKING : ProtocolState {
private constructor TALKING()
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: ProtocolState): kotlin.Int
@@ -43,7 +21,7 @@ internal final enum class ProtocolState : kotlin.Enum<ProtocolState> {
public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int
internal open override /*1*/ fun signal(): ProtocolState
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
public class object <class-object-for-TALKING> : ProtocolState.TALKING {
private constructor <class-object-for-TALKING>()
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: ProtocolState): kotlin.Int
@@ -55,7 +33,7 @@ internal final enum class ProtocolState : kotlin.Enum<ProtocolState> {
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
}
public enum entry WAITING : ProtocolState {
private constructor WAITING()
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: ProtocolState): kotlin.Int
@@ -65,7 +43,7 @@ internal final enum class ProtocolState : kotlin.Enum<ProtocolState> {
public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int
internal open override /*1*/ fun signal(): ProtocolState
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
public class object <class-object-for-WAITING> : ProtocolState.WAITING {
private constructor <class-object-for-WAITING>()
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: ProtocolState): kotlin.Int
@@ -77,8 +55,8 @@ internal final enum class ProtocolState : kotlin.Enum<ProtocolState> {
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
}
// Static members
public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): ProtocolState
public final /*synthesized*/ fun values(): kotlin.Array<ProtocolState>
}
}
@@ -3931,6 +3931,12 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest {
doTest(fileName);
}
@TestMetadata("typeParametersInEnum.kt")
public void testTypeParametersInEnum() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/enum/typeParametersInEnum.kt");
doTest(fileName);
}
@TestMetadata("valuesValueOfAndEntriesAccessibility.kt")
public void testValuesValueOfAndEntriesAccessibility() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/enum/valuesValueOfAndEntriesAccessibility.kt");
@@ -10,13 +10,6 @@ enum class ProtocolState {
abstract fun signal() : ProtocolState
}
enum class Foo<T> {
<error>X</error>
}
fun box() {
val <warning>x</warning>: ProtocolState = ProtocolState.WAITING
}