Delegating to a super constructors, $delegate fields, $this field
This commit is contained in:
@@ -5,10 +5,7 @@ import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.lang.types.ClassDescriptor;
|
||||
import org.jetbrains.jet.lang.types.JetStandardLibrary;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
import org.jetbrains.jet.lang.types.PropertyDescriptor;
|
||||
import org.jetbrains.jet.lang.types.*;
|
||||
import org.objectweb.asm.ClassVisitor;
|
||||
import org.objectweb.asm.MethodVisitor;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
@@ -27,11 +24,15 @@ public class ClassCodegen {
|
||||
private final Project project;
|
||||
private final BindingContext bindingContext;
|
||||
private final Codegens factory;
|
||||
private final JetTypeMapper typeMapper;
|
||||
|
||||
public ClassCodegen(Project project, Codegens factory, BindingContext bindingContext) {
|
||||
this.project = project;
|
||||
this.factory = factory;
|
||||
this.bindingContext = bindingContext;
|
||||
|
||||
final JetStandardLibrary standardLibrary = JetStandardLibrary.getJetStandardLibrary(project);
|
||||
typeMapper = new JetTypeMapper(standardLibrary, bindingContext);
|
||||
}
|
||||
|
||||
public void generate(JetClass aClass) {
|
||||
@@ -158,31 +159,104 @@ public class ClassCodegen {
|
||||
}
|
||||
|
||||
private void generatePrimaryConstructor(JetClass aClass, ClassVisitor v, OwnerKind kind) {
|
||||
ConstructorDescriptor constructorDescriptor = bindingContext.getConstructorDescriptor(aClass);
|
||||
if (constructorDescriptor == null) return;
|
||||
|
||||
ClassDescriptor classDescriptor = bindingContext.getClassDescriptor(aClass);
|
||||
|
||||
Method method = typeMapper.mapConstructorSignature(constructorDescriptor, kind);
|
||||
int flags = Opcodes.ACC_PUBLIC; // TODO
|
||||
Method method = new Method("<init>", Type.VOID_TYPE, new Type[0]);
|
||||
final MethodVisitor mv = v.visitMethod(flags, "<init>", method.getDescriptor(), null, null);
|
||||
mv.visitCode();
|
||||
|
||||
Type[] argTypes = method.getArgumentTypes();
|
||||
List<ValueParameterDescriptor> paramDescrs = constructorDescriptor.getUnsubstitutedValueParameters();
|
||||
|
||||
FrameMap frameMap = new FrameMap();
|
||||
frameMap.enterTemp(); // this
|
||||
|
||||
final InstructionAdapter iv = new InstructionAdapter(mv);
|
||||
String superClass = getSuperClass(aClass, kind);
|
||||
iv.load(0, Type.getType("L" + superClass + ";"));
|
||||
iv.invokespecial(superClass, "<init>", method.getDescriptor());
|
||||
ExpressionCodegen codegen = new ExpressionCodegen(mv, bindingContext, frameMap, typeMapper, Type.VOID_TYPE, classDescriptor, kind);
|
||||
|
||||
final JetStandardLibrary standardLibrary = JetStandardLibrary.getJetStandardLibrary(project);
|
||||
final JetTypeMapper typeMapper = new JetTypeMapper(standardLibrary, bindingContext);
|
||||
ExpressionCodegen codegen = new ExpressionCodegen(mv, bindingContext, frameMap,
|
||||
typeMapper, Type.VOID_TYPE);
|
||||
generateInitializers(aClass, kind, codegen, iv, typeMapper);
|
||||
String classname = JetTypeMapper.jvmName(classDescriptor, kind);
|
||||
if (kind == OwnerKind.DELEGATING_IMPLEMENTATION) {
|
||||
String interfaceDesc = JetTypeMapper.jetInterfaceType(classDescriptor).getDescriptor();
|
||||
v.visitField(Opcodes.ACC_PRIVATE, "$this", interfaceDesc, /*TODO*/null, null);
|
||||
iv.load(1, argTypes[0]);
|
||||
iv.putfield(classname, "$this", interfaceDesc);
|
||||
frameMap.enterTemp();
|
||||
}
|
||||
|
||||
for (int i = 0; i < paramDescrs.size(); i++) {
|
||||
ValueParameterDescriptor parameter = paramDescrs.get(i);
|
||||
frameMap.enter(parameter, argTypes[i].getSize());
|
||||
}
|
||||
|
||||
int n = 0;
|
||||
for (JetDelegationSpecifier specifier : aClass.getDelegationSpecifiers()) {
|
||||
boolean instanceOnStack = pushDelegateInstance(specifier, kind, codegen, iv, n);
|
||||
if (instanceOnStack) {
|
||||
JetType superType = bindingContext.resolveTypeReference(specifier.getTypeReference());
|
||||
ClassDescriptor superClassDescriptor = (ClassDescriptor) superType.getConstructor().getDeclarationDescriptor();
|
||||
String delegateField = "$delegate_" + n;
|
||||
v.visitField(Opcodes.ACC_PRIVATE, delegateField, JetTypeMapper.jvmNameForInterface(superClassDescriptor), /*TODO*/null, null);
|
||||
iv.putfield(classname, delegateField, JetTypeMapper.jetInterfaceType(superClassDescriptor).getDescriptor());
|
||||
}
|
||||
|
||||
n++;
|
||||
}
|
||||
|
||||
generateInitializers(aClass, kind, codegen, iv);
|
||||
|
||||
iv.visitInsn(Opcodes.RETURN);
|
||||
mv.visitMaxs(0, 0);
|
||||
mv.visitEnd();
|
||||
}
|
||||
|
||||
private void generateInitializers(JetClass aClass, OwnerKind kind, ExpressionCodegen codegen, InstructionAdapter iv, JetTypeMapper typeMapper) {
|
||||
private boolean pushDelegateInstance(JetDelegationSpecifier specifier, OwnerKind kind, ExpressionCodegen codegen, InstructionAdapter v, int pos) {
|
||||
boolean instanceOnStack = false;
|
||||
if (specifier instanceof JetDelegatorToSuperCall) {
|
||||
JetDelegatorToSuperCall superCall = (JetDelegatorToSuperCall) specifier;
|
||||
ConstructorDescriptor constructorDescriptor = bindingContext.resolveSuperConstructor(superCall, this);
|
||||
|
||||
ClassDescriptor classDecl = constructorDescriptor.getContainingDeclaration();
|
||||
boolean isDelegating = kind == OwnerKind.DELEGATING_IMPLEMENTATION;
|
||||
Type type = isDelegating ? JetTypeMapper.jetDelegatingImplementationType(classDecl) : JetTypeMapper.jetImplementationType(classDecl);
|
||||
|
||||
if (pos > 0) {
|
||||
if (kind == OwnerKind.DELEGATING_IMPLEMENTATION) {
|
||||
codegen.thisToStack();
|
||||
}
|
||||
}
|
||||
|
||||
Method method = typeMapper.mapConstructorSignature(constructorDescriptor, kind);
|
||||
final Type[] argTypes = method.getArgumentTypes();
|
||||
List<JetArgument> args = superCall.getValueArguments();
|
||||
for (int i = 0, argsSize = args.size(); i < argsSize; i++) {
|
||||
JetArgument arg = args.get(i);
|
||||
codegen.gen(arg.getArgumentExpression(), argTypes[i]);
|
||||
}
|
||||
|
||||
if (pos == 0) {
|
||||
v.load(0, type);
|
||||
}
|
||||
else {
|
||||
v.anew(type);
|
||||
v.dup();
|
||||
instanceOnStack = true;
|
||||
}
|
||||
|
||||
v.invokespecial(type.getClassName(), "<init>", method.getDescriptor());
|
||||
}
|
||||
else if (specifier instanceof JetDelegatorByExpressionSpecifier) {
|
||||
codegen.genToJVMStack(((JetDelegatorByExpressionSpecifier) specifier).getDelegateExpression());
|
||||
instanceOnStack = true;
|
||||
}
|
||||
|
||||
return instanceOnStack;
|
||||
}
|
||||
|
||||
private void generateInitializers(JetClass aClass, OwnerKind kind, ExpressionCodegen codegen, InstructionAdapter iv) {
|
||||
for (JetDeclaration declaration : aClass.getDeclarations()) {
|
||||
if (declaration instanceof JetProperty) {
|
||||
final PropertyDescriptor propertyDescriptor = (PropertyDescriptor) bindingContext.getVariableDescriptor((JetProperty) declaration);
|
||||
@@ -201,7 +275,7 @@ public class ClassCodegen {
|
||||
|
||||
private void generateClassBody(JetClass aClass, ClassVisitor v, OwnerKind kind) {
|
||||
final JetStandardLibrary standardLibrary = JetStandardLibrary.getJetStandardLibrary(project);
|
||||
final FunctionCodegen functionCodegen = new FunctionCodegen(v, standardLibrary, bindingContext);
|
||||
final FunctionCodegen functionCodegen = new FunctionCodegen(aClass, v, standardLibrary, bindingContext);
|
||||
final PropertyCodegen propertyCodegen = new PropertyCodegen(v, standardLibrary, bindingContext, functionCodegen);
|
||||
|
||||
for (JetDeclaration declaration : aClass.getDeclarations()) {
|
||||
|
||||
@@ -35,13 +35,22 @@ public class ExpressionCodegen extends JetVisitor {
|
||||
private final FrameMap myMap;
|
||||
private final JetTypeMapper typeMapper;
|
||||
private final Type returnType;
|
||||
private final ClassDescriptor contextType;
|
||||
private final OwnerKind contextKind;
|
||||
private final BindingContext bindingContext;
|
||||
|
||||
public ExpressionCodegen(MethodVisitor v, BindingContext bindingContext, FrameMap myMap, JetTypeMapper typeMapper,
|
||||
Type returnType) {
|
||||
public ExpressionCodegen(MethodVisitor v,
|
||||
BindingContext bindingContext,
|
||||
FrameMap myMap,
|
||||
JetTypeMapper typeMapper,
|
||||
Type returnType,
|
||||
ClassDescriptor contextType,
|
||||
OwnerKind contextKind) {
|
||||
this.myMap = myMap;
|
||||
this.typeMapper = typeMapper;
|
||||
this.returnType = returnType;
|
||||
this.contextType = contextType;
|
||||
this.contextKind = contextKind;
|
||||
this.v = new InstructionAdapter(v);
|
||||
this.bindingContext = bindingContext;
|
||||
}
|
||||
@@ -51,7 +60,7 @@ public class ExpressionCodegen extends JetVisitor {
|
||||
expr.accept(this);
|
||||
}
|
||||
|
||||
private void gen(JetElement expr, Type type) {
|
||||
public void gen(JetElement expr, Type type) {
|
||||
int oldStackDepth = myStack.size();
|
||||
gen(expr);
|
||||
if (myStack.size() == oldStackDepth+1) {
|
||||
@@ -989,7 +998,7 @@ public class ExpressionCodegen extends JetVisitor {
|
||||
v.anew(type);
|
||||
v.dup();
|
||||
|
||||
Method method = typeMapper.mapConstructorSignature((ConstructorDescriptor) constructorDescriptor);
|
||||
Method method = typeMapper.mapConstructorSignature((ConstructorDescriptor) constructorDescriptor, OwnerKind.IMPLEMENTATION);
|
||||
pushMethodArguments(expression, method);
|
||||
v.invokespecial(JetTypeMapper.jvmNameForImplementation(classDecl), "<init>", method.getDescriptor());
|
||||
myStack.push(StackValue.onStack(type));
|
||||
@@ -1031,6 +1040,27 @@ public class ExpressionCodegen extends JetVisitor {
|
||||
v.athrow();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitThisExpression(JetThisExpression expression) {
|
||||
thisToStack();
|
||||
}
|
||||
|
||||
public void thisToStack() {
|
||||
if (contextKind == OwnerKind.NAMESPACE) {
|
||||
throw new UnsupportedOperationException("Cannot generate this expression in top level context");
|
||||
}
|
||||
|
||||
if (contextKind == OwnerKind.IMPLEMENTATION) {
|
||||
v.load(0, JetTypeMapper.jetImplementationType(contextType));
|
||||
}
|
||||
else if (contextKind == OwnerKind.DELEGATING_IMPLEMENTATION) {
|
||||
v.getfield(JetTypeMapper.jvmName(contextType, contextKind), "$this", JetTypeMapper.jetInterfaceType(contextType).getDescriptor());
|
||||
}
|
||||
else {
|
||||
throw new UnsupportedOperationException("Unknown kind: " + contextKind);
|
||||
}
|
||||
}
|
||||
|
||||
private static class CompilationException extends RuntimeException {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,34 +15,18 @@ import java.util.List;
|
||||
* @author max
|
||||
*/
|
||||
public class FunctionCodegen {
|
||||
private final JetDeclaration owner;
|
||||
private final ClassVisitor v;
|
||||
private final BindingContext bindingContext;
|
||||
private final JetStandardLibrary standardLibrary;
|
||||
private final JetTypeMapper typeMapper;
|
||||
|
||||
public FunctionCodegen(ClassVisitor v, JetStandardLibrary standardLibrary, BindingContext bindingContext) {
|
||||
public FunctionCodegen(JetDeclaration owner, ClassVisitor v, JetStandardLibrary standardLibrary, BindingContext bindingContext) {
|
||||
this.owner = owner;
|
||||
this.v = v;
|
||||
this.bindingContext = bindingContext;
|
||||
this.standardLibrary = standardLibrary;
|
||||
typeMapper = new JetTypeMapper(standardLibrary, bindingContext);
|
||||
}
|
||||
|
||||
public void genInNamespace(JetFunction f) {
|
||||
gen(f, OwnerKind.NAMESPACE);
|
||||
}
|
||||
|
||||
public void genInInterface(JetFunction f) {
|
||||
gen(f, OwnerKind.INTERFACE);
|
||||
}
|
||||
|
||||
public void genInImplementation(JetFunction f) {
|
||||
|
||||
}
|
||||
|
||||
public void genInDelegatingImplementation(JetFunction f) {
|
||||
|
||||
}
|
||||
|
||||
public void gen(JetFunction f, OwnerKind kind) {
|
||||
Method method = typeMapper.mapSignature(f);
|
||||
List<ValueParameterDescriptor> paramDescrs = bindingContext.getFunctionDescriptor(f).getUnsubstitutedValueParameters();
|
||||
@@ -59,6 +43,8 @@ public class FunctionCodegen {
|
||||
boolean isAbstract = kind == OwnerKind.INTERFACE || bodyExpression == null;
|
||||
if (isAbstract) flags |= Opcodes.ACC_ABSTRACT;
|
||||
|
||||
ClassDescriptor ownerClass = owner instanceof JetClass ? bindingContext.getClassDescriptor((JetClass) owner) : null;
|
||||
|
||||
final MethodVisitor mv = v.visitMethod(flags, jvmSignature.getName(), jvmSignature.getDescriptor(), null, null);
|
||||
if (kind != OwnerKind.INTERFACE) {
|
||||
mv.visitCode();
|
||||
@@ -74,7 +60,7 @@ public class FunctionCodegen {
|
||||
frameMap.enter(parameter, argTypes[i].getSize());
|
||||
}
|
||||
|
||||
ExpressionCodegen codegen = new ExpressionCodegen(mv, bindingContext, frameMap, typeMapper, jvmSignature.getReturnType());
|
||||
ExpressionCodegen codegen = new ExpressionCodegen(mv, bindingContext, frameMap, typeMapper, jvmSignature.getReturnType(), ownerClass, kind);
|
||||
bodyExpression.accept(codegen);
|
||||
generateReturn(mv, bodyExpression, codegen);
|
||||
mv.visitMaxs(0, 0);
|
||||
|
||||
@@ -31,6 +31,22 @@ public class JetTypeMapper {
|
||||
return psiClass.getQualifiedName().replace(".", "/");
|
||||
}
|
||||
|
||||
static String jvmName(ClassDescriptor jetClass, OwnerKind kind) {
|
||||
switch (kind) {
|
||||
|
||||
case INTERFACE:
|
||||
return jvmNameForInterface(jetClass);
|
||||
case IMPLEMENTATION:
|
||||
return jvmNameForImplementation(jetClass);
|
||||
case DELEGATING_IMPLEMENTATION:
|
||||
return jvmNameForDelegatingImplementation(jetClass);
|
||||
|
||||
default:
|
||||
assert false : "Unsuitable kind";
|
||||
return "java/lang/Object";
|
||||
}
|
||||
}
|
||||
|
||||
static Type psiClassType(PsiClass psiClass) {
|
||||
return Type.getType("L" + jvmName(psiClass) + ";");
|
||||
}
|
||||
@@ -43,6 +59,10 @@ public class JetTypeMapper {
|
||||
return Type.getType("L" + jvmNameForImplementation(classDescriptor) + ";");
|
||||
}
|
||||
|
||||
static Type jetDelegatingImplementationType(ClassDescriptor classDescriptor) {
|
||||
return Type.getType("L" + jvmNameForDelegatingImplementation(classDescriptor) + ";");
|
||||
}
|
||||
|
||||
static String jvmName(JetNamespace namespace) {
|
||||
return NamespaceCodegen.getJVMClassName(namespace.getFQName());
|
||||
}
|
||||
@@ -187,11 +207,18 @@ public class JetTypeMapper {
|
||||
return new Method(PropertyCodegen.setterName(descriptor.getName()), Type.VOID_TYPE, new Type[] { paramType });
|
||||
}
|
||||
|
||||
public Method mapConstructorSignature(ConstructorDescriptor descriptor) {
|
||||
public Method mapConstructorSignature(ConstructorDescriptor descriptor, OwnerKind kind) {
|
||||
boolean delegate = kind == OwnerKind.DELEGATING_IMPLEMENTATION;
|
||||
List<ValueParameterDescriptor> parameters = descriptor.getUnsubstitutedValueParameters();
|
||||
Type[] parameterTypes = new Type[parameters.size()];
|
||||
for (int i = 0; i < parameters.size(); i++) {
|
||||
parameterTypes[i] = mapType(parameters.get(i).getOutType());
|
||||
int count = parameters.size();
|
||||
int first = delegate ? 1 : 0;
|
||||
Type[] parameterTypes = new Type[count + first];
|
||||
if (delegate) {
|
||||
parameterTypes[0] = jetInterfaceType(descriptor.getContainingDeclaration());
|
||||
}
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
parameterTypes[i + first] = mapType(parameters.get(i).getOutType());
|
||||
}
|
||||
return new Method("<init>", Type.VOID_TYPE, parameterTypes);
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ public class NamespaceCodegen {
|
||||
BindingContext bindingContext = AnalyzingUtils.analyzeNamespace(namespace, ErrorHandler.THROW_EXCEPTION);
|
||||
|
||||
final JetStandardLibrary standardLibrary = JetStandardLibrary.getJetStandardLibrary(project);
|
||||
final FunctionCodegen functionCodegen = new FunctionCodegen(v, standardLibrary, bindingContext);
|
||||
final FunctionCodegen functionCodegen = new FunctionCodegen(namespace, v, standardLibrary, bindingContext);
|
||||
final PropertyCodegen propertyCodegen = new PropertyCodegen(v, standardLibrary, bindingContext, functionCodegen);
|
||||
final ClassCodegen classCodegen = codegens.forClass(bindingContext);
|
||||
|
||||
@@ -51,10 +51,10 @@ public class NamespaceCodegen {
|
||||
|
||||
for (JetDeclaration declaration : namespace.getDeclarations()) {
|
||||
if (declaration instanceof JetProperty) {
|
||||
propertyCodegen.genInNamespace((JetProperty) declaration);
|
||||
propertyCodegen.gen((JetProperty) declaration, OwnerKind.NAMESPACE);
|
||||
}
|
||||
else if (declaration instanceof JetFunction) {
|
||||
functionCodegen.genInNamespace((JetFunction) declaration);
|
||||
functionCodegen.gen((JetFunction) declaration, OwnerKind.NAMESPACE);
|
||||
}
|
||||
else if (declaration instanceof JetClass) {
|
||||
classCodegen.generate((JetClass) declaration);
|
||||
@@ -70,8 +70,7 @@ public class NamespaceCodegen {
|
||||
|
||||
FrameMap frameMap = new FrameMap();
|
||||
JetTypeMapper typeMapper = new JetTypeMapper(JetStandardLibrary.getJetStandardLibrary(namespace.getProject()), bindingContext);
|
||||
ExpressionCodegen codegen = new ExpressionCodegen(mv, bindingContext, frameMap,
|
||||
typeMapper, Type.VOID_TYPE);
|
||||
ExpressionCodegen codegen = new ExpressionCodegen(mv, bindingContext, frameMap, typeMapper, Type.VOID_TYPE, null, OwnerKind.NAMESPACE);
|
||||
|
||||
for (JetDeclaration declaration : namespace.getDeclarations()) {
|
||||
if (declaration instanceof JetProperty) {
|
||||
|
||||
@@ -29,22 +29,6 @@ public class PropertyCodegen {
|
||||
this.mapper = new JetTypeMapper(standardLibrary, context);
|
||||
}
|
||||
|
||||
public void genInNamespace(JetProperty p) {
|
||||
gen(p, OwnerKind.NAMESPACE);
|
||||
}
|
||||
|
||||
public void genInInterface(JetProperty p) {
|
||||
|
||||
}
|
||||
|
||||
public void genInImplementation(JetProperty p) {
|
||||
gen(p, OwnerKind.IMPLEMENTATION);
|
||||
}
|
||||
|
||||
public void genInDelegatingImplementation(JetProperty p) {
|
||||
gen(p, OwnerKind.DELEGATING_IMPLEMENTATION);
|
||||
}
|
||||
|
||||
public void gen(JetProperty p, OwnerKind kind) {
|
||||
final VariableDescriptor descriptor = context.getVariableDescriptor(p);
|
||||
if (!(descriptor instanceof PropertyDescriptor)) {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package org.jetbrains.jet.lang.resolve;
|
||||
|
||||
import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.jet.codegen.ClassCodegen;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.lang.types.*;
|
||||
|
||||
@@ -29,4 +30,6 @@ public interface BindingContext {
|
||||
boolean isBlock(JetFunctionLiteralExpression expression);
|
||||
boolean isStatement(JetExpression expression);
|
||||
boolean hasBackingField(PropertyDescriptor propertyDescriptor);
|
||||
|
||||
ConstructorDescriptor resolveSuperConstructor(JetDelegatorToSuperCall superCall, ClassCodegen classCodegen);
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package org.jetbrains.jet.lang.resolve;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.codegen.ClassCodegen;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.lang.types.*;
|
||||
|
||||
@@ -197,4 +198,15 @@ public class BindingTraceContext implements BindingContext, BindingTrace {
|
||||
}
|
||||
return fieldMentionedInAccessor.contains(propertyDescriptor);
|
||||
}
|
||||
|
||||
public ConstructorDescriptor resolveSuperConstructor(JetDelegatorToSuperCall superCall, ClassCodegen classCodegen) {
|
||||
JetTypeReference typeReference = superCall.getTypeReference();
|
||||
if (typeReference == null) return null;
|
||||
|
||||
JetTypeElement typeElement = typeReference.getTypeElement();
|
||||
if (!(typeElement instanceof JetUserType)) return null;
|
||||
|
||||
DeclarationDescriptor descriptor = resolveReferenceExpression(((JetUserType) typeElement).getReferenceExpression());
|
||||
return descriptor instanceof ConstructorDescriptor ? (ConstructorDescriptor) descriptor : null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
class X(x : Int) {}
|
||||
class Y(y : Int) {}
|
||||
|
||||
class Point(x : Int, y : Int) : X(x), Y(y) {}
|
||||
|
||||
class Abstract {}
|
||||
|
||||
class P1(x : Int, y : Y) : Abstract, X(x), Y by y {}
|
||||
class P2(x : Int, y : Y) : X(x), Abstract, Y by y {}
|
||||
class P3(x : Int, y : Y) : X(x), Y by y, Abstract {}
|
||||
class P4(x : Int, y : Y) : Y by y, Abstract, X(x) {}
|
||||
@@ -23,6 +23,15 @@ public class ClassGenTest extends CodegenTestCase {
|
||||
final Class aClass = loadClass("Foo", generateClassesInFile());
|
||||
checkInterface(aClass, List.class);
|
||||
}
|
||||
public void testArrayInheritance() throws Exception {
|
||||
loadFile("inheritance.jet");
|
||||
System.out.println(generateToText());
|
||||
|
||||
/*
|
||||
final Class aClass = loadClass("Foo", generateClassesInFile());
|
||||
checkInterface(aClass, List.class);
|
||||
*/
|
||||
}
|
||||
|
||||
private static void checkInterface(Class aClass, Class ifs) {
|
||||
for (Class anInterface : aClass.getInterfaces()) {
|
||||
|
||||
Reference in New Issue
Block a user