simplest case of enum classes
This commit is contained in:
@@ -25,13 +25,15 @@ public class ClassCodegen {
|
||||
else {
|
||||
generateInterface(parentContext, aClass);
|
||||
generateImplementation(parentContext, aClass, OwnerKind.IMPLEMENTATION);
|
||||
generateImplementation(parentContext, aClass, OwnerKind.DELEGATING_IMPLEMENTATION);
|
||||
if (!ImplementationBodyCodegen.isEnum(aClass)) {
|
||||
generateImplementation(parentContext, aClass, OwnerKind.DELEGATING_IMPLEMENTATION);
|
||||
}
|
||||
}
|
||||
|
||||
ClassDescriptor descriptor = state.getBindingContext().getClassDescriptor(aClass);
|
||||
final ClassContext contextForInners = parentContext.intoClass(descriptor, OwnerKind.IMPLEMENTATION);
|
||||
for (JetDeclaration declaration : aClass.getDeclarations()) {
|
||||
if (declaration instanceof JetClass) {
|
||||
if (declaration instanceof JetClass && !(declaration instanceof JetEnumEntry)) {
|
||||
generate(contextForInners, (JetClass) declaration);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -146,11 +146,11 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
|
||||
protected void generatePrimaryConstructor() {
|
||||
ConstructorDescriptor constructorDescriptor = state.getBindingContext().getConstructorDescriptor((JetElement) myClass);
|
||||
if (constructorDescriptor == null && !(myClass instanceof JetObjectDeclaration)) return;
|
||||
if (constructorDescriptor == null && !(myClass instanceof JetObjectDeclaration) && !isEnum(myClass)) return;
|
||||
|
||||
Method method;
|
||||
CallableMethod callableMethod;
|
||||
if (myClass instanceof JetObjectDeclaration) {
|
||||
if (myClass instanceof JetObjectDeclaration || isEnum(myClass)) {
|
||||
method = new Method("<init>", Type.VOID_TYPE, new Type[0]);
|
||||
callableMethod = new CallableMethod("", method, Opcodes.INVOKESPECIAL, Collections.<Type>emptyList());
|
||||
}
|
||||
@@ -278,6 +278,11 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
mv.visitEnd();
|
||||
}
|
||||
|
||||
static boolean isEnum(JetClassOrObject myClass) {
|
||||
final JetModifierList modifierList = myClass.getModifierList();
|
||||
return modifierList != null && modifierList.hasModifier(JetTokens.ENUM_KEYWORD);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private ClassDescriptor getOuterClassDescriptor() {
|
||||
if (myClass.getParent() instanceof JetClassObject) {
|
||||
|
||||
@@ -4,12 +4,17 @@ import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
||||
import org.jetbrains.jet.lang.psi.JetClassOrObject;
|
||||
import org.jetbrains.jet.lang.psi.JetDeclaration;
|
||||
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.types.JetType;
|
||||
import org.objectweb.asm.ClassVisitor;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
import org.objectweb.asm.Type;
|
||||
import org.objectweb.asm.commons.InstructionAdapter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
@@ -18,6 +23,8 @@ import java.util.Set;
|
||||
* @author yole
|
||||
*/
|
||||
public class InterfaceBodyCodegen extends ClassBodyCodegen {
|
||||
private final List<JetEnumEntry> myEnumConstants = new ArrayList<JetEnumEntry>();
|
||||
|
||||
public InterfaceBodyCodegen(JetClassOrObject aClass, ClassContext context, ClassVisitor v, GenerationState state) {
|
||||
super(aClass, context, v, state);
|
||||
assert context.getContextKind() == OwnerKind.INTERFACE;
|
||||
@@ -73,4 +80,37 @@ public class InterfaceBodyCodegen extends ClassBodyCodegen {
|
||||
}
|
||||
return superInterfaces;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void generateDeclaration(PropertyCodegen propertyCodegen, JetDeclaration declaration, FunctionCodegen functionCodegen) {
|
||||
if (declaration instanceof JetEnumEntry && !((JetEnumEntry) declaration).hasPrimaryConstructor()) {
|
||||
String name = declaration.getName();
|
||||
final String desc = "L" + state.getTypeMapper().jvmName(descriptor, OwnerKind.INTERFACE) + ";";
|
||||
v.visitField(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC | Opcodes.ACC_FINAL, name, desc, null, null);
|
||||
if (myEnumConstants.isEmpty()) {
|
||||
staticInitializerChunks.add(new CodeChunk() {
|
||||
@Override
|
||||
public void generate(InstructionAdapter v) {
|
||||
initializeEnumConstants(v);
|
||||
}
|
||||
});
|
||||
}
|
||||
myEnumConstants.add((JetEnumEntry) declaration);
|
||||
}
|
||||
else {
|
||||
super.generateDeclaration(propertyCodegen, declaration, functionCodegen);
|
||||
}
|
||||
}
|
||||
|
||||
private void initializeEnumConstants(InstructionAdapter v) {
|
||||
for (JetEnumEntry enumConstant : myEnumConstants) {
|
||||
// TODO type and constructor parameters
|
||||
String intfClass = state.getTypeMapper().jvmName(descriptor, OwnerKind.INTERFACE);
|
||||
String implClass = state.getTypeMapper().jvmName(descriptor, OwnerKind.IMPLEMENTATION);
|
||||
v.anew(Type.getObjectType(implClass));
|
||||
v.dup();
|
||||
v.invokespecial(implClass, "<init>", "()V");
|
||||
v.putstatic(intfClass, enumConstant.getName(), "L" + intfClass + ";");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package org.jetbrains.jet.codegen;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.List;
|
||||
@@ -130,4 +131,13 @@ public class ClassGenTest extends CodegenTestCase {
|
||||
Object result = method.invoke(null);
|
||||
assertInstanceOf(result, Runnable.class);
|
||||
}
|
||||
|
||||
public void testEnumClass() throws Exception {
|
||||
loadText("enum class Direction { NORTH; SOUTH; EAST; WEST }");
|
||||
System.out.println(generateToText());
|
||||
final Class direction = loadAllClasses(generateClassesInFile()).get("Direction");
|
||||
final Field north = direction.getField("NORTH");
|
||||
assertEquals(direction, north.getType());
|
||||
assertInstanceOf(north.get(null), direction);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user