diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/IntrinsicMethods.java b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/IntrinsicMethods.java index c6fe16c8a2a..d4fdf7e46ed 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/IntrinsicMethods.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/IntrinsicMethods.java @@ -19,7 +19,9 @@ package org.jetbrains.jet.codegen.intrinsics; import com.google.common.collect.ImmutableList; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.jet.lang.descriptors.*; +import org.jetbrains.jet.lang.descriptors.CallableMemberDescriptor; +import org.jetbrains.jet.lang.descriptors.ClassifierDescriptor; +import org.jetbrains.jet.lang.descriptors.SimpleFunctionDescriptor; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; import org.jetbrains.jet.lang.resolve.java.JvmPrimitiveType; import org.jetbrains.jet.lang.resolve.name.FqName; @@ -35,7 +37,7 @@ import java.util.List; import java.util.Map; import static org.jetbrains.asm4.Opcodes.*; -import static org.jetbrains.jet.lang.resolve.DescriptorUtils.getClassObjectName; +import static org.jetbrains.jet.lang.resolve.DescriptorUtils.*; public class IntrinsicMethods { private static final IntrinsicMethod UNARY_MINUS = new UnaryMinus(); @@ -229,10 +231,11 @@ public class IntrinsicMethods { SimpleFunctionDescriptor functionDescriptor = (SimpleFunctionDescriptor) descriptor; if (isEnumClassObject(functionDescriptor.getContainingDeclaration())) { - if ("values".equals(functionDescriptor.getName().getName())) { + if (isEnumValuesMethod(functionDescriptor)) { return ENUM_VALUES; } - if ("valueOf".equals(functionDescriptor.getName().getName())) { + + if (isEnumValueOfMethod(functionDescriptor)) { return ENUM_VALUE_OF; } } @@ -254,20 +257,4 @@ public class IntrinsicMethods { } return intrinsicMethod; } - - private static boolean isEnumClassObject(DeclarationDescriptor declaration) { - if (declaration instanceof ClassDescriptor) { - ClassDescriptor descriptor = (ClassDescriptor) declaration; - if (descriptor.getContainingDeclaration() instanceof ClassDescriptor) { - ClassDescriptor containingDeclaration = (ClassDescriptor) descriptor.getContainingDeclaration(); - //noinspection ConstantConditions - if (containingDeclaration != null && - containingDeclaration.getClassObjectDescriptor() != null && - containingDeclaration.getClassObjectDescriptor().equals(descriptor)) { - return true; - } - } - } - return false; - } } diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaFunctionResolver.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaFunctionResolver.java index 383760e66aa..1bdedd22b37 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaFunctionResolver.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaFunctionResolver.java @@ -40,7 +40,6 @@ import org.jetbrains.jet.lang.resolve.java.wrapper.PsiMethodWrapper; import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.lang.types.*; import org.jetbrains.jet.lang.types.checker.JetTypeChecker; -import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; import javax.inject.Inject; import java.util.Collections; @@ -48,6 +47,7 @@ import java.util.HashSet; import java.util.List; import java.util.Set; +import static org.jetbrains.jet.lang.resolve.DescriptorUtils.*; import static org.jetbrains.jet.lang.resolve.OverridingUtil.*; import static org.jetbrains.jet.lang.resolve.java.provider.DeclarationOrigin.JAVA; import static org.jetbrains.jet.lang.resolve.java.provider.DeclarationOrigin.KOTLIN; @@ -296,9 +296,9 @@ public final class JavaFunctionResolver { OverrideResolver.resolveUnknownVisibilities(functions, trace); functions.addAll(functionsFromCurrent); - if (DescriptorUtils.isEnumClassObject(owner)) { + if (isEnumClassObject(owner)) { for (FunctionDescriptor functionDescriptor : Lists.newArrayList(functions)) { - if (isEnumSpecialMethod(functionDescriptor)) { + if (isEnumValueOfMethod(functionDescriptor) || isEnumValuesMethod(functionDescriptor)) { functions.remove(functionDescriptor); } } @@ -361,17 +361,6 @@ public final class JavaFunctionResolver { return r; } - private static boolean isEnumSpecialMethod(@NotNull FunctionDescriptor functionDescriptor) { - List methodTypeParameters = functionDescriptor.getValueParameters(); - String methodName = functionDescriptor.getName().getName(); - JetType nullableString = TypeUtils.makeNullable(KotlinBuiltIns.getInstance().getStringType()); - if (methodName.equals("valueOf") && methodTypeParameters.size() == 1 - && JetTypeChecker.INSTANCE.isSubtypeOf(methodTypeParameters.get(0).getType(), nullableString)) { - return true; - } - return (methodName.equals("values") && methodTypeParameters.isEmpty()); - } - private static boolean containsErrorType(@NotNull List superFunctions, @NotNull FunctionDescriptor function) { if (containsErrorType(function)) { return true; diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java index a215b082834..33203194794 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java @@ -354,10 +354,14 @@ public class DescriptorUtils { return Name.special(""); } - public static boolean isEnumClassObject(@NotNull DeclarationDescriptor classObjectDescriptor) { - DeclarationDescriptor containingDeclaration = classObjectDescriptor.getContainingDeclaration(); - return ((containingDeclaration instanceof ClassDescriptor) && - ((ClassDescriptor) containingDeclaration).getKind() == ClassKind.ENUM_CLASS); + public static boolean isEnumClassObject(@NotNull DeclarationDescriptor descriptor) { + if (descriptor instanceof ClassDescriptor && ((ClassDescriptor) descriptor).getKind() == ClassKind.CLASS_OBJECT) { + DeclarationDescriptor containing = descriptor.getContainingDeclaration(); + if ((containing instanceof ClassDescriptor) && ((ClassDescriptor) containing).getKind() == ClassKind.ENUM_CLASS) { + return true; + } + } + return false; } @NotNull @@ -512,4 +516,17 @@ public class DescriptorUtils { return null; } + public static boolean isEnumValueOfMethod(@NotNull FunctionDescriptor functionDescriptor) { + List methodTypeParameters = functionDescriptor.getValueParameters(); + JetType nullableString = TypeUtils.makeNullable(KotlinBuiltIns.getInstance().getStringType()); + return "valueOf".equals(functionDescriptor.getName().getName()) + && methodTypeParameters.size() == 1 + && JetTypeChecker.INSTANCE.isSubtypeOf(methodTypeParameters.get(0).getType(), nullableString); + } + + public static boolean isEnumValuesMethod(@NotNull FunctionDescriptor functionDescriptor) { + List methodTypeParameters = functionDescriptor.getValueParameters(); + return "values".equals(functionDescriptor.getName().getName()) + && methodTypeParameters.isEmpty(); + } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/descriptors/LazyClassMemberScope.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/descriptors/LazyClassMemberScope.java index 8fcb4f78688..db40dc32249 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/descriptors/LazyClassMemberScope.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/descriptors/LazyClassMemberScope.java @@ -189,7 +189,7 @@ public class LazyClassMemberScope extends AbstractLazyMemberScope result, @NotNull Name name) { - if (!isEnumClassObject()) return; + if (!DescriptorUtils.isEnumClassObject(thisDescriptor)) return; if (name.equals(DescriptorResolver.VALUES_METHOD_NAME)) { SimpleFunctionDescriptor valuesMethod = DescriptorResolver @@ -203,15 +203,6 @@ public class LazyClassMemberScope extends AbstractLazyMemberScope getProperties(@NotNull Name name) { diff --git a/compiler/testData/codegen/box/classes/classObjectNotOfEnum.kt b/compiler/testData/codegen/box/classes/classObjectNotOfEnum.kt new file mode 100644 index 00000000000..4cbb7a4e0a6 --- /dev/null +++ b/compiler/testData/codegen/box/classes/classObjectNotOfEnum.kt @@ -0,0 +1,8 @@ +class A { + class object { + fun values() = "O" + fun valueOf() = "K" + } +} + +fun box() = A.values() + A.valueOf() diff --git a/compiler/testData/loadJava/compiledJava/static/Enum.java b/compiler/testData/loadJava/compiledJava/static/Enum.java index 19106c02dad..4e9b9aa8ea1 100644 --- a/compiler/testData/loadJava/compiledJava/static/Enum.java +++ b/compiler/testData/loadJava/compiledJava/static/Enum.java @@ -7,9 +7,11 @@ public enum Enum { public static class Nested { void foo() {} + void values() {} } public class Inner { void bar() {} + void valueOf(String s) {} } } \ No newline at end of file diff --git a/compiler/testData/loadJava/compiledJava/static/Enum.txt b/compiler/testData/loadJava/compiledJava/static/Enum.txt index 9c9e4d3e4e1..28b1c534a06 100644 --- a/compiler/testData/loadJava/compiledJava/static/Enum.txt +++ b/compiler/testData/loadJava/compiledJava/static/Enum.txt @@ -17,10 +17,12 @@ public final enum class Enum : jet.Enum { public open inner class Inner : java.lang.Object { public constructor Inner() public/*package*/ open fun bar() : Unit + public/*package*/ open fun valueOf(/*0*/ p0 : jet.String?) : Unit } public open class Nested : java.lang.Object { public constructor Nested() public/*package*/ open fun foo() : Unit + public/*package*/ open fun values() : Unit } } diff --git a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java index 7688bddc584..3535ef1d278 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java @@ -477,6 +477,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { doTest("compiler/testData/codegen/box/classes/classObjectInTrait.kt"); } + @TestMetadata("classObjectNotOfEnum.kt") + public void testClassObjectNotOfEnum() throws Exception { + doTest("compiler/testData/codegen/box/classes/classObjectNotOfEnum.kt"); + } + @TestMetadata("delegation2.kt") public void testDelegation2() throws Exception { doTest("compiler/testData/codegen/box/classes/delegation2.kt");