enum constant constructors
This commit is contained in:
@@ -150,7 +150,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
|
|
||||||
Method method;
|
Method method;
|
||||||
CallableMethod callableMethod;
|
CallableMethod callableMethod;
|
||||||
if (myClass instanceof JetObjectDeclaration || isEnum(myClass)) {
|
if (constructorDescriptor == null) {
|
||||||
method = new Method("<init>", Type.VOID_TYPE, new Type[0]);
|
method = new Method("<init>", Type.VOID_TYPE, new Type[0]);
|
||||||
callableMethod = new CallableMethod("", method, Opcodes.INVOKESPECIAL, Collections.<Type>emptyList());
|
callableMethod = new CallableMethod("", method, Opcodes.INVOKESPECIAL, Collections.<Type>emptyList());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,10 +3,8 @@ package org.jetbrains.jet.codegen;
|
|||||||
import com.intellij.psi.PsiClass;
|
import com.intellij.psi.PsiClass;
|
||||||
import com.intellij.psi.PsiElement;
|
import com.intellij.psi.PsiElement;
|
||||||
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
||||||
import org.jetbrains.jet.lang.psi.JetClassOrObject;
|
import org.jetbrains.jet.lang.descriptors.ConstructorDescriptor;
|
||||||
import org.jetbrains.jet.lang.psi.JetDeclaration;
|
import org.jetbrains.jet.lang.psi.*;
|
||||||
import org.jetbrains.jet.lang.psi.JetDelegationSpecifier;
|
|
||||||
import org.jetbrains.jet.lang.psi.JetEnumEntry;
|
|
||||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||||
import org.jetbrains.jet.lang.types.JetType;
|
import org.jetbrains.jet.lang.types.JetType;
|
||||||
import org.objectweb.asm.ClassVisitor;
|
import org.objectweb.asm.ClassVisitor;
|
||||||
@@ -103,13 +101,35 @@ public class InterfaceBodyCodegen extends ClassBodyCodegen {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void initializeEnumConstants(InstructionAdapter v) {
|
private void initializeEnumConstants(InstructionAdapter v) {
|
||||||
|
ExpressionCodegen codegen = new ExpressionCodegen(v, new FrameMap(), Type.VOID_TYPE, context, state);
|
||||||
for (JetEnumEntry enumConstant : myEnumConstants) {
|
for (JetEnumEntry enumConstant : myEnumConstants) {
|
||||||
// TODO type and constructor parameters
|
// TODO type and constructor parameters
|
||||||
String intfClass = state.getTypeMapper().jvmName(descriptor, OwnerKind.INTERFACE);
|
String intfClass = state.getTypeMapper().jvmName(descriptor, OwnerKind.INTERFACE);
|
||||||
String implClass = state.getTypeMapper().jvmName(descriptor, OwnerKind.IMPLEMENTATION);
|
String implClass = state.getTypeMapper().jvmName(descriptor, OwnerKind.IMPLEMENTATION);
|
||||||
|
|
||||||
|
final List<JetDelegationSpecifier> delegationSpecifiers = enumConstant.getDelegationSpecifiers();
|
||||||
|
if (delegationSpecifiers.size() > 1) {
|
||||||
|
throw new UnsupportedOperationException("multiple delegation specifiers for enum constant not supported");
|
||||||
|
}
|
||||||
|
|
||||||
v.anew(Type.getObjectType(implClass));
|
v.anew(Type.getObjectType(implClass));
|
||||||
v.dup();
|
v.dup();
|
||||||
v.invokespecial(implClass, "<init>", "()V");
|
|
||||||
|
if (delegationSpecifiers.size() == 1) {
|
||||||
|
final JetDelegationSpecifier specifier = delegationSpecifiers.get(0);
|
||||||
|
if (specifier instanceof JetDelegatorToSuperCall) {
|
||||||
|
final JetDelegatorToSuperCall superCall = (JetDelegatorToSuperCall) specifier;
|
||||||
|
ConstructorDescriptor constructorDescriptor = state.getBindingContext().resolveSuperConstructor(superCall);
|
||||||
|
CallableMethod method = state.getTypeMapper().mapToCallableMethod(constructorDescriptor, OwnerKind.IMPLEMENTATION);
|
||||||
|
codegen.invokeMethodWithArguments(method, superCall);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw new UnsupportedOperationException("unsupported type of enum constant initializer: " + specifier);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
v.invokespecial(implClass, "<init>", "()V");
|
||||||
|
}
|
||||||
v.putstatic(intfClass, enumConstant.getName(), "L" + intfClass + ";");
|
v.putstatic(intfClass, enumConstant.getName(), "L" + intfClass + ";");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -134,10 +134,18 @@ public class ClassGenTest extends CodegenTestCase {
|
|||||||
|
|
||||||
public void testEnumClass() throws Exception {
|
public void testEnumClass() throws Exception {
|
||||||
loadText("enum class Direction { NORTH; SOUTH; EAST; WEST }");
|
loadText("enum class Direction { NORTH; SOUTH; EAST; WEST }");
|
||||||
System.out.println(generateToText());
|
|
||||||
final Class direction = loadAllClasses(generateClassesInFile()).get("Direction");
|
final Class direction = loadAllClasses(generateClassesInFile()).get("Direction");
|
||||||
final Field north = direction.getField("NORTH");
|
final Field north = direction.getField("NORTH");
|
||||||
assertEquals(direction, north.getType());
|
assertEquals(direction, north.getType());
|
||||||
assertInstanceOf(north.get(null), direction);
|
assertInstanceOf(north.get(null), direction);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testEnumConstantConstructors() throws Exception {
|
||||||
|
loadText("enum class Color(val rgb: Int) { RED: Color(0xFF0000); GREEN: Color(0x00FF00); }");
|
||||||
|
final Class colorClass = loadAllClasses(generateClassesInFile()).get("Color");
|
||||||
|
final Field redField = colorClass.getField("RED");
|
||||||
|
final Object redValue = redField.get(null);
|
||||||
|
final Method rgbMethod = colorClass.getMethod("getRgb");
|
||||||
|
assertEquals(0xFF0000, rgbMethod.invoke(redValue));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user