Drop enum class object hack

Place valueOf() and values() into the static scope of the corresponding enum
class

 #KT-5580 Fixed
 #KT-2410 Fixed
This commit is contained in:
Alexander Udalov
2014-09-05 13:39:33 +04:00
parent bb54825fac
commit b52f337f7f
43 changed files with 299 additions and 352 deletions
@@ -963,13 +963,11 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
}
@NotNull
private FunctionDescriptor findEnumFunction(@NotNull String name, Function1<FunctionDescriptor, Boolean> predicate) {
ClassDescriptor enumClassObject = descriptor.getClassObjectDescriptor();
assert enumClassObject != null : "No class object in " + descriptor;
Collection<FunctionDescriptor> 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<FunctionDescriptor, Boolean> predicate) {
Collection<FunctionDescriptor> 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;
@@ -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;
@@ -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);
+8 -12
View File
@@ -777,12 +777,6 @@ public final enum class InlineOption : kotlin.Enum<kotlin.InlineOption> {
public final override /*1*/ /*fake_override*/ fun name(): kotlin.String
public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int
public class object <class-object-for-InlineOption> {
/*primary*/ private constructor <class-object-for-InlineOption>()
public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): kotlin.InlineOption
public final /*synthesized*/ fun values(): kotlin.Array<kotlin.InlineOption>
}
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<kotlin.InlineOption> {
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<kotlin.InlineOption>
}
public final enum class InlineStrategy : kotlin.Enum<kotlin.InlineStrategy> {
@@ -813,12 +811,6 @@ public final enum class InlineStrategy : kotlin.Enum<kotlin.InlineStrategy> {
public final override /*1*/ /*fake_override*/ fun name(): kotlin.String
public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int
public class object <class-object-for-InlineStrategy> {
/*primary*/ private constructor <class-object-for-InlineStrategy>()
public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): kotlin.InlineStrategy
public final /*synthesized*/ fun values(): kotlin.Array<kotlin.InlineStrategy>
}
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<kotlin.InlineStrategy> {
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<kotlin.InlineStrategy>
}
public final class Int : kotlin.Number, kotlin.Comparable<kotlin.Int> {
@@ -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"
}
@@ -0,0 +1,9 @@
package library
public enum class EnumClass {
ENTRY
public class object {
public fun entry(): EnumClass = ENTRY
}
}
@@ -0,0 +1,5 @@
import library.EnumClass
fun main(args: Array<String>) {
if (EnumClass.entry() != EnumClass.ENTRY) throw AssertionError()
}
@@ -0,0 +1,12 @@
enum class <!CONFLICTING_JVM_DECLARATIONS, CONFLICTING_JVM_DECLARATIONS!>A<!> {
A1
A2
<!CONFLICTING_JVM_DECLARATIONS!>fun valueOf(s: String): A<!> = valueOf(s)
fun valueOf() = "OK"
<!CONFLICTING_JVM_DECLARATIONS!>fun values(): Array<A><!> = null!!
fun values(x: String) = x
}
@@ -0,0 +1,9 @@
enum class E {
ENTRY
class object {
fun entry() = ENTRY
}
}
fun bar() = E.entry()
@@ -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() = <!INVISIBLE_MEMBER!>E<!>
@@ -1,9 +0,0 @@
// FILE: 1.kt
package a
private enum class E { ENTRY }
// FILE: 2.kt
package b
val e = a.<!INVISIBLE_MEMBER!>E<!>
@@ -21,4 +21,4 @@ fun f1() = ENTRY
fun f2() = ANOTHER
fun f3() = Nested()
fun f4() = Nested.foo()
fun f5() = <!UNRESOLVED_REFERENCE!>values<!>()
fun f5() = values()
@@ -0,0 +1,11 @@
enum class E {
<!REDECLARATION!>FIRST<!>
<!REDECLARATION!>SECOND<!>
class object {
class <!REDECLARATION!>FIRST<!>
val <!REDECLARATION!>SECOND<!> = this
}
}
@@ -7,12 +7,6 @@ public final enum class EnumMembers : kotlin.Enum<test.EnumMembers> {
public final override /*1*/ /*fake_override*/ fun name(): kotlin.String
public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int
public class object <class-object-for-EnumMembers> {
private constructor <class-object-for-EnumMembers>()
public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): test.EnumMembers
public final /*synthesized*/ fun values(): kotlin.Array<test.EnumMembers>
}
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<test.EnumMembers> {
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<test.EnumMembers>
}
@@ -5,12 +5,6 @@ public final enum class JavaEnum : kotlin.Enum<test.JavaEnum> {
public final override /*1*/ /*fake_override*/ fun name(): kotlin.String
public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int
public class object <class-object-for-JavaEnum> {
private constructor <class-object-for-JavaEnum>()
public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): test.JavaEnum
public final /*synthesized*/ fun values(): kotlin.Array<test.JavaEnum>
}
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<test.JavaEnum> {
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<test.JavaEnum>
}
@@ -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 <class-object-for-MyEnum> {
private constructor <class-object-for-MyEnum>()
public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): test.CustomAnnotation.MyEnum
public final /*synthesized*/ fun values(): kotlin.Array<test.CustomAnnotation.MyEnum>
}
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.MyEnum>
}
test.CustomAnnotation.MyAnnotation(value = MyEnum.ONE: test.CustomAnnotation.MyEnum) public open class MyTest {
@@ -5,12 +5,6 @@ public final enum class Enum : kotlin.Enum<test.Enum> {
public final override /*1*/ /*fake_override*/ fun name(): kotlin.String
public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int
public class object <class-object-for-Enum> {
private constructor <class-object-for-Enum>()
public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): test.Enum
public final /*synthesized*/ fun values(): kotlin.Array<test.Enum>
}
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<test.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<test.Enum>
}
@@ -5,12 +5,6 @@ public final enum class StaticMembersInEnum : kotlin.Enum<test.StaticMembersInEn
public final override /*1*/ /*fake_override*/ fun name(): kotlin.String
public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int
public class object <class-object-for-StaticMembersInEnum> {
private constructor <class-object-for-StaticMembersInEnum>()
public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): test.StaticMembersInEnum
public final /*synthesized*/ fun values(): kotlin.Array<test.StaticMembersInEnum>
}
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<test.StaticMembersInEn
public final var STATIC_FIELD: kotlin.Int
public open fun foo(): kotlin.Unit
public open fun valueOf(/*0*/ p0: kotlin.Int): kotlin.Unit
public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): test.StaticMembersInEnum
public final /*synthesized*/ fun values(): kotlin.Array<test.StaticMembersInEnum>
public open fun values(/*0*/ p0: kotlin.Int): kotlin.Unit
}
@@ -17,9 +17,7 @@ internal final enum class E : kotlin.Enum<test.E> {
public final override /*1*/ /*fake_override*/ fun name(): kotlin.String
public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int
public class object <class-object-for-E> {
/*primary*/ private constructor <class-object-for-E>()
public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): test.E
public final /*synthesized*/ fun values(): kotlin.Array<test.E>
}
// Static members
public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): test.E
public final /*synthesized*/ fun values(): kotlin.Array<test.E>
}
@@ -5,9 +5,7 @@ internal final enum class EnumWithGenericConstructorParameter : kotlin.Enum<test
public final override /*1*/ /*fake_override*/ fun name(): kotlin.String
public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int
public class object <class-object-for-EnumWithGenericConstructorParameter> {
/*primary*/ private constructor <class-object-for-EnumWithGenericConstructorParameter>()
public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): test.EnumWithGenericConstructorParameter
public final /*synthesized*/ fun values(): kotlin.Array<test.EnumWithGenericConstructorParameter>
}
// Static members
public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): test.EnumWithGenericConstructorParameter
public final /*synthesized*/ fun values(): kotlin.Array<test.EnumWithGenericConstructorParameter>
}
@@ -5,9 +5,7 @@ internal final enum class EnumWithPrimitiveConstructorParameter : kotlin.Enum<te
public final override /*1*/ /*fake_override*/ fun name(): kotlin.String
public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int
public class object <class-object-for-EnumWithPrimitiveConstructorParameter> {
/*primary*/ private constructor <class-object-for-EnumWithPrimitiveConstructorParameter>()
public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): test.EnumWithPrimitiveConstructorParameter
public final /*synthesized*/ fun values(): kotlin.Array<test.EnumWithPrimitiveConstructorParameter>
}
// Static members
public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): test.EnumWithPrimitiveConstructorParameter
public final /*synthesized*/ fun values(): kotlin.Array<test.EnumWithPrimitiveConstructorParameter>
}
@@ -5,12 +5,6 @@ internal final enum class In : kotlin.Enum<test.In> {
public final override /*1*/ /*fake_override*/ fun name(): kotlin.String
public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int
public class object <class-object-for-In> {
/*primary*/ private constructor <class-object-for-In>()
public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): test.In
public final /*synthesized*/ fun values(): kotlin.Array<test.In>
}
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<test.In> {
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<test.In>
}
private final enum class Pr : kotlin.Enum<test.Pr> {
@@ -29,12 +27,6 @@ private final enum class Pr : kotlin.Enum<test.Pr> {
public final override /*1*/ /*fake_override*/ fun name(): kotlin.String
public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int
public class object <class-object-for-Pr> {
/*primary*/ private constructor <class-object-for-Pr>()
public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): test.Pr
public final /*synthesized*/ fun values(): kotlin.Array<test.Pr>
}
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<test.Pr> {
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<test.Pr>
}
public final enum class Pu : kotlin.Enum<test.Pu> {
@@ -53,12 +49,6 @@ public final enum class Pu : kotlin.Enum<test.Pu> {
public final override /*1*/ /*fake_override*/ fun name(): kotlin.String
public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int
public class object <class-object-for-Pu> {
/*primary*/ private constructor <class-object-for-Pu>()
public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): test.Pu
public final /*synthesized*/ fun values(): kotlin.Array<test.Pu>
}
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<test.Pu> {
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<test.Pu>
}
@@ -9,12 +9,6 @@ internal final enum class En : kotlin.Enum<test.En> {
public final override /*1*/ /*fake_override*/ fun name(): kotlin.String
public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int
public class object <class-object-for-En> {
/*primary*/ private constructor <class-object-for-En>()
public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): test.En
public final /*synthesized*/ fun values(): kotlin.Array<test.En>
}
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<test.En> {
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<test.En>
}
@@ -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 <class-object-for-E> {
/*primary*/ private constructor <class-object-for-E>()
public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): test.A.E
public final /*synthesized*/ fun values(): kotlin.Array<test.A.E>
}
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<test.A.E>
}
}
@@ -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 <class-object-for-E> {
/*primary*/ private constructor <class-object-for-E>()
public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): test.A.E
public final /*synthesized*/ fun values(): kotlin.Array<test.A.E>
}
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<test.A.E>
}
}
@@ -5,12 +5,6 @@ internal final enum class MyEnum : kotlin.Enum<test.MyEnum> {
public final override /*1*/ /*fake_override*/ fun name(): kotlin.String
public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int
public class object <class-object-for-MyEnum> {
/*primary*/ private constructor <class-object-for-MyEnum>()
public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): test.MyEnum
public final /*synthesized*/ fun values(): kotlin.Array<test.MyEnum>
}
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<test.MyEnum> {
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<test.MyEnum>
}
@@ -5,12 +5,6 @@ internal final enum class Test : kotlin.Enum<test.Test> {
public final override /*1*/ /*fake_override*/ fun name(): kotlin.String
public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int
public class object <class-object-for-Test> {
/*primary*/ private constructor <class-object-for-Test>()
public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): test.Test
public final /*synthesized*/ fun values(): kotlin.Array<test.Test>
}
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<test.Test> {
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<test.Test>
}
@@ -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");
@@ -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");
@@ -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");
@@ -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()
@@ -87,6 +87,8 @@ public class LazyJavaClassMemberScope(
c.errorReporter))
}
override fun computeAdditionalFunctions(name: Name) = listOf<SimpleFunctionDescriptor>()
private fun getPropertiesFromSupertypes(name: Name, descriptor: ClassDescriptor): Set<PropertyDescriptor> {
return descriptor.getTypeConstructor().getSupertypes().flatMap {
it.getMemberScope().getProperties(name).map { p -> p as PropertyDescriptor }
@@ -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<SimpleFunctionDescriptor>
private val _functions = c.storageManager.createMemoizedFunction {
(name: Name): Collection<FunctionDescriptor>
->
(name: Name): Collection<FunctionDescriptor> ->
val methods = memberIndex().findMethodsByName(name)
val functions = LinkedHashSet<SimpleFunctionDescriptor>(
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)
@@ -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<SimpleFunctionDescriptor>()
override fun getAllClassNames(): Collection<Name> {
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<Name> {
if (jClass.isEnum()) {
return super.getAllFunctionNames() + listOf(Name.identifier("valueOf"), Name.identifier("values"))
}
return super.getAllFunctionNames()
}
override fun computeAdditionalFunctions(name: Name): Collection<SimpleFunctionDescriptor> {
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<Name> = listOf()
override fun getClassifier(name: Name): ClassifierDescriptor? = null
@@ -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);
}
@@ -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<ConstructorDescriptor> = 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<FunctionDescriptor> by Delegates.lazy {
val result = ArrayList<FunctionDescriptor>(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
}
}
@@ -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.<TypeParameterDescriptor>emptyList(),
Collections.<ValueParameterDescriptor>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.<TypeParameterDescriptor>emptyList(),
Collections.singletonList(parameterDescriptor), enumClass.getDefaultType(), Modality.FINAL,
Visibilities.PUBLIC);
}
@Nullable
public static ReceiverParameterDescriptor createReceiverParameterForCallable(
@NotNull CallableDescriptor owner,
@@ -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
@@ -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
@@ -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<DeclarationDescriptor>() // TODO
private val functions: List<FunctionDescriptor> by Delegates.lazy {
if (containingClass.getKind() != ClassKind.ENUM_CLASS) {
listOf<FunctionDescriptor>()
}
else {
listOf(createEnumValueOfMethod(containingClass), createEnumValuesMethod(containingClass))
}
}
override fun getOwnDeclaredDescriptors() = listOf<DeclarationDescriptor>() // TODO
override fun getAllDescriptors() = functions
override fun getOwnDeclaredDescriptors() = functions
override fun getFunctions(name: Name) = functions.filterTo(ArrayList<FunctionDescriptor>(2)) { it.getName() == name }
override fun getPackage(name: Name) = null
override fun getProperties(name: Name) = listOf<VariableDescriptor>()
override fun getLocalVariable(name: Name) = null
override fun getFunctions(name: Name) = listOf<FunctionDescriptor>()
override fun getContainingDeclaration() = containingClass
override fun getDeclarationsByLabel(labelName: Name) = listOf<DeclarationDescriptor>()
override fun getImplicitReceiversHierarchy() = listOf<ReceiverParameterDescriptor>()
@@ -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()) {
@@ -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")
@@ -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");