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.JetExpression;
|
||||||
import org.jetbrains.jet.lang.psi.JetSimpleNameExpression;
|
import org.jetbrains.jet.lang.psi.JetSimpleNameExpression;
|
||||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
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.CallResolverUtil;
|
||||||
import org.jetbrains.jet.lang.resolve.calls.callUtil.CallUtilPackage;
|
import org.jetbrains.jet.lang.resolve.calls.callUtil.CallUtilPackage;
|
||||||
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall;
|
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall;
|
||||||
@@ -176,14 +177,14 @@ public class CodegenUtil {
|
|||||||
public static boolean isEnumValueOfMethod(@NotNull FunctionDescriptor functionDescriptor) {
|
public static boolean isEnumValueOfMethod(@NotNull FunctionDescriptor functionDescriptor) {
|
||||||
List<ValueParameterDescriptor> methodTypeParameters = functionDescriptor.getValueParameters();
|
List<ValueParameterDescriptor> methodTypeParameters = functionDescriptor.getValueParameters();
|
||||||
JetType nullableString = TypeUtils.makeNullable(KotlinBuiltIns.getInstance().getStringType());
|
JetType nullableString = TypeUtils.makeNullable(KotlinBuiltIns.getInstance().getStringType());
|
||||||
return "valueOf".equals(functionDescriptor.getName().asString())
|
return DescriptorUtils.ENUM_VALUE_OF.equals(functionDescriptor.getName())
|
||||||
&& methodTypeParameters.size() == 1
|
&& methodTypeParameters.size() == 1
|
||||||
&& JetTypeChecker.DEFAULT.isSubtypeOf(methodTypeParameters.get(0).getType(), nullableString);
|
&& JetTypeChecker.DEFAULT.isSubtypeOf(methodTypeParameters.get(0).getType(), nullableString);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isEnumValuesMethod(@NotNull FunctionDescriptor functionDescriptor) {
|
public static boolean isEnumValuesMethod(@NotNull FunctionDescriptor functionDescriptor) {
|
||||||
List<ValueParameterDescriptor> methodTypeParameters = functionDescriptor.getValueParameters();
|
List<ValueParameterDescriptor> methodTypeParameters = functionDescriptor.getValueParameters();
|
||||||
return "values".equals(functionDescriptor.getName().asString())
|
return DescriptorUtils.ENUM_VALUES.equals(functionDescriptor.getName())
|
||||||
&& methodTypeParameters.isEmpty();
|
&& methodTypeParameters.isEmpty();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ import static org.jetbrains.jet.lang.resolve.java.diagnostics.JvmDeclarationOrig
|
|||||||
import static org.jetbrains.org.objectweb.asm.Opcodes.*;
|
import static org.jetbrains.org.objectweb.asm.Opcodes.*;
|
||||||
|
|
||||||
public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||||
private static final String VALUES = "$VALUES";
|
private static final String ENUM_VALUES_FIELD_NAME = "$VALUES";
|
||||||
private JetDelegatorToSuperCall superCall;
|
private JetDelegatorToSuperCall superCall;
|
||||||
private Type superClassAsmType;
|
private Type superClassAsmType;
|
||||||
@Nullable // null means java/lang/Object
|
@Nullable // null means java/lang/Object
|
||||||
@@ -925,17 +925,19 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
private void generateEnumValuesMethod() {
|
private void generateEnumValuesMethod() {
|
||||||
Type type = typeMapper.mapType(KotlinBuiltIns.getInstance().getArrayType(descriptor.getDefaultType()));
|
Type type = typeMapper.mapType(KotlinBuiltIns.getInstance().getArrayType(descriptor.getDefaultType()));
|
||||||
|
|
||||||
FunctionDescriptor valuesFunction = findEnumFunction("values", new Function1<FunctionDescriptor, Boolean>() {
|
FunctionDescriptor valuesFunction =
|
||||||
@Override
|
KotlinPackage.single(descriptor.getStaticScope().getFunctions(ENUM_VALUES), new Function1<FunctionDescriptor, Boolean>() {
|
||||||
public Boolean invoke(FunctionDescriptor descriptor) {
|
@Override
|
||||||
return CodegenUtil.isEnumValuesMethod(descriptor);
|
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);
|
});
|
||||||
|
MethodVisitor mv = v.newMethod(OtherOrigin(myClass, valuesFunction), ACC_PUBLIC | ACC_STATIC, ENUM_VALUES.asString(),
|
||||||
|
"()" + type.getDescriptor(), null, null);
|
||||||
if (state.getClassBuilderMode() != ClassBuilderMode.FULL) return;
|
if (state.getClassBuilderMode() != ClassBuilderMode.FULL) return;
|
||||||
|
|
||||||
mv.visitCode();
|
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.visitMethodInsn(INVOKEVIRTUAL, type.getInternalName(), "clone", "()Ljava/lang/Object;", false);
|
||||||
mv.visitTypeInsn(CHECKCAST, type.getInternalName());
|
mv.visitTypeInsn(CHECKCAST, type.getInternalName());
|
||||||
mv.visitInsn(ARETURN);
|
mv.visitInsn(ARETURN);
|
||||||
@@ -943,14 +945,15 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void generateEnumValueOfMethod() {
|
private void generateEnumValueOfMethod() {
|
||||||
FunctionDescriptor valueOfFunction = findEnumFunction("valueOf", new Function1<FunctionDescriptor, Boolean>() {
|
FunctionDescriptor valueOfFunction =
|
||||||
@Override
|
KotlinPackage.single(descriptor.getStaticScope().getFunctions(ENUM_VALUE_OF), new Function1<FunctionDescriptor, Boolean>() {
|
||||||
public Boolean invoke(FunctionDescriptor descriptor) {
|
@Override
|
||||||
return CodegenUtil.isEnumValueOfMethod(descriptor);
|
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);
|
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;
|
if (state.getClassBuilderMode() != ClassBuilderMode.FULL) return;
|
||||||
|
|
||||||
mv.visitCode();
|
mv.visitCode();
|
||||||
@@ -962,14 +965,6 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
FunctionCodegen.endVisit(mv, "valueOf()", myClass);
|
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() {
|
protected void generateSyntheticAccessors() {
|
||||||
Map<DeclarationDescriptor, DeclarationDescriptor> accessors = context.getAccessors();
|
Map<DeclarationDescriptor, DeclarationDescriptor> accessors = context.getAccessors();
|
||||||
for (Map.Entry<DeclarationDescriptor, DeclarationDescriptor> entry : accessors.entrySet()) {
|
for (Map.Entry<DeclarationDescriptor, DeclarationDescriptor> entry : accessors.entrySet()) {
|
||||||
@@ -1633,7 +1628,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
InstructionAdapter iv = codegen.v;
|
InstructionAdapter iv = codegen.v;
|
||||||
|
|
||||||
Type arrayAsmType = typeMapper.mapType(KotlinBuiltIns.getInstance().getArrayType(descriptor.getDefaultType()));
|
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.iconst(myEnumConstants.size());
|
||||||
iv.newarray(classAsmType);
|
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) {
|
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 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;
|
import static org.jetbrains.jet.lang.resolve.java.AsmTypeConstants.JAVA_STRING_TYPE;
|
||||||
|
|
||||||
public class EnumValueOf extends IntrinsicMethod {
|
public class EnumValueOf extends IntrinsicMethod {
|
||||||
@@ -42,7 +43,7 @@ public class EnumValueOf extends IntrinsicMethod {
|
|||||||
) {
|
) {
|
||||||
assert arguments != null;
|
assert arguments != null;
|
||||||
codegen.gen(arguments.get(0), JAVA_STRING_TYPE);
|
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;
|
return returnType;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,6 +27,8 @@ import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.jetbrains.jet.lang.resolve.DescriptorUtils.ENUM_VALUES;
|
||||||
|
|
||||||
public class EnumValues extends IntrinsicMethod {
|
public class EnumValues extends IntrinsicMethod {
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
@@ -38,7 +40,7 @@ public class EnumValues extends IntrinsicMethod {
|
|||||||
@Nullable List<JetExpression> arguments,
|
@Nullable List<JetExpression> arguments,
|
||||||
StackValue receiver
|
StackValue receiver
|
||||||
) {
|
) {
|
||||||
v.invokestatic(returnType.getElementType().getInternalName(), "values", "()" + returnType, false);
|
v.invokestatic(returnType.getElementType().getInternalName(), ENUM_VALUES.asString(), "()" + returnType, false);
|
||||||
return returnType;
|
return returnType;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
@@ -22,6 +22,7 @@ import org.jetbrains.jet.codegen.AsmUtil;
|
|||||||
import org.jetbrains.jet.codegen.ClassBuilder;
|
import org.jetbrains.jet.codegen.ClassBuilder;
|
||||||
import org.jetbrains.jet.codegen.state.GenerationState;
|
import org.jetbrains.jet.codegen.state.GenerationState;
|
||||||
import org.jetbrains.jet.lang.psi.JetFile;
|
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.constants.EnumValue;
|
||||||
import org.jetbrains.jet.lang.resolve.java.diagnostics.JvmDeclarationOrigin;
|
import org.jetbrains.jet.lang.resolve.java.diagnostics.JvmDeclarationOrigin;
|
||||||
import org.jetbrains.org.objectweb.asm.MethodVisitor;
|
import org.jetbrains.org.objectweb.asm.MethodVisitor;
|
||||||
|
|||||||
+5
-3
@@ -170,15 +170,17 @@ public class LazyJavaStaticClassScope(
|
|||||||
|
|
||||||
override fun getAllFunctionNames(): Collection<Name> {
|
override fun getAllFunctionNames(): Collection<Name> {
|
||||||
if (jClass.isEnum()) {
|
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()
|
return super.getAllFunctionNames()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun computeAdditionalFunctions(name: Name): Collection<SimpleFunctionDescriptor> {
|
override fun computeAdditionalFunctions(name: Name): Collection<SimpleFunctionDescriptor> {
|
||||||
if (jClass.isEnum()) {
|
if (jClass.isEnum()) {
|
||||||
if (name.asString() == "valueOf") return listOf(createEnumValueOfMethod(getContainingDeclaration()))
|
when (name) {
|
||||||
if (name.asString() == "values") return listOf(createEnumValuesMethod(getContainingDeclaration()))
|
DescriptorUtils.ENUM_VALUE_OF -> return listOf(createEnumValueOfMethod(getContainingDeclaration()))
|
||||||
|
DescriptorUtils.ENUM_VALUES -> return listOf(createEnumValuesMethod(getContainingDeclaration()))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return listOf()
|
return listOf()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ public class DescriptorFactory {
|
|||||||
@NotNull
|
@NotNull
|
||||||
public static SimpleFunctionDescriptor createEnumValuesMethod(@NotNull ClassDescriptor enumClass) {
|
public static SimpleFunctionDescriptor createEnumValuesMethod(@NotNull ClassDescriptor enumClass) {
|
||||||
SimpleFunctionDescriptorImpl values =
|
SimpleFunctionDescriptorImpl values =
|
||||||
SimpleFunctionDescriptorImpl.create(enumClass, Annotations.EMPTY, Name.identifier("values"),
|
SimpleFunctionDescriptorImpl.create(enumClass, Annotations.EMPTY, DescriptorUtils.ENUM_VALUES,
|
||||||
CallableMemberDescriptor.Kind.SYNTHESIZED, SourceElement.NO_SOURCE);
|
CallableMemberDescriptor.Kind.SYNTHESIZED, SourceElement.NO_SOURCE);
|
||||||
return values.initialize(null, NO_RECEIVER_PARAMETER, Collections.<TypeParameterDescriptor>emptyList(),
|
return values.initialize(null, NO_RECEIVER_PARAMETER, Collections.<TypeParameterDescriptor>emptyList(),
|
||||||
Collections.<ValueParameterDescriptor>emptyList(),
|
Collections.<ValueParameterDescriptor>emptyList(),
|
||||||
@@ -96,7 +96,7 @@ public class DescriptorFactory {
|
|||||||
@NotNull
|
@NotNull
|
||||||
public static SimpleFunctionDescriptor createEnumValueOfMethod(@NotNull ClassDescriptor enumClass) {
|
public static SimpleFunctionDescriptor createEnumValueOfMethod(@NotNull ClassDescriptor enumClass) {
|
||||||
SimpleFunctionDescriptorImpl valueOf =
|
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);
|
CallableMemberDescriptor.Kind.SYNTHESIZED, SourceElement.NO_SOURCE);
|
||||||
ValueParameterDescriptor parameterDescriptor = new ValueParameterDescriptorImpl(
|
ValueParameterDescriptor parameterDescriptor = new ValueParameterDescriptorImpl(
|
||||||
valueOf, null, 0, Annotations.EMPTY, Name.identifier("value"), KotlinBuiltIns.getInstance().getStringType(), false, null,
|
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;
|
import static org.jetbrains.jet.lang.descriptors.ReceiverParameterDescriptor.NO_RECEIVER_PARAMETER;
|
||||||
|
|
||||||
public class DescriptorUtils {
|
public class DescriptorUtils {
|
||||||
|
public static final Name ENUM_VALUES = Name.identifier("values");
|
||||||
|
public static final Name ENUM_VALUE_OF = Name.identifier("valueOf");
|
||||||
|
|
||||||
private DescriptorUtils() {
|
private DescriptorUtils() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user