From b52f337f7f881fc70d5f2c52a3aa793fdd1bdc67 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Fri, 5 Sep 2014 13:39:33 +0400 Subject: [PATCH] Drop enum class object hack Place valueOf() and values() into the static scope of the corresponding enum class #KT-5580 Fixed #KT-2410 Fixed --- .../codegen/ImplementationBodyCodegen.java | 14 +- .../lang/resolve/TypeHierarchyResolver.java | 20 +-- .../lazy/descriptors/LazyClassDescriptor.java | 9 +- compiler/testData/builtin-classes.txt | 20 +-- .../codegen/box/enum/classObjectInEnum.kt | 19 +++ .../ClassObjectInEnum.A.kt | 9 ++ .../ClassObjectInEnum.B.kt | 5 + .../synthesized/enumValuesValueOf.kt | 12 ++ .../tests/enum/classObjectInEnum.kt | 9 ++ .../tests/enum/classObjectInEnumPrivate.kt | 10 ++ .../tests/enum/classObjectOfPrivateEnum.kt | 9 -- .../enum/starImportNestedClassAndEntries.kt | 2 +- .../EnumEntriesAndClassObjectMembers.kt | 11 ++ .../loadJava/compiledJava/EnumMembers.txt | 10 +- .../loadJava/compiledJava/JavaEnum.txt | 10 +- .../annotations/CustomAnnotation.txt | 10 +- .../loadJava/compiledJava/static/Enum.txt | 10 +- .../static/StaticMembersInEnum.txt | 8 +- .../parameters/EnumConstructor.txt | 8 +- .../EnumWithGenericConstructorParameter.txt | 8 +- .../EnumWithPrimitiveConstructorParameter.txt | 8 +- .../compiledKotlin/enum/enumVisibility.txt | 30 ++-- .../enum/enumWithConstuctor.txt | 10 +- .../compiledKotlin/enum/innerEnum.txt | 10 +- .../enum/innerEnumExistingClassObject.txt | 10 +- .../compiledKotlin/enum/simpleEnum.txt | 10 +- .../compiledKotlin/fromLoadJava/enum.txt | 10 +- .../checkers/JetDiagnosticsTestGenerated.java | 33 ++++- .../BlackBoxCodegenTestGenerated.java | 5 + ...mpileKotlinAgainstKotlinTestGenerated.java | 5 + .../descriptors/LazyJavaClassDescriptor.kt | 10 +- .../descriptors/LazyJavaClassMemberScope.kt | 2 + .../lazy/descriptors/LazyJavaMemberScope.kt | 29 ++-- .../lazy/descriptors/LazyJavaStaticScope.kt | 18 +++ .../resolver/DescriptorResolverUtils.java | 17 --- .../impl/EnumClassObjectDescriptor.kt | 140 ------------------ .../jet/lang/resolve/DescriptorFactory.java | 32 +++- .../jet/lang/resolve/DescriptorUtils.java | 8 +- .../jet/lang/resolve/DescriptorUtils.kt | 11 +- .../scopes/StaticScopeForKotlinClass.kt | 19 ++- .../DeserializedClassDescriptor.java | 5 - idea/testData/checker/ClassObjectInEnum.kt | 11 ++ .../checkers/JetPsiCheckerTestGenerated.java | 5 + 43 files changed, 299 insertions(+), 352 deletions(-) create mode 100644 compiler/testData/codegen/box/enum/classObjectInEnum.kt create mode 100644 compiler/testData/compileKotlinAgainstKotlin/ClassObjectInEnum.A.kt create mode 100644 compiler/testData/compileKotlinAgainstKotlin/ClassObjectInEnum.B.kt create mode 100644 compiler/testData/diagnostics/tests/duplicateJvmSignature/synthesized/enumValuesValueOf.kt create mode 100644 compiler/testData/diagnostics/tests/enum/classObjectInEnum.kt create mode 100644 compiler/testData/diagnostics/tests/enum/classObjectInEnumPrivate.kt delete mode 100644 compiler/testData/diagnostics/tests/enum/classObjectOfPrivateEnum.kt create mode 100644 compiler/testData/diagnostics/tests/redeclarations/EnumEntriesAndClassObjectMembers.kt delete mode 100644 core/descriptors/src/org/jetbrains/jet/lang/descriptors/impl/EnumClassObjectDescriptor.kt create mode 100644 idea/testData/checker/ClassObjectInEnum.kt diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java index 7e625bd4f93..b177e21677c 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java @@ -963,13 +963,11 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { } @NotNull - private FunctionDescriptor findEnumFunction(@NotNull String name, Function1 predicate) { - ClassDescriptor enumClassObject = descriptor.getClassObjectDescriptor(); - assert enumClassObject != null : "No class object in " + descriptor; - Collection valuesFunctions = enumClassObject.getDefaultType().getMemberScope().getFunctions(Name.identifier(name)); - FunctionDescriptor valuesFunction = KotlinPackage.firstOrNull(valuesFunctions, predicate); - assert valuesFunction != null : "No " + name + "() function found for " + descriptor; - return valuesFunction; + private FunctionDescriptor findEnumFunction(@NotNull String name, @NotNull Function1 predicate) { + Collection functions = descriptor.getStaticScope().getFunctions(Name.identifier(name)); + FunctionDescriptor function = KotlinPackage.firstOrNull(functions, predicate); + assert function != null : "No " + name + "() function found for " + descriptor; + return function; } protected void generateSyntheticAccessors() { @@ -1073,7 +1071,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { } private void generateFieldForSingleton() { - if (isEnumClass(descriptor) || isEnumEntry(descriptor)) return; + if (isEnumEntry(descriptor)) return; ClassDescriptor classObjectDescriptor = descriptor.getClassObjectDescriptor(); ClassDescriptor fieldTypeDescriptor; diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeHierarchyResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeHierarchyResolver.java index 34184de6cc4..1e7a430e4f7 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeHierarchyResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeHierarchyResolver.java @@ -21,7 +21,10 @@ import com.intellij.psi.PsiNameIdentifierOwner; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.*; -import org.jetbrains.jet.lang.descriptors.impl.*; +import org.jetbrains.jet.lang.descriptors.impl.ConstructorDescriptorImpl; +import org.jetbrains.jet.lang.descriptors.impl.MutableClassDescriptor; +import org.jetbrains.jet.lang.descriptors.impl.MutablePackageFragmentDescriptor; +import org.jetbrains.jet.lang.descriptors.impl.PackageLikeBuilder; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.lang.resolve.name.SpecialNames; @@ -30,7 +33,6 @@ import org.jetbrains.jet.lang.resolve.scopes.JetScope; import org.jetbrains.jet.lang.resolve.scopes.WritableScope; import org.jetbrains.jet.lang.resolve.scopes.WriteThroughScope; import org.jetbrains.jet.lang.types.JetType; -import org.jetbrains.jet.storage.LockBasedStorageManager; import org.jetbrains.jet.utils.DFS; import javax.inject.Inject; @@ -448,21 +450,13 @@ public class TypeHierarchyResolver { @NotNull JetClass klass, @NotNull DeclarationDescriptor containingDeclaration ) { - ClassKind kind = getClassKind(klass); - // Kind check is needed in order to not consider enums as inner in any case - // (otherwise it would be impossible to create a class object in the enum) - boolean isInner = kind == ClassKind.CLASS && klass.isInner(); MutableClassDescriptor descriptor = new MutableClassDescriptor( - containingDeclaration, outerScope, kind, isInner, JetPsiUtil.safeName(klass.getName()), - toSourceElement(klass)); + containingDeclaration, outerScope, getClassKind(klass), klass.isInner(), JetPsiUtil.safeName(klass.getName()), + toSourceElement(klass) + ); c.getDeclaredClasses().put(klass, descriptor); trace.record(FQNAME_TO_CLASS_DESCRIPTOR, JetNamedDeclarationUtil.getUnsafeFQName(klass), descriptor); - if (descriptor.getKind() == ClassKind.ENUM_CLASS) { - ClassDescriptor classObject = new EnumClassObjectDescriptor(LockBasedStorageManager.NO_LOCKS, descriptor); - descriptor.getBuilder().setClassObjectDescriptor(classObject); - } - prepareForDeferredCall(descriptor.getScopeForMemberDeclarationResolution(), descriptor, klass); return descriptor; diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/descriptors/LazyClassDescriptor.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/descriptors/LazyClassDescriptor.java index 3b26aff357d..b62d93e6dbe 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/descriptors/LazyClassDescriptor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/descriptors/LazyClassDescriptor.java @@ -31,7 +31,6 @@ import org.jetbrains.annotations.ReadOnly; import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.annotations.Annotations; import org.jetbrains.jet.lang.descriptors.impl.ClassDescriptorBase; -import org.jetbrains.jet.lang.descriptors.impl.EnumClassObjectDescriptor; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.DescriptorUtils; @@ -353,9 +352,6 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDes @Nullable private ClassDescriptor computeClassObjectDescriptor(@Nullable JetClassObject classObject) { - if (getKind() == ClassKind.ENUM_CLASS) { - return new EnumClassObjectDescriptor(resolveSession.getStorageManager(), this); - } JetClassLikeInfo classObjectInfo = getClassObjectInfo(classObject); if (classObjectInfo != null) { return new LazyClassDescriptor(resolveSession, this, getClassObjectName(getName()), classObjectInfo); @@ -366,12 +362,11 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDes @Nullable private JetClassLikeInfo getClassObjectInfo(@Nullable JetClassObject classObject) { if (classObject != null) { - if (getKind() != ClassKind.CLASS && getKind() != ClassKind.TRAIT && getKind() != ClassKind.ANNOTATION_CLASS || isInner()) { + if (getKind().isSingleton() || isInner()) { resolveSession.getTrace().report(CLASS_OBJECT_NOT_ALLOWED.on(classObject)); } - JetObjectDeclaration objectDeclaration = classObject.getObjectDeclaration(); - return JetClassInfoUtil.createClassLikeInfo(objectDeclaration); + return JetClassInfoUtil.createClassLikeInfo(classObject.getObjectDeclaration()); } else if (getKind() == ClassKind.OBJECT || getKind() == ClassKind.ENUM_ENTRY) { return new SyntheticClassObjectInfo(originalClassInfo, this); diff --git a/compiler/testData/builtin-classes.txt b/compiler/testData/builtin-classes.txt index 5b5f063a4f6..53d6cee47db 100644 --- a/compiler/testData/builtin-classes.txt +++ b/compiler/testData/builtin-classes.txt @@ -777,12 +777,6 @@ public final enum class InlineOption : kotlin.Enum { public final override /*1*/ /*fake_override*/ fun name(): kotlin.String public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int - public class object { - /*primary*/ private constructor () - public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): kotlin.InlineOption - public final /*synthesized*/ fun values(): kotlin.Array - } - public enum entry LOCAL_CONTINUE_AND_BREAK : kotlin.InlineOption { /*primary*/ private constructor LOCAL_CONTINUE_AND_BREAK() public final override /*1*/ /*fake_override*/ fun name(): kotlin.String @@ -806,6 +800,10 @@ public final enum class InlineOption : kotlin.Enum { public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int } } + + // Static members + public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): kotlin.InlineOption + public final /*synthesized*/ fun values(): kotlin.Array } public final enum class InlineStrategy : kotlin.Enum { @@ -813,12 +811,6 @@ public final enum class InlineStrategy : kotlin.Enum { public final override /*1*/ /*fake_override*/ fun name(): kotlin.String public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int - public class object { - /*primary*/ private constructor () - public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): kotlin.InlineStrategy - public final /*synthesized*/ fun values(): kotlin.Array - } - public enum entry AS_FUNCTION : kotlin.InlineStrategy { /*primary*/ private constructor AS_FUNCTION() public final override /*1*/ /*fake_override*/ fun name(): kotlin.String @@ -842,6 +834,10 @@ public final enum class InlineStrategy : kotlin.Enum { public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int } } + + // Static members + public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): kotlin.InlineStrategy + public final /*synthesized*/ fun values(): kotlin.Array } public final class Int : kotlin.Number, kotlin.Comparable { diff --git a/compiler/testData/codegen/box/enum/classObjectInEnum.kt b/compiler/testData/codegen/box/enum/classObjectInEnum.kt new file mode 100644 index 00000000000..2d466e8b304 --- /dev/null +++ b/compiler/testData/codegen/box/enum/classObjectInEnum.kt @@ -0,0 +1,19 @@ +enum class Game { + ROCK + PAPER + SCISSORS + + class object { + fun foo() = ROCK + val bar = PAPER + } +} + +fun box(): String { + if (Game.foo() != Game.ROCK) return "Fail 1" + // TODO: fix initialization order and uncomment + // if (Game.bar != Game.PAPER) return "Fail 2: ${Game.bar}" + if (Game.values().size != 3) return "Fail 3" + if (Game.valueOf("SCISSORS") != Game.SCISSORS) return "Fail 4" + return "OK" +} diff --git a/compiler/testData/compileKotlinAgainstKotlin/ClassObjectInEnum.A.kt b/compiler/testData/compileKotlinAgainstKotlin/ClassObjectInEnum.A.kt new file mode 100644 index 00000000000..1672e5c3267 --- /dev/null +++ b/compiler/testData/compileKotlinAgainstKotlin/ClassObjectInEnum.A.kt @@ -0,0 +1,9 @@ +package library + +public enum class EnumClass { + ENTRY + + public class object { + public fun entry(): EnumClass = ENTRY + } +} diff --git a/compiler/testData/compileKotlinAgainstKotlin/ClassObjectInEnum.B.kt b/compiler/testData/compileKotlinAgainstKotlin/ClassObjectInEnum.B.kt new file mode 100644 index 00000000000..16342e549b5 --- /dev/null +++ b/compiler/testData/compileKotlinAgainstKotlin/ClassObjectInEnum.B.kt @@ -0,0 +1,5 @@ +import library.EnumClass + +fun main(args: Array) { + if (EnumClass.entry() != EnumClass.ENTRY) throw AssertionError() +} diff --git a/compiler/testData/diagnostics/tests/duplicateJvmSignature/synthesized/enumValuesValueOf.kt b/compiler/testData/diagnostics/tests/duplicateJvmSignature/synthesized/enumValuesValueOf.kt new file mode 100644 index 00000000000..3bda966bc39 --- /dev/null +++ b/compiler/testData/diagnostics/tests/duplicateJvmSignature/synthesized/enumValuesValueOf.kt @@ -0,0 +1,12 @@ +enum class A { + A1 + A2 + + fun valueOf(s: String): A = valueOf(s) + + fun valueOf() = "OK" + + fun values(): Array = null!! + + fun values(x: String) = x +} diff --git a/compiler/testData/diagnostics/tests/enum/classObjectInEnum.kt b/compiler/testData/diagnostics/tests/enum/classObjectInEnum.kt new file mode 100644 index 00000000000..591f7fabdf0 --- /dev/null +++ b/compiler/testData/diagnostics/tests/enum/classObjectInEnum.kt @@ -0,0 +1,9 @@ +enum class E { + ENTRY + + class object { + fun entry() = ENTRY + } +} + +fun bar() = E.entry() diff --git a/compiler/testData/diagnostics/tests/enum/classObjectInEnumPrivate.kt b/compiler/testData/diagnostics/tests/enum/classObjectInEnumPrivate.kt new file mode 100644 index 00000000000..75e83840075 --- /dev/null +++ b/compiler/testData/diagnostics/tests/enum/classObjectInEnumPrivate.kt @@ -0,0 +1,10 @@ +enum class E { + ENTRY + + private class object +} + +fun foo() = E.values() +fun bar() = E.valueOf("ENTRY") +fun baz() = E.ENTRY +fun quux() = E diff --git a/compiler/testData/diagnostics/tests/enum/classObjectOfPrivateEnum.kt b/compiler/testData/diagnostics/tests/enum/classObjectOfPrivateEnum.kt deleted file mode 100644 index 959b09adc52..00000000000 --- a/compiler/testData/diagnostics/tests/enum/classObjectOfPrivateEnum.kt +++ /dev/null @@ -1,9 +0,0 @@ -// FILE: 1.kt -package a - -private enum class E { ENTRY } - -// FILE: 2.kt -package b - -val e = a.E diff --git a/compiler/testData/diagnostics/tests/enum/starImportNestedClassAndEntries.kt b/compiler/testData/diagnostics/tests/enum/starImportNestedClassAndEntries.kt index 872997884e5..55850414848 100644 --- a/compiler/testData/diagnostics/tests/enum/starImportNestedClassAndEntries.kt +++ b/compiler/testData/diagnostics/tests/enum/starImportNestedClassAndEntries.kt @@ -21,4 +21,4 @@ fun f1() = ENTRY fun f2() = ANOTHER fun f3() = Nested() fun f4() = Nested.foo() -fun f5() = values() \ No newline at end of file +fun f5() = values() diff --git a/compiler/testData/diagnostics/tests/redeclarations/EnumEntriesAndClassObjectMembers.kt b/compiler/testData/diagnostics/tests/redeclarations/EnumEntriesAndClassObjectMembers.kt new file mode 100644 index 00000000000..e8eb3711c21 --- /dev/null +++ b/compiler/testData/diagnostics/tests/redeclarations/EnumEntriesAndClassObjectMembers.kt @@ -0,0 +1,11 @@ +enum class E { + FIRST + + SECOND + + class object { + class FIRST + + val SECOND = this + } +} diff --git a/compiler/testData/loadJava/compiledJava/EnumMembers.txt b/compiler/testData/loadJava/compiledJava/EnumMembers.txt index 55facbfd1fa..31317f1f953 100644 --- a/compiler/testData/loadJava/compiledJava/EnumMembers.txt +++ b/compiler/testData/loadJava/compiledJava/EnumMembers.txt @@ -7,12 +7,6 @@ public final enum class EnumMembers : kotlin.Enum { public final override /*1*/ /*fake_override*/ fun name(): kotlin.String public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int - public class object { - private constructor () - public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): test.EnumMembers - public final /*synthesized*/ fun values(): kotlin.Array - } - public enum entry FIRST : test.EnumMembers { private constructor FIRST() public final override /*1*/ /*fake_override*/ val isFirst: kotlin.Boolean @@ -44,4 +38,8 @@ public final enum class EnumMembers : kotlin.Enum { public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int } } + + // Static members + public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): test.EnumMembers + public final /*synthesized*/ fun values(): kotlin.Array } diff --git a/compiler/testData/loadJava/compiledJava/JavaEnum.txt b/compiler/testData/loadJava/compiledJava/JavaEnum.txt index 672422d6ba1..1a4a2f1d022 100644 --- a/compiler/testData/loadJava/compiledJava/JavaEnum.txt +++ b/compiler/testData/loadJava/compiledJava/JavaEnum.txt @@ -5,12 +5,6 @@ public final enum class JavaEnum : kotlin.Enum { public final override /*1*/ /*fake_override*/ fun name(): kotlin.String public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int - public class object { - private constructor () - public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): test.JavaEnum - public final /*synthesized*/ fun values(): kotlin.Array - } - public enum entry ANOTHER : test.JavaEnum { private constructor ANOTHER() public final override /*1*/ /*fake_override*/ fun name(): kotlin.String @@ -34,4 +28,8 @@ public final enum class JavaEnum : kotlin.Enum { public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int } } + + // Static members + public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): test.JavaEnum + public final /*synthesized*/ fun values(): kotlin.Array } diff --git a/compiler/testData/loadJava/compiledJava/annotations/CustomAnnotation.txt b/compiler/testData/loadJava/compiledJava/annotations/CustomAnnotation.txt index 515dde7b6e9..5bb5dc11086 100644 --- a/compiler/testData/loadJava/compiledJava/annotations/CustomAnnotation.txt +++ b/compiler/testData/loadJava/compiledJava/annotations/CustomAnnotation.txt @@ -12,12 +12,6 @@ public trait CustomAnnotation { public final override /*1*/ /*fake_override*/ fun name(): kotlin.String public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int - public class object { - private constructor () - public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): test.CustomAnnotation.MyEnum - public final /*synthesized*/ fun values(): kotlin.Array - } - public enum entry ONE : test.CustomAnnotation.MyEnum { private constructor ONE() public final override /*1*/ /*fake_override*/ fun name(): kotlin.String @@ -29,6 +23,10 @@ public trait CustomAnnotation { public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int } } + + // Static members + public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): test.CustomAnnotation.MyEnum + public final /*synthesized*/ fun values(): kotlin.Array } test.CustomAnnotation.MyAnnotation(value = MyEnum.ONE: test.CustomAnnotation.MyEnum) public open class MyTest { diff --git a/compiler/testData/loadJava/compiledJava/static/Enum.txt b/compiler/testData/loadJava/compiledJava/static/Enum.txt index 819dbc1fcd0..c69dadaf040 100644 --- a/compiler/testData/loadJava/compiledJava/static/Enum.txt +++ b/compiler/testData/loadJava/compiledJava/static/Enum.txt @@ -5,12 +5,6 @@ public final enum class Enum : kotlin.Enum { public final override /*1*/ /*fake_override*/ fun name(): kotlin.String public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int - public class object { - private constructor () - public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): test.Enum - public final /*synthesized*/ fun values(): kotlin.Array - } - public enum entry A : test.Enum { private constructor A() public final override /*1*/ /*fake_override*/ fun name(): kotlin.String @@ -58,4 +52,8 @@ public final enum class Enum : kotlin.Enum { public/*package*/ open fun foo(): kotlin.Unit public/*package*/ open fun values(): kotlin.Unit } + + // Static members + public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): test.Enum + public final /*synthesized*/ fun values(): kotlin.Array } diff --git a/compiler/testData/loadJava/compiledJava/static/StaticMembersInEnum.txt b/compiler/testData/loadJava/compiledJava/static/StaticMembersInEnum.txt index 09aa288ca05..7a760dd1c01 100644 --- a/compiler/testData/loadJava/compiledJava/static/StaticMembersInEnum.txt +++ b/compiler/testData/loadJava/compiledJava/static/StaticMembersInEnum.txt @@ -5,12 +5,6 @@ public final enum class StaticMembersInEnum : kotlin.Enum { - private constructor () - public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): test.StaticMembersInEnum - public final /*synthesized*/ fun values(): kotlin.Array - } - public enum entry ENTRY : test.StaticMembersInEnum { private constructor ENTRY() public final override /*1*/ /*fake_override*/ fun name(): kotlin.String @@ -28,5 +22,7 @@ public final enum class StaticMembersInEnum : kotlin.Enum public open fun values(/*0*/ p0: kotlin.Int): kotlin.Unit } diff --git a/compiler/testData/loadJava/compiledKotlin/annotations/parameters/EnumConstructor.txt b/compiler/testData/loadJava/compiledKotlin/annotations/parameters/EnumConstructor.txt index 44b814e785f..ae31fcae23b 100644 --- a/compiler/testData/loadJava/compiledKotlin/annotations/parameters/EnumConstructor.txt +++ b/compiler/testData/loadJava/compiledKotlin/annotations/parameters/EnumConstructor.txt @@ -17,9 +17,7 @@ internal final enum class E : kotlin.Enum { public final override /*1*/ /*fake_override*/ fun name(): kotlin.String public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int - public class object { - /*primary*/ private constructor () - public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): test.E - public final /*synthesized*/ fun values(): kotlin.Array - } + // Static members + public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): test.E + public final /*synthesized*/ fun values(): kotlin.Array } diff --git a/compiler/testData/loadJava/compiledKotlin/class/EnumWithGenericConstructorParameter.txt b/compiler/testData/loadJava/compiledKotlin/class/EnumWithGenericConstructorParameter.txt index ad5d12656a9..3d59071c967 100644 --- a/compiler/testData/loadJava/compiledKotlin/class/EnumWithGenericConstructorParameter.txt +++ b/compiler/testData/loadJava/compiledKotlin/class/EnumWithGenericConstructorParameter.txt @@ -5,9 +5,7 @@ internal final enum class EnumWithGenericConstructorParameter : kotlin.Enum { - /*primary*/ private constructor () - public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): test.EnumWithGenericConstructorParameter - public final /*synthesized*/ fun values(): kotlin.Array - } + // Static members + public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): test.EnumWithGenericConstructorParameter + public final /*synthesized*/ fun values(): kotlin.Array } diff --git a/compiler/testData/loadJava/compiledKotlin/class/EnumWithPrimitiveConstructorParameter.txt b/compiler/testData/loadJava/compiledKotlin/class/EnumWithPrimitiveConstructorParameter.txt index 6e6523b8cce..99964cbcda3 100644 --- a/compiler/testData/loadJava/compiledKotlin/class/EnumWithPrimitiveConstructorParameter.txt +++ b/compiler/testData/loadJava/compiledKotlin/class/EnumWithPrimitiveConstructorParameter.txt @@ -5,9 +5,7 @@ internal final enum class EnumWithPrimitiveConstructorParameter : kotlin.Enum { - /*primary*/ private constructor () - public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): test.EnumWithPrimitiveConstructorParameter - public final /*synthesized*/ fun values(): kotlin.Array - } + // Static members + public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): test.EnumWithPrimitiveConstructorParameter + public final /*synthesized*/ fun values(): kotlin.Array } diff --git a/compiler/testData/loadJava/compiledKotlin/enum/enumVisibility.txt b/compiler/testData/loadJava/compiledKotlin/enum/enumVisibility.txt index 05aebaf7239..a3fb69ffdae 100644 --- a/compiler/testData/loadJava/compiledKotlin/enum/enumVisibility.txt +++ b/compiler/testData/loadJava/compiledKotlin/enum/enumVisibility.txt @@ -5,12 +5,6 @@ internal final enum class In : kotlin.Enum { public final override /*1*/ /*fake_override*/ fun name(): kotlin.String public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int - public class object { - /*primary*/ private constructor () - public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): test.In - public final /*synthesized*/ fun values(): kotlin.Array - } - public enum entry A : test.In { /*primary*/ private constructor A() public final override /*1*/ /*fake_override*/ fun name(): kotlin.String @@ -22,6 +16,10 @@ internal final enum class In : kotlin.Enum { public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int } } + + // Static members + public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): test.In + public final /*synthesized*/ fun values(): kotlin.Array } private final enum class Pr : kotlin.Enum { @@ -29,12 +27,6 @@ private final enum class Pr : kotlin.Enum { public final override /*1*/ /*fake_override*/ fun name(): kotlin.String public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int - public class object { - /*primary*/ private constructor () - public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): test.Pr - public final /*synthesized*/ fun values(): kotlin.Array - } - public enum entry A : test.Pr { /*primary*/ private constructor A() public final override /*1*/ /*fake_override*/ fun name(): kotlin.String @@ -46,6 +38,10 @@ private final enum class Pr : kotlin.Enum { public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int } } + + // Static members + public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): test.Pr + public final /*synthesized*/ fun values(): kotlin.Array } public final enum class Pu : kotlin.Enum { @@ -53,12 +49,6 @@ public final enum class Pu : kotlin.Enum { public final override /*1*/ /*fake_override*/ fun name(): kotlin.String public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int - public class object { - /*primary*/ private constructor () - public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): test.Pu - public final /*synthesized*/ fun values(): kotlin.Array - } - public enum entry A : test.Pu { /*primary*/ private constructor A() public final override /*1*/ /*fake_override*/ fun name(): kotlin.String @@ -70,4 +60,8 @@ public final enum class Pu : kotlin.Enum { public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int } } + + // Static members + public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): test.Pu + public final /*synthesized*/ fun values(): kotlin.Array } diff --git a/compiler/testData/loadJava/compiledKotlin/enum/enumWithConstuctor.txt b/compiler/testData/loadJava/compiledKotlin/enum/enumWithConstuctor.txt index 4b981726126..d081aacb327 100644 --- a/compiler/testData/loadJava/compiledKotlin/enum/enumWithConstuctor.txt +++ b/compiler/testData/loadJava/compiledKotlin/enum/enumWithConstuctor.txt @@ -9,12 +9,6 @@ internal final enum class En : kotlin.Enum { public final override /*1*/ /*fake_override*/ fun name(): kotlin.String public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int - public class object { - /*primary*/ private constructor () - public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): test.En - public final /*synthesized*/ fun values(): kotlin.Array - } - public enum entry E1 : test.En { /*primary*/ private constructor E1() internal final override /*1*/ /*fake_override*/ val b: kotlin.Boolean @@ -74,4 +68,8 @@ internal final enum class En : kotlin.Enum { public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int } } + + // Static members + public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): test.En + public final /*synthesized*/ fun values(): kotlin.Array } diff --git a/compiler/testData/loadJava/compiledKotlin/enum/innerEnum.txt b/compiler/testData/loadJava/compiledKotlin/enum/innerEnum.txt index 09669954b77..dab01f547e1 100644 --- a/compiler/testData/loadJava/compiledKotlin/enum/innerEnum.txt +++ b/compiler/testData/loadJava/compiledKotlin/enum/innerEnum.txt @@ -8,12 +8,6 @@ internal final class A { public final override /*1*/ /*fake_override*/ fun name(): kotlin.String public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int - public class object { - /*primary*/ private constructor () - public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): test.A.E - public final /*synthesized*/ fun values(): kotlin.Array - } - public enum entry ENTRY : test.A.E { /*primary*/ private constructor ENTRY() public final override /*1*/ /*fake_override*/ fun name(): kotlin.String @@ -25,5 +19,9 @@ internal final class A { public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int } } + + // Static members + public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): test.A.E + public final /*synthesized*/ fun values(): kotlin.Array } } diff --git a/compiler/testData/loadJava/compiledKotlin/enum/innerEnumExistingClassObject.txt b/compiler/testData/loadJava/compiledKotlin/enum/innerEnumExistingClassObject.txt index e4437ea18d3..269db1646fc 100644 --- a/compiler/testData/loadJava/compiledKotlin/enum/innerEnumExistingClassObject.txt +++ b/compiler/testData/loadJava/compiledKotlin/enum/innerEnumExistingClassObject.txt @@ -12,12 +12,6 @@ internal final class A { public final override /*1*/ /*fake_override*/ fun name(): kotlin.String public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int - public class object { - /*primary*/ private constructor () - public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): test.A.E - public final /*synthesized*/ fun values(): kotlin.Array - } - public enum entry ENTRY : test.A.E { /*primary*/ private constructor ENTRY() public final override /*1*/ /*fake_override*/ fun name(): kotlin.String @@ -29,5 +23,9 @@ internal final class A { public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int } } + + // Static members + public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): test.A.E + public final /*synthesized*/ fun values(): kotlin.Array } } diff --git a/compiler/testData/loadJava/compiledKotlin/enum/simpleEnum.txt b/compiler/testData/loadJava/compiledKotlin/enum/simpleEnum.txt index c18c24ef4d7..eda2c954c36 100644 --- a/compiler/testData/loadJava/compiledKotlin/enum/simpleEnum.txt +++ b/compiler/testData/loadJava/compiledKotlin/enum/simpleEnum.txt @@ -5,12 +5,6 @@ internal final enum class MyEnum : kotlin.Enum { public final override /*1*/ /*fake_override*/ fun name(): kotlin.String public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int - public class object { - /*primary*/ private constructor () - public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): test.MyEnum - public final /*synthesized*/ fun values(): kotlin.Array - } - public enum entry ENTRY : test.MyEnum { /*primary*/ private constructor ENTRY() public final override /*1*/ /*fake_override*/ fun name(): kotlin.String @@ -22,4 +16,8 @@ internal final enum class MyEnum : kotlin.Enum { public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int } } + + // Static members + public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): test.MyEnum + public final /*synthesized*/ fun values(): kotlin.Array } diff --git a/compiler/testData/loadJava/compiledKotlin/fromLoadJava/enum.txt b/compiler/testData/loadJava/compiledKotlin/fromLoadJava/enum.txt index 4141aa4f9fb..927065cd7a5 100644 --- a/compiler/testData/loadJava/compiledKotlin/fromLoadJava/enum.txt +++ b/compiler/testData/loadJava/compiledKotlin/fromLoadJava/enum.txt @@ -5,12 +5,6 @@ internal final enum class Test : kotlin.Enum { public final override /*1*/ /*fake_override*/ fun name(): kotlin.String public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int - public class object { - /*primary*/ private constructor () - public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): test.Test - public final /*synthesized*/ fun values(): kotlin.Array - } - public enum entry A : test.Test { /*primary*/ private constructor A() public final override /*1*/ /*fake_override*/ fun name(): kotlin.String @@ -34,4 +28,8 @@ internal final enum class Test : kotlin.Enum { public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int } } + + // Static members + public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): test.Test + public final /*synthesized*/ fun values(): kotlin.Array } diff --git a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java index e4f30a4f231..c0c09416ade 100644 --- a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java @@ -3178,7 +3178,7 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest { @TestMetadata("compiler/testData/diagnostics/tests/duplicateJvmSignature") @TestDataPath("$PROJECT_ROOT") - @InnerTestClasses({DuplicateJvmSignature.AccidentalOverrides.class, DuplicateJvmSignature.Bridges.class, DuplicateJvmSignature.Erasure.class, DuplicateJvmSignature.FunctionAndProperty.class, DuplicateJvmSignature.SpecialNames.class, DuplicateJvmSignature.TraitImpl.class}) + @InnerTestClasses({DuplicateJvmSignature.AccidentalOverrides.class, DuplicateJvmSignature.Bridges.class, DuplicateJvmSignature.Erasure.class, DuplicateJvmSignature.FunctionAndProperty.class, DuplicateJvmSignature.SpecialNames.class, DuplicateJvmSignature.Synthesized.class, DuplicateJvmSignature.TraitImpl.class}) @RunWith(org.jetbrains.jet.JUnit3RunnerWithInners.class) public static class DuplicateJvmSignature extends AbstractJetDiagnosticsTest { public void testAllFilesPresentInDuplicateJvmSignature() throws Exception { @@ -3625,6 +3625,19 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest { } + @TestMetadata("compiler/testData/diagnostics/tests/duplicateJvmSignature/synthesized") + public static class Synthesized extends AbstractJetDiagnosticsTest { + public void testAllFilesPresentInSynthesized() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/diagnostics/tests/duplicateJvmSignature/synthesized"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("enumValuesValueOf.kt") + public void testEnumValuesValueOf() throws Exception { + doTest("compiler/testData/diagnostics/tests/duplicateJvmSignature/synthesized/enumValuesValueOf.kt"); + } + + } + @TestMetadata("compiler/testData/diagnostics/tests/duplicateJvmSignature/traitImpl") @TestDataPath("$PROJECT_ROOT") @RunWith(org.jetbrains.jet.JUnit3RunnerWithInners.class) @@ -3669,13 +3682,24 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest { public void testAllFilesPresentInEnum() throws Exception { JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/diagnostics/tests/enum"), Pattern.compile("^(.+)\\.kt$"), true); } - @TestMetadata("classObjectOfPrivateEnum.kt") public void testClassObjectOfPrivateEnum() throws Exception { String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/enum/classObjectOfPrivateEnum.kt"); doTest(fileName); } + @TestMetadata("classObjectInEnum.kt") + public void testClassObjectInEnum() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/enum/classObjectInEnum.kt"); + doTest(fileName); + } + + @TestMetadata("classObjectInEnumPrivate.kt") + public void testClassObjectInEnumPrivate() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/enum/classObjectInEnumPrivate.kt"); + doTest(fileName); + } + @TestMetadata("dontCreatePackageTypeForEnumEntry.kt") public void testDontCreatePackageTypeForEnumEntry() throws Exception { String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/enum/dontCreatePackageTypeForEnumEntry.kt"); @@ -7615,6 +7639,11 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest { doTest(fileName); } + @TestMetadata("EnumEntriesAndClassObjectMembers.kt") + public void testEnumEntriesAndClassObjectMembers() throws Exception { + doTest("compiler/testData/diagnostics/tests/redeclarations/EnumEntriesAndClassObjectMembers.kt"); + } + @TestMetadata("kt2247.kt") public void testKt2247() throws Exception { String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/redeclarations/kt2247.kt"); diff --git a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java index a4c72ff1738..ba760ce0562 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java @@ -2512,6 +2512,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { doTest(fileName); } + @TestMetadata("classObjectInEnum.kt") + public void testClassObjectInEnum() throws Exception { + doTest("compiler/testData/codegen/box/enum/classObjectInEnum.kt"); + } + @TestMetadata("emptyEnumValuesValueOf.kt") public void testEmptyEnumValuesValueOf() throws Exception { String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/box/enum/emptyEnumValuesValueOf.kt"); diff --git a/compiler/tests/org/jetbrains/jet/jvm/compiler/CompileKotlinAgainstKotlinTestGenerated.java b/compiler/tests/org/jetbrains/jet/jvm/compiler/CompileKotlinAgainstKotlinTestGenerated.java index d43e61cec89..caf1921412e 100644 --- a/compiler/tests/org/jetbrains/jet/jvm/compiler/CompileKotlinAgainstKotlinTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/jvm/compiler/CompileKotlinAgainstKotlinTestGenerated.java @@ -44,6 +44,11 @@ public class CompileKotlinAgainstKotlinTestGenerated extends AbstractCompileKotl doTest(fileName); } + @TestMetadata("ClassObjectInEnum.A.kt") + public void testClassObjectInEnum() throws Exception { + doTest("compiler/testData/compileKotlinAgainstKotlin/ClassObjectInEnum.A.kt"); + } + @TestMetadata("ClassObjectMember.A.kt") public void testClassObjectMember() throws Exception { String fileName = JetTestUtils.navigationMetadata("compiler/testData/compileKotlinAgainstKotlin/ClassObjectMember.A.kt"); diff --git a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/descriptors/LazyJavaClassDescriptor.kt b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/descriptors/LazyJavaClassDescriptor.kt index b960a02de7c..fb1d52c479c 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/descriptors/LazyJavaClassDescriptor.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/descriptors/LazyJavaClassDescriptor.kt @@ -39,7 +39,6 @@ import org.jetbrains.jet.lang.descriptors.annotations.Annotations import java.util.ArrayList import org.jetbrains.jet.lang.types.checker.JetTypeChecker import org.jetbrains.jet.lang.types.AbstractClassTypeConstructor -import org.jetbrains.jet.lang.descriptors.impl.EnumClassObjectDescriptor class LazyJavaClassDescriptor( private val outerC: LazyJavaResolverContextWithTypes, @@ -88,14 +87,7 @@ class LazyJavaClassDescriptor( override fun getUnsubstitutedPrimaryConstructor(): ConstructorDescriptor? = null - private val _classObjectDescriptor = c.storageManager.createNullableLazyValue { - if (jClass.isEnum()) { - EnumClassObjectDescriptor(c.storageManager, this) - } - else null - } - - override fun getClassObjectDescriptor(): ClassDescriptor? = _classObjectDescriptor() + override fun getClassObjectDescriptor(): ClassDescriptor? = null override fun getClassObjectType(): JetType? = getClassObjectDescriptor()?.let { d -> d.getDefaultType() } override fun getConstructors() = _scopeForMemberLookup._constructors() diff --git a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/descriptors/LazyJavaClassMemberScope.kt b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/descriptors/LazyJavaClassMemberScope.kt index 30705b74323..1c8e921ec78 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/descriptors/LazyJavaClassMemberScope.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/descriptors/LazyJavaClassMemberScope.kt @@ -87,6 +87,8 @@ public class LazyJavaClassMemberScope( c.errorReporter)) } + override fun computeAdditionalFunctions(name: Name) = listOf() + private fun getPropertiesFromSupertypes(name: Name, descriptor: ClassDescriptor): Set { return descriptor.getTypeConstructor().getSupertypes().flatMap { it.getMemberScope().getProperties(name).map { p -> p as PropertyDescriptor } diff --git a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/descriptors/LazyJavaMemberScope.kt b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/descriptors/LazyJavaMemberScope.kt index 8eef948db5b..33800875168 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/descriptors/LazyJavaMemberScope.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/descriptors/LazyJavaMemberScope.kt @@ -38,7 +38,6 @@ import org.jetbrains.jet.lang.resolve.java.lazy.hasMutableAnnotation import org.jetbrains.jet.lang.resolve.java.lazy.hasReadOnlyAnnotation import org.jetbrains.jet.lang.resolve.java.structure.JavaValueParameter import java.util.ArrayList -import org.jetbrains.jet.lang.resolve.java.resolver.DescriptorResolverUtils import java.util.LinkedHashSet import org.jetbrains.jet.lang.types.JetType import org.jetbrains.jet.lang.resolve.java.descriptor.JavaPropertyDescriptor @@ -72,23 +71,25 @@ public abstract class LazyJavaMemberScope( protected abstract fun getExpectedThisObject(): ReceiverParameterDescriptor? + protected abstract fun computeAdditionalFunctions(name: Name): Collection + private val _functions = c.storageManager.createMemoizedFunction { - (name: Name): Collection - -> + (name: Name): Collection -> val methods = memberIndex().findMethodsByName(name) val functions = LinkedHashSet( methods.stream() - // values() and valueOf() are added manually, see LazyJavaClassDescriptor::getClassObjectDescriptor() - .filter{ m -> !DescriptorResolverUtils.shouldBeInEnumClassObject(m) } - .flatMap { - m -> - val function = resolveMethodToFunctionDescriptor(m, true) - val samAdapter = resolveSamAdapter(function) - if (samAdapter != null) - listOf(function, samAdapter).stream() - else - listOf(function).stream() - }.toList()) + .flatMap { + m -> + val function = resolveMethodToFunctionDescriptor(m, true) + val samAdapter = resolveSamAdapter(function) + if (samAdapter != null) + listOf(function, samAdapter).stream() + else + listOf(function).stream() + } + .plus(computeAdditionalFunctions(name)) + .toList() + ) computeNonDeclaredFunctions(functions, name) diff --git a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/descriptors/LazyJavaStaticScope.kt b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/descriptors/LazyJavaStaticScope.kt index 279465d0c56..645be388ce0 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/descriptors/LazyJavaStaticScope.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/descriptors/LazyJavaStaticScope.kt @@ -36,6 +36,7 @@ import org.jetbrains.jet.lang.resolve.java.lazy.descriptors.LazyJavaMemberScope. import org.jetbrains.jet.lang.resolve.java.descriptor.SamConstructorDescriptor import org.jetbrains.jet.lang.resolve.name.SpecialNames import org.jetbrains.jet.lang.resolve.kotlin.KotlinJvmBinaryClass +import org.jetbrains.jet.lang.resolve.DescriptorFactory.* public abstract class LazyJavaStaticScope( c: LazyJavaResolverContext, @@ -131,6 +132,8 @@ public class LazyPackageFragmentScopeForJavaPackage( override fun computeMemberIndex(): MemberIndex = computeMemberIndexForSamConstructors(EMPTY_MEMBER_INDEX) + override fun computeAdditionalFunctions(name: Name) = listOf() + override fun getAllClassNames(): Collection { return jPackage.getClasses().stream() .filter { c -> c.getOriginKind() != JavaClass.OriginKind.KOTLIN_LIGHT_CLASS } @@ -165,6 +168,21 @@ public class LazyJavaStaticClassScope( override fun computeMemberIndex(): MemberIndex = computeMemberIndexForSamConstructors(ClassMemberIndex(jClass, { m -> m.isStatic() })) + override fun getAllFunctionNames(): Collection { + if (jClass.isEnum()) { + return super.getAllFunctionNames() + listOf(Name.identifier("valueOf"), Name.identifier("values")) + } + return super.getAllFunctionNames() + } + + override fun computeAdditionalFunctions(name: Name): Collection { + if (jClass.isEnum()) { + if (name.asString() == "valueOf") return listOf(createEnumValueOfMethod(getContainingDeclaration())) + if (name.asString() == "values") return listOf(createEnumValuesMethod(getContainingDeclaration())) + } + return listOf() + } + override fun getAllClassNames(): Collection = listOf() override fun getClassifier(name: Name): ClassifierDescriptor? = null diff --git a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/resolver/DescriptorResolverUtils.java b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/resolver/DescriptorResolverUtils.java index 3962109bcb2..401a755c706 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/resolver/DescriptorResolverUtils.java +++ b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/resolver/DescriptorResolverUtils.java @@ -87,23 +87,6 @@ public final class DescriptorResolverUtils { return null; } - /** - * @return true if {@code method} is a static method of enum class, which is to be put into its class object (and not into the - * corresponding package). This applies to values() and valueOf(String) methods - */ - public static boolean shouldBeInEnumClassObject(@NotNull JavaMethod method) { - if (!method.getContainingClass().isEnum()) return false; - - String name = method.getName().asString(); - if (name.equals("values")) { - return method.getValueParameters().isEmpty(); - } - else if (name.equals("valueOf")) { - return isMethodWithOneParameterWithFqName(method, "java.lang.String"); - } - return false; - } - public static boolean isObjectMethodInInterface(@NotNull JavaMember member) { return member.getContainingClass().isInterface() && member instanceof JavaMethod && isObjectMethod((JavaMethod) member); } diff --git a/core/descriptors/src/org/jetbrains/jet/lang/descriptors/impl/EnumClassObjectDescriptor.kt b/core/descriptors/src/org/jetbrains/jet/lang/descriptors/impl/EnumClassObjectDescriptor.kt deleted file mode 100644 index c93e1eb02da..00000000000 --- a/core/descriptors/src/org/jetbrains/jet/lang/descriptors/impl/EnumClassObjectDescriptor.kt +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright 2010-2014 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.jetbrains.jet.lang.descriptors.impl - -import org.jetbrains.jet.storage.StorageManager -import org.jetbrains.jet.lang.descriptors.* -import org.jetbrains.jet.lang.descriptors.CallableMemberDescriptor.Kind.SYNTHESIZED -import org.jetbrains.jet.lang.descriptors.annotations.Annotations -import org.jetbrains.jet.lang.resolve.name.SpecialNames -import org.jetbrains.jet.lang.resolve.scopes.JetScope -import org.jetbrains.jet.lang.resolve.DescriptorUtils -import org.jetbrains.jet.lang.resolve.DescriptorFactory -import org.jetbrains.jet.lang.types.TypeConstructor -import org.jetbrains.jet.lang.types.TypeConstructorImpl -import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns -import org.jetbrains.jet.lang.resolve.OverridingUtil -import org.jetbrains.jet.lang.types.DelegatingType -import org.jetbrains.jet.lang.types.JetType -import org.jetbrains.jet.lang.resolve.name.Name -import org.jetbrains.jet.lang.resolve.scopes.JetScopeImpl -import org.jetbrains.jet.utils.Printer -import java.util.ArrayList -import kotlin.properties.Delegates -import org.jetbrains.jet.lang.resolve.scopes.StaticScopeForKotlinClass - -public class EnumClassObjectDescriptor( - storageManager: StorageManager, - enumClass: ClassDescriptor -) : ClassDescriptorBase(storageManager, enumClass, SpecialNames.getClassObjectName(enumClass.getName()), SourceElement.NO_SOURCE) { - private val primaryConstructor = DescriptorFactory.createPrimaryConstructorForObject(this, SourceElement.NO_SOURCE) - - ;{ - primaryConstructor.setReturnType(object : DelegatingType() { - override fun getDelegate() = getDefaultType() - }) - } - - private val _typeConstructor = TypeConstructorImpl.createForClass(this, getAnnotations(), true, getName().asString(), - listOf(), listOf(KotlinBuiltIns.getInstance().getAnyType())) - - private val scope = EnumClassObjectScope() - private val staticScope = StaticScopeForKotlinClass(this) - - override fun getScopeForMemberLookup(): JetScope = scope - - override fun getStaticScope(): JetScope = staticScope - - override fun getClassObjectDescriptor(): ClassDescriptor? = null - - override fun getConstructors(): List = listOf(primaryConstructor) - - override fun getUnsubstitutedPrimaryConstructor(): ConstructorDescriptor = primaryConstructor - - override fun getTypeConstructor(): TypeConstructor = _typeConstructor - - override fun getKind(): ClassKind = ClassKind.CLASS_OBJECT - - override fun getModality(): Modality = Modality.FINAL - - override fun getVisibility(): Visibility = DescriptorUtils.getSyntheticClassObjectVisibility() - - override fun isInner(): Boolean = false - - override fun getAnnotations(): Annotations = Annotations.EMPTY - - private inner class EnumClassObjectScope : JetScopeImpl() { - private val enumClassObject: EnumClassObjectDescriptor - get() = this@EnumClassObjectDescriptor - - private val functions: List by Delegates.lazy { - val result = ArrayList(5) - - val enumType = object : DelegatingType() { - override fun getDelegate() = (enumClassObject.getContainingDeclaration() as ClassDescriptor).getDefaultType() - } - - result.add(createEnumClassObjectValuesMethod(enumType)) - result.add(createEnumClassObjectValueOfMethod(enumType)) - - val sink = object : OverridingUtil.DescriptorSink { - override fun addToScope(fakeOverride: CallableMemberDescriptor) { - OverridingUtil.resolveUnknownVisibilityForMember(fakeOverride, null) - result.add(fakeOverride as FunctionDescriptor) - } - - override fun conflict(fromSuper: CallableMemberDescriptor, fromCurrent: CallableMemberDescriptor) { - throw IllegalStateException("Conflict on enum class object override: $fromSuper vs $fromCurrent") - } - } - - val superScope = KotlinBuiltIns.getInstance().getAnyType().getMemberScope() - - for (descriptor in superScope.getAllDescriptors()) { - if (descriptor is FunctionDescriptor) { - val name = descriptor.getName() - OverridingUtil.generateOverridesInFunctionGroup(name, superScope.getFunctions(name), setOf(), enumClassObject, sink) - } - } - - result - } - - private fun createEnumClassObjectValuesMethod(enumType: JetType): SimpleFunctionDescriptor { - val enumArrayType = KotlinBuiltIns.getInstance().getArrayType(enumType) - val values = SimpleFunctionDescriptorImpl.create(enumClassObject, Annotations.EMPTY, Name.identifier("values"), SYNTHESIZED, SourceElement.NO_SOURCE) - return values.initialize(null, getThisAsReceiverParameter(), listOf(), listOf(), enumArrayType, Modality.FINAL, Visibilities.PUBLIC) - } - - private fun createEnumClassObjectValueOfMethod(enumType: JetType): SimpleFunctionDescriptor { - val values = SimpleFunctionDescriptorImpl.create(enumClassObject, Annotations.EMPTY, Name.identifier("valueOf"), SYNTHESIZED, SourceElement.NO_SOURCE) - val parameter = ValueParameterDescriptorImpl(values, null, 0, Annotations.EMPTY, Name.identifier("value"), - KotlinBuiltIns.getInstance().getStringType(), false, null, SourceElement.NO_SOURCE) - return values.initialize(null, getThisAsReceiverParameter(), listOf(), listOf(parameter), enumType, Modality.FINAL, Visibilities.PUBLIC) - } - - override fun getFunctions(name: Name) = functions.filter { it.getName() == name } - - override fun getAllDescriptors() = functions - - override fun printScopeStructure(p: Printer) { - p.println("enum class object scope for $enumClassObject") - } - - override fun getContainingDeclaration(): ClassDescriptor = enumClassObject - } -} diff --git a/core/descriptors/src/org/jetbrains/jet/lang/resolve/DescriptorFactory.java b/core/descriptors/src/org/jetbrains/jet/lang/resolve/DescriptorFactory.java index f835d1fc39f..489a376c120 100644 --- a/core/descriptors/src/org/jetbrains/jet/lang/resolve/DescriptorFactory.java +++ b/core/descriptors/src/org/jetbrains/jet/lang/resolve/DescriptorFactory.java @@ -20,12 +20,11 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.annotations.Annotations; -import org.jetbrains.jet.lang.descriptors.impl.ConstructorDescriptorImpl; -import org.jetbrains.jet.lang.descriptors.impl.PropertyGetterDescriptorImpl; -import org.jetbrains.jet.lang.descriptors.impl.PropertySetterDescriptorImpl; -import org.jetbrains.jet.lang.descriptors.impl.ReceiverParameterDescriptorImpl; +import org.jetbrains.jet.lang.descriptors.impl.*; +import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.lang.resolve.scopes.receivers.ExtensionReceiver; import org.jetbrains.jet.lang.types.JetType; +import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; import java.util.Collections; @@ -83,6 +82,31 @@ public class DescriptorFactory { return constructor instanceof DefaultConstructorDescriptor; } + @NotNull + public static SimpleFunctionDescriptor createEnumValuesMethod(@NotNull ClassDescriptor enumClass) { + SimpleFunctionDescriptorImpl values = + SimpleFunctionDescriptorImpl.create(enumClass, Annotations.EMPTY, Name.identifier("values"), + CallableMemberDescriptor.Kind.SYNTHESIZED, SourceElement.NO_SOURCE); + return values.initialize(null, NO_RECEIVER_PARAMETER, Collections.emptyList(), + Collections.emptyList(), + KotlinBuiltIns.getInstance().getArrayType(enumClass.getDefaultType()), Modality.FINAL, + Visibilities.PUBLIC); + } + + @NotNull + public static SimpleFunctionDescriptor createEnumValueOfMethod(@NotNull ClassDescriptor enumClass) { + SimpleFunctionDescriptorImpl valueOf = + SimpleFunctionDescriptorImpl.create(enumClass, Annotations.EMPTY, Name.identifier("valueOf"), + CallableMemberDescriptor.Kind.SYNTHESIZED, SourceElement.NO_SOURCE); + ValueParameterDescriptor parameterDescriptor = new ValueParameterDescriptorImpl( + valueOf, null, 0, Annotations.EMPTY, Name.identifier("value"), KotlinBuiltIns.getInstance().getStringType(), false, null, + SourceElement.NO_SOURCE + ); + return valueOf.initialize(null, NO_RECEIVER_PARAMETER, Collections.emptyList(), + Collections.singletonList(parameterDescriptor), enumClass.getDefaultType(), Modality.FINAL, + Visibilities.PUBLIC); + } + @Nullable public static ReceiverParameterDescriptor createReceiverParameterForCallable( @NotNull CallableDescriptor owner, diff --git a/core/descriptors/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java b/core/descriptors/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java index 1e06e1fe9fd..e0603d03aff 100644 --- a/core/descriptors/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java +++ b/core/descriptors/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java @@ -299,13 +299,7 @@ public class DescriptorUtils { } public static boolean isSyntheticClassObject(@NotNull DeclarationDescriptor descriptor) { - if (isClassObject(descriptor)) { - DeclarationDescriptor containing = descriptor.getContainingDeclaration(); - if (containing != null) { - return isEnumClass(containing) || isObject(containing) || isEnumEntry(containing); - } - } - return false; + return isClassObject(descriptor) && isSingleton(descriptor.getContainingDeclaration()); } @NotNull diff --git a/core/descriptors/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.kt b/core/descriptors/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.kt index f9e3f28a8f7..549e7197510 100644 --- a/core/descriptors/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.kt +++ b/core/descriptors/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.kt @@ -16,21 +16,16 @@ package org.jetbrains.jet.lang.resolve.descriptorUtil -import org.jetbrains.jet.lang.descriptors.ClassDescriptor -import org.jetbrains.jet.lang.descriptors.ClassKind.ENUM_ENTRY -import org.jetbrains.jet.lang.descriptors.ClassKind.ENUM_CLASS -import org.jetbrains.jet.lang.descriptors.ClassKind.OBJECT -import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor -import org.jetbrains.jet.lang.descriptors.ConstructorDescriptor +import org.jetbrains.jet.lang.descriptors.* import org.jetbrains.jet.lang.resolve.DescriptorUtils - +import org.jetbrains.jet.lang.descriptors.ClassKind.* public fun ClassDescriptor.getClassObjectReferenceTarget(): ClassDescriptor { val classObjectDescriptor = getClassObjectDescriptor() return if (classObjectDescriptor == null || hasSyntheticClassObject()) this else classObjectDescriptor } -public fun ClassDescriptor.hasSyntheticClassObject(): Boolean = getKind() in setOf(ENUM_ENTRY, ENUM_CLASS, OBJECT) +public fun ClassDescriptor.hasSyntheticClassObject(): Boolean = getKind() in setOf(ENUM_ENTRY, OBJECT) public fun DeclarationDescriptor.getImportableDescriptor(): DeclarationDescriptor = if (this is ConstructorDescriptor || DescriptorUtils.isClassObject(this)) getContainingDeclaration()!! else this diff --git a/core/descriptors/src/org/jetbrains/jet/lang/resolve/scopes/StaticScopeForKotlinClass.kt b/core/descriptors/src/org/jetbrains/jet/lang/resolve/scopes/StaticScopeForKotlinClass.kt index fa815f80a37..97c10e659bd 100644 --- a/core/descriptors/src/org/jetbrains/jet/lang/resolve/scopes/StaticScopeForKotlinClass.kt +++ b/core/descriptors/src/org/jetbrains/jet/lang/resolve/scopes/StaticScopeForKotlinClass.kt @@ -19,20 +19,33 @@ package org.jetbrains.jet.lang.resolve.scopes import org.jetbrains.jet.lang.resolve.name.Name import org.jetbrains.jet.lang.descriptors.* import org.jetbrains.jet.utils.Printer +import java.util.ArrayList +import kotlin.properties.Delegates +import org.jetbrains.jet.lang.resolve.DescriptorFactory.* public class StaticScopeForKotlinClass( private val containingClass: ClassDescriptor ) : JetScope { override fun getClassifier(name: Name) = null // TODO - override fun getAllDescriptors() = listOf() // TODO + private val functions: List by Delegates.lazy { + if (containingClass.getKind() != ClassKind.ENUM_CLASS) { + listOf() + } + else { + listOf(createEnumValueOfMethod(containingClass), createEnumValuesMethod(containingClass)) + } + } - override fun getOwnDeclaredDescriptors() = listOf() // TODO + override fun getAllDescriptors() = functions + + override fun getOwnDeclaredDescriptors() = functions + + override fun getFunctions(name: Name) = functions.filterTo(ArrayList(2)) { it.getName() == name } override fun getPackage(name: Name) = null override fun getProperties(name: Name) = listOf() override fun getLocalVariable(name: Name) = null - override fun getFunctions(name: Name) = listOf() override fun getContainingDeclaration() = containingClass override fun getDeclarationsByLabel(labelName: Name) = listOf() override fun getImplicitReceiversHierarchy() = listOf() diff --git a/core/serialization/src/org/jetbrains/jet/descriptors/serialization/descriptors/DeserializedClassDescriptor.java b/core/serialization/src/org/jetbrains/jet/descriptors/serialization/descriptors/DeserializedClassDescriptor.java index 85d6b65fc6c..fdf6d3a63a7 100644 --- a/core/serialization/src/org/jetbrains/jet/descriptors/serialization/descriptors/DeserializedClassDescriptor.java +++ b/core/serialization/src/org/jetbrains/jet/descriptors/serialization/descriptors/DeserializedClassDescriptor.java @@ -30,7 +30,6 @@ import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.annotations.Annotations; import org.jetbrains.jet.lang.descriptors.impl.AbstractClassDescriptor; import org.jetbrains.jet.lang.descriptors.impl.ConstructorDescriptorImpl; -import org.jetbrains.jet.lang.descriptors.impl.EnumClassObjectDescriptor; import org.jetbrains.jet.lang.descriptors.impl.EnumEntrySyntheticClassDescriptor; import org.jetbrains.jet.lang.resolve.DescriptorFactory; import org.jetbrains.jet.lang.resolve.OverridingUtil; @@ -238,10 +237,6 @@ public class DeserializedClassDescriptor extends AbstractClassDescriptor impleme return null; } - if (getKind() == ClassKind.ENUM_CLASS) { - return new EnumClassObjectDescriptor(context.getStorageManager(), this); - } - if (getKind() == ClassKind.OBJECT) { ProtoBuf.Class.ClassObject classObjectProto = classProto.getClassObject(); if (!classObjectProto.hasData()) { diff --git a/idea/testData/checker/ClassObjectInEnum.kt b/idea/testData/checker/ClassObjectInEnum.kt new file mode 100644 index 00000000000..661e9a6c272 --- /dev/null +++ b/idea/testData/checker/ClassObjectInEnum.kt @@ -0,0 +1,11 @@ +enum class E { + ENTRY + + class object { + fun foo(): E = ENTRY + } +} + +fun foo() = E.ENTRY +fun bar() = E.values() +fun baz() = E.valueOf("ENTRY") diff --git a/idea/tests/org/jetbrains/jet/checkers/JetPsiCheckerTestGenerated.java b/idea/tests/org/jetbrains/jet/checkers/JetPsiCheckerTestGenerated.java index 7abc7aa6785..8e5e7ec15aa 100644 --- a/idea/tests/org/jetbrains/jet/checkers/JetPsiCheckerTestGenerated.java +++ b/idea/tests/org/jetbrains/jet/checkers/JetPsiCheckerTestGenerated.java @@ -95,6 +95,11 @@ public class JetPsiCheckerTestGenerated extends AbstractJetPsiCheckerTest { doTest(fileName); } + @TestMetadata("ClassObjectInEnum.kt") + public void testClassObjectInEnum() throws Exception { + doTest("idea/testData/checker/ClassObjectInEnum.kt"); + } + @TestMetadata("ClassObjects.kt") public void testClassObjects() throws Exception { String fileName = JetTestUtils.navigationMetadata("idea/testData/checker/ClassObjects.kt");