Extract "values" and "valueOf" names as static constants
This commit is contained in:
@@ -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<ValueParameterDescriptor> 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<ValueParameterDescriptor> methodTypeParameters = functionDescriptor.getValueParameters();
|
||||
return "values".equals(functionDescriptor.getName().asString())
|
||||
return DescriptorUtils.ENUM_VALUES.equals(functionDescriptor.getName())
|
||||
&& methodTypeParameters.isEmpty();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<FunctionDescriptor, Boolean>() {
|
||||
@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<FunctionDescriptor, Boolean>() {
|
||||
@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<FunctionDescriptor, Boolean>() {
|
||||
@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<FunctionDescriptor, Boolean>() {
|
||||
@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<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() {
|
||||
Map<DeclarationDescriptor, DeclarationDescriptor> accessors = context.getAccessors();
|
||||
for (Map.Entry<DeclarationDescriptor, DeclarationDescriptor> 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) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<JetExpression> arguments,
|
||||
StackValue receiver
|
||||
) {
|
||||
v.invokestatic(returnType.getElementType().getInternalName(), "values", "()" + returnType, false);
|
||||
v.invokestatic(returnType.getElementType().getInternalName(), ENUM_VALUES.asString(), "()" + returnType, false);
|
||||
return returnType;
|
||||
}
|
||||
}
|
||||
|
||||
+1
@@ -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;
|
||||
|
||||
+5
-3
@@ -170,15 +170,17 @@ public class LazyJavaStaticClassScope(
|
||||
|
||||
override fun getAllFunctionNames(): Collection<Name> {
|
||||
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<SimpleFunctionDescriptor> {
|
||||
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()
|
||||
}
|
||||
|
||||
@@ -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.<TypeParameterDescriptor>emptyList(),
|
||||
Collections.<ValueParameterDescriptor>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,
|
||||
|
||||
@@ -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() {
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user