diff --git a/compiler/backend-common/src/org/jetbrains/jet/backend/common/CodegenUtil.java b/compiler/backend-common/src/org/jetbrains/jet/backend/common/CodegenUtil.java index c42c38c13e0..8ecd58263ee 100644 --- a/compiler/backend-common/src/org/jetbrains/jet/backend/common/CodegenUtil.java +++ b/compiler/backend-common/src/org/jetbrains/jet/backend/common/CodegenUtil.java @@ -23,6 +23,7 @@ import org.jetbrains.jet.lang.psi.JetDelegationSpecifier; import org.jetbrains.jet.lang.psi.JetExpression; import org.jetbrains.jet.lang.psi.JetSimpleNameExpression; import org.jetbrains.jet.lang.resolve.BindingContext; +import org.jetbrains.jet.lang.resolve.DescriptorUtils; import org.jetbrains.jet.lang.resolve.calls.CallResolverUtil; import org.jetbrains.jet.lang.resolve.calls.callUtil.CallUtilPackage; import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall; @@ -176,14 +177,14 @@ public class CodegenUtil { public static boolean isEnumValueOfMethod(@NotNull FunctionDescriptor functionDescriptor) { List methodTypeParameters = functionDescriptor.getValueParameters(); JetType nullableString = TypeUtils.makeNullable(KotlinBuiltIns.getInstance().getStringType()); - return "valueOf".equals(functionDescriptor.getName().asString()) + return DescriptorUtils.ENUM_VALUE_OF.equals(functionDescriptor.getName()) && methodTypeParameters.size() == 1 && JetTypeChecker.DEFAULT.isSubtypeOf(methodTypeParameters.get(0).getType(), nullableString); } public static boolean isEnumValuesMethod(@NotNull FunctionDescriptor functionDescriptor) { List methodTypeParameters = functionDescriptor.getValueParameters(); - return "values".equals(functionDescriptor.getName().asString()) + return DescriptorUtils.ENUM_VALUES.equals(functionDescriptor.getName()) && methodTypeParameters.isEmpty(); } } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java index ca45ffa6245..9d897d52baf 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java @@ -83,7 +83,7 @@ import static org.jetbrains.jet.lang.resolve.java.diagnostics.JvmDeclarationOrig import static org.jetbrains.org.objectweb.asm.Opcodes.*; public class ImplementationBodyCodegen extends ClassBodyCodegen { - private static final String VALUES = "$VALUES"; + private static final String ENUM_VALUES_FIELD_NAME = "$VALUES"; private JetDelegatorToSuperCall superCall; private Type superClassAsmType; @Nullable // null means java/lang/Object @@ -925,17 +925,19 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { private void generateEnumValuesMethod() { Type type = typeMapper.mapType(KotlinBuiltIns.getInstance().getArrayType(descriptor.getDefaultType())); - FunctionDescriptor valuesFunction = findEnumFunction("values", new Function1() { - @Override - public Boolean invoke(FunctionDescriptor descriptor) { - return CodegenUtil.isEnumValuesMethod(descriptor); - } - }); - MethodVisitor mv = v.newMethod(OtherOrigin(myClass, valuesFunction), ACC_PUBLIC | ACC_STATIC, "values", "()" + type.getDescriptor(), null, null); + FunctionDescriptor valuesFunction = + KotlinPackage.single(descriptor.getStaticScope().getFunctions(ENUM_VALUES), new Function1() { + @Override + public Boolean invoke(FunctionDescriptor descriptor) { + return CodegenUtil.isEnumValuesMethod(descriptor); + } + }); + MethodVisitor mv = v.newMethod(OtherOrigin(myClass, valuesFunction), ACC_PUBLIC | ACC_STATIC, ENUM_VALUES.asString(), + "()" + type.getDescriptor(), null, null); if (state.getClassBuilderMode() != ClassBuilderMode.FULL) return; mv.visitCode(); - mv.visitFieldInsn(GETSTATIC, classAsmType.getInternalName(), VALUES, type.getDescriptor()); + mv.visitFieldInsn(GETSTATIC, classAsmType.getInternalName(), ENUM_VALUES_FIELD_NAME, type.getDescriptor()); mv.visitMethodInsn(INVOKEVIRTUAL, type.getInternalName(), "clone", "()Ljava/lang/Object;", false); mv.visitTypeInsn(CHECKCAST, type.getInternalName()); mv.visitInsn(ARETURN); @@ -943,14 +945,15 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { } private void generateEnumValueOfMethod() { - FunctionDescriptor valueOfFunction = findEnumFunction("valueOf", new Function1() { - @Override - public Boolean invoke(FunctionDescriptor descriptor) { - return CodegenUtil.isEnumValueOfMethod(descriptor); - } - }); - MethodVisitor mv = v.newMethod(OtherOrigin(myClass, valueOfFunction), - ACC_PUBLIC | ACC_STATIC, "valueOf", "(Ljava/lang/String;)" + classAsmType.getDescriptor(), null, null); + FunctionDescriptor valueOfFunction = + KotlinPackage.single(descriptor.getStaticScope().getFunctions(ENUM_VALUE_OF), new Function1() { + @Override + public Boolean invoke(FunctionDescriptor descriptor) { + return CodegenUtil.isEnumValueOfMethod(descriptor); + } + }); + MethodVisitor mv = v.newMethod(OtherOrigin(myClass, valueOfFunction), ACC_PUBLIC | ACC_STATIC, ENUM_VALUE_OF.asString(), + "(Ljava/lang/String;)" + classAsmType.getDescriptor(), null, null); if (state.getClassBuilderMode() != ClassBuilderMode.FULL) return; mv.visitCode(); @@ -962,14 +965,6 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { FunctionCodegen.endVisit(mv, "valueOf()", myClass); } - @NotNull - 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() { Map accessors = context.getAccessors(); for (Map.Entry entry : accessors.entrySet()) { @@ -1633,7 +1628,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { InstructionAdapter iv = codegen.v; Type arrayAsmType = typeMapper.mapType(KotlinBuiltIns.getInstance().getArrayType(descriptor.getDefaultType())); - v.newField(OtherOrigin(myClass), ACC_PRIVATE | ACC_STATIC | ACC_FINAL | ACC_SYNTHETIC, VALUES, arrayAsmType.getDescriptor(), null, null); + v.newField(OtherOrigin(myClass), ACC_PRIVATE | ACC_STATIC | ACC_FINAL | ACC_SYNTHETIC, ENUM_VALUES_FIELD_NAME, + arrayAsmType.getDescriptor(), null, null); iv.iconst(myEnumConstants.size()); iv.newarray(classAsmType); @@ -1645,7 +1641,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { } } - iv.putstatic(classAsmType.getInternalName(), VALUES, arrayAsmType.getDescriptor()); + iv.putstatic(classAsmType.getInternalName(), ENUM_VALUES_FIELD_NAME, arrayAsmType.getDescriptor()); } private void initializeEnumConstant(@NotNull ExpressionCodegen codegen, int ordinal) { diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/EnumValueOf.java b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/EnumValueOf.java index 7568756ed23..8af7de2759f 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/EnumValueOf.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/EnumValueOf.java @@ -27,6 +27,7 @@ import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter; import java.util.List; +import static org.jetbrains.jet.lang.resolve.DescriptorUtils.ENUM_VALUE_OF; import static org.jetbrains.jet.lang.resolve.java.AsmTypeConstants.JAVA_STRING_TYPE; public class EnumValueOf extends IntrinsicMethod { @@ -42,7 +43,7 @@ public class EnumValueOf extends IntrinsicMethod { ) { assert arguments != null; codegen.gen(arguments.get(0), JAVA_STRING_TYPE); - v.invokestatic(returnType.getInternalName(), "valueOf", "(Ljava/lang/String;)" + returnType.getDescriptor(), false); + v.invokestatic(returnType.getInternalName(), ENUM_VALUE_OF.asString(), "(Ljava/lang/String;)" + returnType.getDescriptor(), false); return returnType; } } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/EnumValues.java b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/EnumValues.java index 301ed3ec2f6..80929155378 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/EnumValues.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/EnumValues.java @@ -27,6 +27,8 @@ import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter; import java.util.List; +import static org.jetbrains.jet.lang.resolve.DescriptorUtils.ENUM_VALUES; + public class EnumValues extends IntrinsicMethod { @NotNull @Override @@ -38,7 +40,7 @@ public class EnumValues extends IntrinsicMethod { @Nullable List arguments, StackValue receiver ) { - v.invokestatic(returnType.getElementType().getInternalName(), "values", "()" + returnType, false); + v.invokestatic(returnType.getElementType().getInternalName(), ENUM_VALUES.asString(), "()" + returnType, false); return returnType; } } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/when/MappingClassesForWhenByEnumCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/when/MappingClassesForWhenByEnumCodegen.java index c30f4c7f2fe..df6c375a6ae 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/when/MappingClassesForWhenByEnumCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/when/MappingClassesForWhenByEnumCodegen.java @@ -22,6 +22,7 @@ import org.jetbrains.jet.codegen.AsmUtil; import org.jetbrains.jet.codegen.ClassBuilder; import org.jetbrains.jet.codegen.state.GenerationState; import org.jetbrains.jet.lang.psi.JetFile; +import org.jetbrains.jet.lang.resolve.DescriptorUtils; import org.jetbrains.jet.lang.resolve.constants.EnumValue; import org.jetbrains.jet.lang.resolve.java.diagnostics.JvmDeclarationOrigin; import org.jetbrains.org.objectweb.asm.MethodVisitor; 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 645be388ce0..53be3319399 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 @@ -170,15 +170,17 @@ public class LazyJavaStaticClassScope( override fun getAllFunctionNames(): Collection { if (jClass.isEnum()) { - return super.getAllFunctionNames() + listOf(Name.identifier("valueOf"), Name.identifier("values")) + return super.getAllFunctionNames() + listOf(DescriptorUtils.ENUM_VALUE_OF, DescriptorUtils.ENUM_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())) + when (name) { + DescriptorUtils.ENUM_VALUE_OF -> return listOf(createEnumValueOfMethod(getContainingDeclaration())) + DescriptorUtils.ENUM_VALUES -> return listOf(createEnumValuesMethod(getContainingDeclaration())) + } } return listOf() } 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 489a376c120..6980b036e09 100644 --- a/core/descriptors/src/org/jetbrains/jet/lang/resolve/DescriptorFactory.java +++ b/core/descriptors/src/org/jetbrains/jet/lang/resolve/DescriptorFactory.java @@ -85,7 +85,7 @@ public class DescriptorFactory { @NotNull public static SimpleFunctionDescriptor createEnumValuesMethod(@NotNull ClassDescriptor enumClass) { SimpleFunctionDescriptorImpl values = - SimpleFunctionDescriptorImpl.create(enumClass, Annotations.EMPTY, Name.identifier("values"), + SimpleFunctionDescriptorImpl.create(enumClass, Annotations.EMPTY, DescriptorUtils.ENUM_VALUES, CallableMemberDescriptor.Kind.SYNTHESIZED, SourceElement.NO_SOURCE); return values.initialize(null, NO_RECEIVER_PARAMETER, Collections.emptyList(), Collections.emptyList(), @@ -96,7 +96,7 @@ public class DescriptorFactory { @NotNull public static SimpleFunctionDescriptor createEnumValueOfMethod(@NotNull ClassDescriptor enumClass) { SimpleFunctionDescriptorImpl valueOf = - SimpleFunctionDescriptorImpl.create(enumClass, Annotations.EMPTY, Name.identifier("valueOf"), + SimpleFunctionDescriptorImpl.create(enumClass, Annotations.EMPTY, DescriptorUtils.ENUM_VALUE_OF, CallableMemberDescriptor.Kind.SYNTHESIZED, SourceElement.NO_SOURCE); ValueParameterDescriptor parameterDescriptor = new ValueParameterDescriptorImpl( valueOf, null, 0, Annotations.EMPTY, Name.identifier("value"), KotlinBuiltIns.getInstance().getStringType(), false, null, 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 e0603d03aff..2751d001338 100644 --- a/core/descriptors/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java +++ b/core/descriptors/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java @@ -41,6 +41,9 @@ import java.util.Set; import static org.jetbrains.jet.lang.descriptors.ReceiverParameterDescriptor.NO_RECEIVER_PARAMETER; public class DescriptorUtils { + public static final Name ENUM_VALUES = Name.identifier("values"); + public static final Name ENUM_VALUE_OF = Name.identifier("valueOf"); + private DescriptorUtils() { }