removing unnneded InstructionAdapterEx
This commit is contained in:
@@ -89,6 +89,7 @@ public abstract class ClassBodyCodegen {
|
|||||||
propertyCodegen.generateDefaultSetter(propertyDescriptor, Opcodes.ACC_PUBLIC);
|
propertyCodegen.generateDefaultSetter(propertyDescriptor, Opcodes.ACC_PUBLIC);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//noinspection ConstantConditions
|
||||||
if (!(kind instanceof OwnerKind.DelegateKind) && kind != OwnerKind.INTERFACE && state.getBindingContext().get(BindingContext.BACKING_FIELD_REQUIRED, propertyDescriptor)) {
|
if (!(kind instanceof OwnerKind.DelegateKind) && kind != OwnerKind.INTERFACE && state.getBindingContext().get(BindingContext.BACKING_FIELD_REQUIRED, propertyDescriptor)) {
|
||||||
v.visitField(Opcodes.ACC_PRIVATE, p.getName(), state.getTypeMapper().mapType(propertyDescriptor.getOutType()).getDescriptor(), null, null);
|
v.visitField(Opcodes.ACC_PRIVATE, p.getName(), state.getTypeMapper().mapType(propertyDescriptor.getOutType()).getDescriptor(), null, null);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,13 +20,7 @@ public class ClassCodegen {
|
|||||||
public void generate(ClassContext parentContext, JetClassOrObject aClass) {
|
public void generate(ClassContext parentContext, JetClassOrObject aClass) {
|
||||||
GenerationState.prepareAnonymousClasses((JetElement) aClass, state.getTypeMapper());
|
GenerationState.prepareAnonymousClasses((JetElement) aClass, state.getTypeMapper());
|
||||||
|
|
||||||
if (aClass instanceof JetObjectDeclaration) {
|
generateImplementation(parentContext, aClass, OwnerKind.IMPLEMENTATION);
|
||||||
generateImplementation(parentContext, aClass, OwnerKind.IMPLEMENTATION);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
generateInterface(parentContext, aClass);
|
|
||||||
generateImplementation(parentContext, aClass, OwnerKind.IMPLEMENTATION);
|
|
||||||
}
|
|
||||||
|
|
||||||
ClassDescriptor descriptor = state.getBindingContext().get(BindingContext.CLASS, aClass);
|
ClassDescriptor descriptor = state.getBindingContext().get(BindingContext.CLASS, aClass);
|
||||||
final ClassContext contextForInners = parentContext.intoClass(descriptor, OwnerKind.IMPLEMENTATION);
|
final ClassContext contextForInners = parentContext.intoClass(descriptor, OwnerKind.IMPLEMENTATION);
|
||||||
@@ -37,17 +31,9 @@ public class ClassCodegen {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void generateInterface(ClassContext parentContext, JetClassOrObject aClass) {
|
|
||||||
ClassDescriptor descriptor = state.getBindingContext().get(BindingContext.CLASS, aClass);
|
|
||||||
final ClassVisitor visitor = state.forClassInterface(descriptor);
|
|
||||||
new InterfaceBodyCodegen(aClass, parentContext.intoClass(descriptor, OwnerKind.INTERFACE), visitor, state).generate();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void generateImplementation(ClassContext parentContext, JetClassOrObject aClass, OwnerKind kind) {
|
private void generateImplementation(ClassContext parentContext, JetClassOrObject aClass, OwnerKind kind) {
|
||||||
ClassDescriptor descriptor = state.getBindingContext().get(BindingContext.CLASS, aClass);
|
ClassDescriptor descriptor = state.getBindingContext().get(BindingContext.CLASS, aClass);
|
||||||
ClassVisitor v = kind == OwnerKind.IMPLEMENTATION
|
ClassVisitor v = state.forClassImplementation(descriptor);
|
||||||
? state.forClassImplementation(descriptor)
|
|
||||||
: state.forClassDelegatingImplementation(descriptor);
|
|
||||||
new ImplementationBodyCodegen(aClass, parentContext.intoClass(descriptor, kind), v, state).generate();
|
new ImplementationBodyCodegen(aClass, parentContext.intoClass(descriptor, kind), v, state).generate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -154,7 +154,7 @@ public class ClassContext {
|
|||||||
public Type enclosingClassType(JetTypeMapper mapper) {
|
public Type enclosingClassType(JetTypeMapper mapper) {
|
||||||
DeclarationDescriptor descriptor = getContextDescriptor();
|
DeclarationDescriptor descriptor = getContextDescriptor();
|
||||||
if (descriptor instanceof ClassDescriptor) {
|
if (descriptor instanceof ClassDescriptor) {
|
||||||
return Type.getObjectType(mapper.jvmName((ClassDescriptor) descriptor, OwnerKind.INTERFACE));
|
return Type.getObjectType(mapper.jvmName((ClassDescriptor) descriptor, OwnerKind.IMPLEMENTATION));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (descriptor instanceof NamespaceDescriptor) {
|
if (descriptor instanceof NamespaceDescriptor) {
|
||||||
|
|||||||
@@ -730,6 +730,13 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
}
|
}
|
||||||
JetType receiverType = bindingContext.get(BindingContext.EXPRESSION_TYPE, r);
|
JetType receiverType = bindingContext.get(BindingContext.EXPRESSION_TYPE, r);
|
||||||
receiver.put(receiverType != null ? typeMapper.mapType(receiverType) : JetTypeMapper.TYPE_OBJECT, v);
|
receiver.put(receiverType != null ? typeMapper.mapType(receiverType) : JetTypeMapper.TYPE_OBJECT, v);
|
||||||
|
if(receiverType != null) {
|
||||||
|
ClassDescriptor propReceiverDescriptor = (ClassDescriptor) propertyDescriptor.getContainingDeclaration();
|
||||||
|
if(!TypeUtils.isInterface(propReceiverDescriptor, bindingContext) && TypeUtils.isInterface(receiverType.getConstructor().getDeclarationDescriptor(), bindingContext)) {
|
||||||
|
// I hope it happens only in case of required super class for traits
|
||||||
|
v.checkcast(typeMapper.mapType(propReceiverDescriptor.getDefaultType()));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return iValue;
|
return iValue;
|
||||||
}
|
}
|
||||||
@@ -752,8 +759,11 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (descriptor instanceof TypeParameterDescriptor) {
|
else if (descriptor instanceof TypeParameterDescriptor) {
|
||||||
loadTypeParameterTypeInfo((TypeParameterDescriptor) descriptor);
|
TypeParameterDescriptor typeParameterDescriptor = (TypeParameterDescriptor) descriptor;
|
||||||
|
loadTypeParameterTypeInfo(typeParameterDescriptor);
|
||||||
v.invokevirtual("jet/typeinfo/TypeInfo", "getClassObject", "()Ljava/lang/Object;");
|
v.invokevirtual("jet/typeinfo/TypeInfo", "getClassObject", "()Ljava/lang/Object;");
|
||||||
|
v.checkcast(typeMapper.mapType(typeParameterDescriptor.getClassObjectType()));
|
||||||
|
|
||||||
return StackValue.onStack(OBJECT_TYPE);
|
return StackValue.onStack(OBJECT_TYPE);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -786,14 +796,20 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
isInterface = false;
|
isInterface = false;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
owner = typeMapper.getOwner(functionDescriptor, OwnerKind.INTERFACE);
|
owner = typeMapper.getOwner(functionDescriptor, OwnerKind.IMPLEMENTATION);
|
||||||
if(containingDeclaration instanceof JavaClassDescriptor) {
|
if(containingDeclaration instanceof JavaClassDescriptor) {
|
||||||
PsiClass psiElement = (PsiClass) bindingContext.get(BindingContext.DESCRIPTOR_TO_DECLARATION, containingDeclaration);
|
PsiClass psiElement = (PsiClass) bindingContext.get(BindingContext.DESCRIPTOR_TO_DECLARATION, containingDeclaration);
|
||||||
assert psiElement != null;
|
assert psiElement != null;
|
||||||
isInterface = psiElement.isInterface();
|
isInterface = psiElement.isInterface();
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
isInterface = !(containingDeclaration instanceof ClassDescriptor && ((ClassDescriptor) containingDeclaration).getKind() == ClassKind.OBJECT);
|
if(containingDeclaration instanceof ClassDescriptor && ((ClassDescriptor) containingDeclaration).getKind() == ClassKind.OBJECT)
|
||||||
|
isInterface = false;
|
||||||
|
else {
|
||||||
|
JetClass jetClass = (JetClass) bindingContext.get(BindingContext.DESCRIPTOR_TO_DECLARATION, containingDeclaration);
|
||||||
|
isInterface = jetClass == null || jetClass.isTrait();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
v.visitMethodInsn(isStatic ? Opcodes.INVOKESTATIC : isInterface ? Opcodes.INVOKEINTERFACE : Opcodes.INVOKEVIRTUAL, owner, functionDescriptor.getName(), typeMapper.mapSignature(functionDescriptor.getName(),functionDescriptor).getDescriptor());
|
v.visitMethodInsn(isStatic ? Opcodes.INVOKESTATIC : isInterface ? Opcodes.INVOKEINTERFACE : Opcodes.INVOKEVIRTUAL, owner, functionDescriptor.getName(), typeMapper.mapSignature(functionDescriptor.getName(),functionDescriptor).getDescriptor());
|
||||||
@@ -827,8 +843,13 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
isInterface = false;
|
isInterface = false;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
owner = typeMapper.getOwner(propertyDescriptor, OwnerKind.INTERFACE);
|
owner = typeMapper.getOwner(propertyDescriptor, OwnerKind.IMPLEMENTATION);
|
||||||
isInterface = !(containingDeclaration instanceof ClassDescriptor && ((ClassDescriptor) containingDeclaration).getKind() == ClassKind.OBJECT);
|
if(containingDeclaration instanceof ClassDescriptor && ((ClassDescriptor) containingDeclaration).getKind() == ClassKind.OBJECT)
|
||||||
|
isInterface = false;
|
||||||
|
else {
|
||||||
|
JetClass jetClass = (JetClass) bindingContext.get(BindingContext.DESCRIPTOR_TO_DECLARATION, containingDeclaration);
|
||||||
|
isInterface = jetClass == null || jetClass.isTrait();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return StackValue.property(propertyDescriptor.getName(), owner, typeMapper.mapType(propertyDescriptor.getOutType()), isStatic, isInterface, getter, setter);
|
return StackValue.property(propertyDescriptor.getName(), owner, typeMapper.mapType(propertyDescriptor.getOutType()), isStatic, isInterface, getter, setter);
|
||||||
@@ -971,7 +992,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
|
|
||||||
for (JetType superType : allSuperTypes) {
|
for (JetType superType : allSuperTypes) {
|
||||||
final DeclarationDescriptor descriptor = superType.getConstructor().getDeclarationDescriptor();
|
final DeclarationDescriptor descriptor = superType.getConstructor().getDeclarationDescriptor();
|
||||||
if (descriptor != null && superOriginal == descriptor.getOriginal()) {
|
if (descriptor != null && superOriginal.equals(descriptor.getOriginal())) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1795,7 +1816,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
if (!(descriptor instanceof ClassDescriptor)) {
|
if (!(descriptor instanceof ClassDescriptor)) {
|
||||||
throw new UnsupportedOperationException("don't know how to handle non-class types in as/as?");
|
throw new UnsupportedOperationException("don't know how to handle non-class types in as/as?");
|
||||||
}
|
}
|
||||||
Type type = JetTypeMapper.boxType(typeMapper.mapType(jetType, OwnerKind.INTERFACE));
|
Type type = JetTypeMapper.boxType(typeMapper.mapType(jetType));
|
||||||
generateInstanceOf(StackValue.expression(OBJECT_TYPE, expression.getLeft(), this), jetType, true);
|
generateInstanceOf(StackValue.expression(OBJECT_TYPE, expression.getLeft(), this), jetType, true);
|
||||||
Label isInstance = new Label();
|
Label isInstance = new Label();
|
||||||
v.ifne(isInstance);
|
v.ifne(isInstance);
|
||||||
@@ -1921,7 +1942,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
if (leaveExpressionOnStack) {
|
if (leaveExpressionOnStack) {
|
||||||
v.dup();
|
v.dup();
|
||||||
}
|
}
|
||||||
Type type = JetTypeMapper.boxType(typeMapper.mapType(jetType, OwnerKind.INTERFACE));
|
Type type = JetTypeMapper.boxType(typeMapper.mapType(jetType));
|
||||||
if(jetType.isNullable()) {
|
if(jetType.isNullable()) {
|
||||||
Label nope = new Label();
|
Label nope = new Label();
|
||||||
Label end = new Label();
|
Label end = new Label();
|
||||||
@@ -1967,7 +1988,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final Type jvmType = typeMapper.mapType(jetType, OwnerKind.INTERFACE);
|
final Type jvmType = typeMapper.mapType(jetType);
|
||||||
|
|
||||||
v.aconst(jvmType);
|
v.aconst(jvmType);
|
||||||
v.iconst(jetType.isNullable()?1:0);
|
v.iconst(jetType.isNullable()?1:0);
|
||||||
|
|||||||
@@ -89,15 +89,11 @@ public class FunctionCodegen {
|
|||||||
boolean isStatic = kind == OwnerKind.NAMESPACE;
|
boolean isStatic = kind == OwnerKind.NAMESPACE;
|
||||||
if (isStatic) flags |= Opcodes.ACC_STATIC;
|
if (isStatic) flags |= Opcodes.ACC_STATIC;
|
||||||
|
|
||||||
boolean isAbstract = kind == OwnerKind.INTERFACE || bodyExpressions == null;
|
boolean isAbstract = bodyExpressions == null;
|
||||||
if (isAbstract) flags |= Opcodes.ACC_ABSTRACT;
|
if (isAbstract) flags |= Opcodes.ACC_ABSTRACT;
|
||||||
|
|
||||||
if (isAbstract && (kind == OwnerKind.IMPLEMENTATION )) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
final MethodVisitor mv = v.visitMethod(flags, jvmSignature.getName(), jvmSignature.getDescriptor(), null, null);
|
final MethodVisitor mv = v.visitMethod(flags, jvmSignature.getName(), jvmSignature.getDescriptor(), null, null);
|
||||||
if (kind != OwnerKind.INTERFACE) {
|
if (!isAbstract) {
|
||||||
mv.visitCode();
|
mv.visitCode();
|
||||||
FrameMap frameMap = context.prepareFrame();
|
FrameMap frameMap = context.prepareFrame();
|
||||||
|
|
||||||
|
|||||||
@@ -22,29 +22,77 @@ import java.util.*;
|
|||||||
/**
|
/**
|
||||||
* @author max
|
* @author max
|
||||||
* @author yole
|
* @author yole
|
||||||
|
* @author alex.tkachman
|
||||||
*/
|
*/
|
||||||
public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||||
|
private JetDelegationSpecifier superCall;
|
||||||
|
private String superClass = "java/lang/Object";
|
||||||
|
|
||||||
public ImplementationBodyCodegen(JetClassOrObject aClass, ClassContext context, ClassVisitor v, GenerationState state) {
|
public ImplementationBodyCodegen(JetClassOrObject aClass, ClassContext context, ClassVisitor v, GenerationState state) {
|
||||||
super(aClass, context, v, state);
|
super(aClass, context, v, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Set<String> getSuperInterfaces(JetClassOrObject aClass) {
|
||||||
|
List<JetDelegationSpecifier> delegationSpecifiers = aClass.getDelegationSpecifiers();
|
||||||
|
String superClassName = null;
|
||||||
|
Set<String> superInterfaces = new LinkedHashSet<String>();
|
||||||
|
|
||||||
|
for (JetDelegationSpecifier specifier : delegationSpecifiers) {
|
||||||
|
JetType superType = state.getBindingContext().get(BindingContext.TYPE, specifier.getTypeReference());
|
||||||
|
ClassDescriptor superClassDescriptor = (ClassDescriptor) superType.getConstructor().getDeclarationDescriptor();
|
||||||
|
PsiElement superPsi = state.getBindingContext().get(BindingContext.DESCRIPTOR_TO_DECLARATION, superClassDescriptor);
|
||||||
|
|
||||||
|
if (superPsi instanceof PsiClass) {
|
||||||
|
PsiClass psiClass = (PsiClass) superPsi;
|
||||||
|
String fqn = psiClass.getQualifiedName();
|
||||||
|
if (psiClass.isInterface()) {
|
||||||
|
superInterfaces.add(fqn.replace('.', '/'));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (superClassName == null) {
|
||||||
|
superClassName = fqn.replace('.', '/');
|
||||||
|
|
||||||
|
while (psiClass != null) {
|
||||||
|
for (PsiClass ifs : psiClass.getInterfaces()) {
|
||||||
|
superInterfaces.add(ifs.getQualifiedName().replace('.', '/'));
|
||||||
|
}
|
||||||
|
psiClass = psiClass.getSuperClass();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw new RuntimeException("Cannot determine single class to inherit from");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if(superPsi == null || ((JetClass)superPsi).isTrait())
|
||||||
|
superInterfaces.add(JetTypeMapper.jvmNameForInterface(superClassDescriptor));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return superInterfaces;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void generateDeclaration() {
|
protected void generateDeclaration() {
|
||||||
String superClass = getSuperClass();
|
getSuperClass();
|
||||||
|
|
||||||
List<String> interfaces = new ArrayList<String>();
|
List<String> interfaces = new ArrayList<String>();
|
||||||
interfaces.add("jet/JetObject");
|
interfaces.add("jet/JetObject");
|
||||||
if (!(myClass instanceof JetObjectDeclaration)) {
|
interfaces.addAll(getSuperInterfaces(myClass));
|
||||||
interfaces.add(JetTypeMapper.jvmNameForInterface(descriptor));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
interfaces.addAll(InterfaceBodyCodegen.getSuperInterfaces(myClass, state.getBindingContext()));
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean isAbstract = myClass instanceof JetClass && ((JetClass) myClass).hasModifier(JetTokens.ABSTRACT_KEYWORD);
|
boolean isAbstract = false;
|
||||||
|
boolean isInterface = false;
|
||||||
|
if(myClass instanceof JetClass) {
|
||||||
|
if(((JetClass) myClass).hasModifier(JetTokens.ABSTRACT_KEYWORD))
|
||||||
|
isAbstract = true;
|
||||||
|
if(((JetClass) myClass).isTrait()) {
|
||||||
|
isAbstract = true;
|
||||||
|
isInterface = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
v.visit(Opcodes.V1_6,
|
v.visit(Opcodes.V1_6,
|
||||||
Opcodes.ACC_PUBLIC | (isAbstract ? Opcodes.ACC_ABSTRACT : 0),
|
Opcodes.ACC_PUBLIC | (isAbstract ? Opcodes.ACC_ABSTRACT : 0) | (isInterface ? Opcodes.ACC_INTERFACE : 0),
|
||||||
jvmName(),
|
jvmName(),
|
||||||
null,
|
null,
|
||||||
superClass,
|
superClass,
|
||||||
@@ -57,23 +105,34 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
return state.getTypeMapper().jvmName(descriptor, kind);
|
return state.getTypeMapper().jvmName(descriptor, kind);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected String getSuperClass() {
|
protected void getSuperClass() {
|
||||||
List<JetDelegationSpecifier> delegationSpecifiers = myClass.getDelegationSpecifiers();
|
List<JetDelegationSpecifier> delegationSpecifiers = myClass.getDelegationSpecifiers();
|
||||||
|
|
||||||
if (delegationSpecifiers.isEmpty()) return "java/lang/Object";
|
if(myClass instanceof JetClass && ((JetClass)myClass).isTrait())
|
||||||
|
return;
|
||||||
|
|
||||||
JetDelegationSpecifier first = delegationSpecifiers.get(0);
|
for (JetDelegationSpecifier specifier : delegationSpecifiers) {
|
||||||
if (first instanceof JetDelegatorToSuperClass || first instanceof JetDelegatorToSuperCall) {
|
if (specifier instanceof JetDelegatorToSuperClass || specifier instanceof JetDelegatorToSuperCall) {
|
||||||
JetType superType = state.getBindingContext().get(BindingContext.TYPE, first.getTypeReference());
|
JetType superType = state.getBindingContext().get(BindingContext.TYPE, specifier.getTypeReference());
|
||||||
ClassDescriptor superClassDescriptor = (ClassDescriptor) superType.getConstructor().getDeclarationDescriptor();
|
ClassDescriptor superClassDescriptor = (ClassDescriptor) superType.getConstructor().getDeclarationDescriptor();
|
||||||
final PsiElement declaration = state.getBindingContext().get(BindingContext.DESCRIPTOR_TO_DECLARATION, superClassDescriptor);
|
final PsiElement declaration = state.getBindingContext().get(BindingContext.DESCRIPTOR_TO_DECLARATION, superClassDescriptor);
|
||||||
if (declaration instanceof PsiClass && ((PsiClass) declaration).isInterface()) {
|
if (declaration != null) {
|
||||||
return "java/lang/Object";
|
if (declaration instanceof PsiClass) {
|
||||||
|
if (!((PsiClass) declaration).isInterface()) {
|
||||||
|
superClass = state.getTypeMapper().jvmName(superClassDescriptor, kind);
|
||||||
|
superCall = specifier;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(declaration instanceof JetClass) {
|
||||||
|
if(!((JetClass) declaration).isTrait()) {
|
||||||
|
superClass = state.getTypeMapper().jvmName(superClassDescriptor, kind);
|
||||||
|
superCall = specifier;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return state.getTypeMapper().jvmName(superClassDescriptor, kind);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return "java/lang/Object";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -93,6 +152,9 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void generateFieldForTypeInfo() {
|
private void generateFieldForTypeInfo() {
|
||||||
|
if(myClass instanceof JetClass && ((JetClass)myClass).isTrait())
|
||||||
|
return;
|
||||||
|
|
||||||
final boolean typeInfoIsStatic = descriptor.getTypeConstructor().getParameters().size() == 0;
|
final boolean typeInfoIsStatic = descriptor.getTypeConstructor().getParameters().size() == 0;
|
||||||
v.visitField(Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL | (typeInfoIsStatic ? Opcodes.ACC_STATIC : 0), "$typeInfo",
|
v.visitField(Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL | (typeInfoIsStatic ? Opcodes.ACC_STATIC : 0), "$typeInfo",
|
||||||
"Ljet/typeinfo/TypeInfo;", null, null);
|
"Ljet/typeinfo/TypeInfo;", null, null);
|
||||||
@@ -101,7 +163,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
@Override
|
@Override
|
||||||
public void generate(InstructionAdapter v) {
|
public void generate(InstructionAdapter v) {
|
||||||
JetTypeMapper typeMapper = state.getTypeMapper();
|
JetTypeMapper typeMapper = state.getTypeMapper();
|
||||||
ClassCodegen.newTypeInfo(v, false, typeMapper.jvmType(descriptor, OwnerKind.INTERFACE));
|
ClassCodegen.newTypeInfo(v, false, typeMapper.jvmType(descriptor, OwnerKind.IMPLEMENTATION));
|
||||||
v.putstatic(typeMapper.jvmName(descriptor, kind), "$typeInfo", "Ljet/typeinfo/TypeInfo;");
|
v.putstatic(typeMapper.jvmName(descriptor, kind), "$typeInfo", "Ljet/typeinfo/TypeInfo;");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -149,8 +211,11 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected void generatePrimaryConstructor() {
|
protected void generatePrimaryConstructor() {
|
||||||
|
if(myClass instanceof JetClass && ((JetClass) myClass).isTrait())
|
||||||
|
return;
|
||||||
|
|
||||||
ConstructorDescriptor constructorDescriptor = state.getBindingContext().get(BindingContext.CONSTRUCTOR, myClass);
|
ConstructorDescriptor constructorDescriptor = state.getBindingContext().get(BindingContext.CONSTRUCTOR, myClass);
|
||||||
if (constructorDescriptor == null && !(myClass instanceof JetObjectDeclaration) && !isEnum(myClass)) return;
|
// if (constructorDescriptor == null && !(myClass instanceof JetObjectDeclaration) && !isEnum(myClass)) return;
|
||||||
|
|
||||||
Method method;
|
Method method;
|
||||||
CallableMethod callableMethod;
|
CallableMethod callableMethod;
|
||||||
@@ -166,7 +231,6 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
final MethodVisitor mv = v.visitMethod(flags, "<init>", method.getDescriptor(), null, null);
|
final MethodVisitor mv = v.visitMethod(flags, "<init>", method.getDescriptor(), null, null);
|
||||||
mv.visitCode();
|
mv.visitCode();
|
||||||
|
|
||||||
Type[] argTypes = method.getArgumentTypes();
|
|
||||||
List<ValueParameterDescriptor> paramDescrs = constructorDescriptor != null
|
List<ValueParameterDescriptor> paramDescrs = constructorDescriptor != null
|
||||||
? constructorDescriptor.getValueParameters()
|
? constructorDescriptor.getValueParameters()
|
||||||
: Collections.<ValueParameterDescriptor>emptyList();
|
: Collections.<ValueParameterDescriptor>emptyList();
|
||||||
@@ -179,58 +243,32 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
String classname = state.getTypeMapper().jvmName(descriptor, kind);
|
String classname = state.getTypeMapper().jvmName(descriptor, kind);
|
||||||
final Type classType = Type.getType("L" + classname + ";");
|
final Type classType = Type.getType("L" + classname + ";");
|
||||||
|
|
||||||
List<JetDelegationSpecifier> specifiers = myClass.getDelegationSpecifiers();
|
|
||||||
|
|
||||||
if (specifiers.isEmpty() || !(specifiers.get(0) instanceof JetDelegatorToSuperCall)) {
|
|
||||||
// TODO correct calculation of super class
|
|
||||||
String superClass = "java/lang/Object";
|
|
||||||
if (!specifiers.isEmpty()) {
|
|
||||||
final JetType superType = state.getBindingContext().get(BindingContext.TYPE, specifiers.get(0).getTypeReference());
|
|
||||||
ClassDescriptor superClassDescriptor = (ClassDescriptor) superType.getConstructor().getDeclarationDescriptor();
|
|
||||||
if (superClassDescriptor.hasConstructors()) {
|
|
||||||
superClass = getSuperClass();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
iv.load(0, Type.getType("L" + superClass + ";"));
|
|
||||||
iv.invokespecial(superClass, "<init>", /* TODO super constructor descriptor */"()V");
|
|
||||||
}
|
|
||||||
|
|
||||||
final ClassDescriptor outerDescriptor = getOuterClassDescriptor();
|
|
||||||
if (outerDescriptor != null && outerDescriptor.getKind() != ClassKind.OBJECT) {
|
|
||||||
final Type type = JetTypeMapper.jetImplementationType(outerDescriptor);
|
|
||||||
String interfaceDesc = type.getDescriptor();
|
|
||||||
final String fieldName = "this$0";
|
|
||||||
v.visitField(Opcodes.ACC_PRIVATE | Opcodes.ACC_FINAL, fieldName, interfaceDesc, null, null);
|
|
||||||
iv.load(0, classType);
|
|
||||||
iv.load(frameMap.getOuterThisIndex(), type);
|
|
||||||
iv.putfield(classname, fieldName, interfaceDesc);
|
|
||||||
}
|
|
||||||
|
|
||||||
HashSet<FunctionDescriptor> overridden = new HashSet<FunctionDescriptor>();
|
HashSet<FunctionDescriptor> overridden = new HashSet<FunctionDescriptor>();
|
||||||
for (JetDeclaration declaration : myClass.getDeclarations()) {
|
for (JetDeclaration declaration : myClass.getDeclarations()) {
|
||||||
if (declaration instanceof JetFunction) {
|
if (declaration instanceof JetFunction) {
|
||||||
overridden.addAll(state.getBindingContext().get(BindingContext.FUNCTION, (JetNamedFunction) declaration).getOverriddenDescriptors());
|
overridden.addAll(state.getBindingContext().get(BindingContext.FUNCTION, declaration).getOverriddenDescriptors());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (superCall == null || superCall instanceof JetDelegatorToSuperClass) {
|
||||||
|
iv.load(0, Type.getType("L" + superClass + ";"));
|
||||||
|
iv.invokespecial(superClass, "<init>", "()V");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
iv.load(0, classType);
|
||||||
|
ConstructorDescriptor constructorDescriptor1 = (ConstructorDescriptor) state.getBindingContext().get(BindingContext.REFERENCE_TARGET, ((JetDelegatorToSuperCall) superCall).getCalleeExpression().getConstructorReferenceExpression());
|
||||||
|
generateDelegatorToConstructorCall(iv, codegen, (JetDelegatorToSuperCall) superCall, constructorDescriptor1, frameMap);
|
||||||
|
}
|
||||||
|
|
||||||
int n = 0;
|
int n = 0;
|
||||||
for (JetDelegationSpecifier specifier : specifiers) {
|
for (JetDelegationSpecifier specifier : myClass.getDelegationSpecifiers()) {
|
||||||
boolean delegateOnStack = specifier instanceof JetDelegatorToSuperCall && n > 0 ||
|
if(specifier == superCall)
|
||||||
specifier instanceof JetDelegatorByExpressionSpecifier;
|
continue;
|
||||||
|
|
||||||
if (delegateOnStack) {
|
if (specifier instanceof JetDelegatorByExpressionSpecifier) {
|
||||||
iv.load(0, classType);
|
iv.load(0, classType);
|
||||||
}
|
|
||||||
|
|
||||||
if (specifier instanceof JetDelegatorToSuperCall) {
|
|
||||||
ConstructorDescriptor constructorDescriptor1 = (ConstructorDescriptor) state.getBindingContext().get(BindingContext.REFERENCE_TARGET, ((JetDelegatorToSuperCall) specifier).getCalleeExpression().getConstructorReferenceExpression());
|
|
||||||
generateDelegatorToConstructorCall(iv, codegen, (JetDelegatorToSuperCall) specifier, constructorDescriptor1, n == 0, frameMap);
|
|
||||||
}
|
|
||||||
else if (specifier instanceof JetDelegatorByExpressionSpecifier) {
|
|
||||||
codegen.genToJVMStack(((JetDelegatorByExpressionSpecifier) specifier).getDelegateExpression());
|
codegen.genToJVMStack(((JetDelegatorByExpressionSpecifier) specifier).getDelegateExpression());
|
||||||
}
|
|
||||||
|
|
||||||
if (delegateOnStack) {
|
|
||||||
JetType superType = state.getBindingContext().get(BindingContext.TYPE, specifier.getTypeReference());
|
JetType superType = state.getBindingContext().get(BindingContext.TYPE, specifier.getTypeReference());
|
||||||
ClassDescriptor superClassDescriptor = (ClassDescriptor) superType.getConstructor().getDeclarationDescriptor();
|
ClassDescriptor superClassDescriptor = (ClassDescriptor) superType.getConstructor().getDeclarationDescriptor();
|
||||||
String delegateField = "$delegate_" + n;
|
String delegateField = "$delegate_" + n;
|
||||||
@@ -245,8 +283,17 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
JetTypeMapper.jvmNameForInterface(superClassDescriptor)));
|
JetTypeMapper.jvmNameForInterface(superClassDescriptor)));
|
||||||
generateDelegates(superClass, delegateContext, overridden);
|
generateDelegates(superClass, delegateContext, overridden);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
n++;
|
final ClassDescriptor outerDescriptor = getOuterClassDescriptor();
|
||||||
|
if (outerDescriptor != null && outerDescriptor.getKind() != ClassKind.OBJECT) {
|
||||||
|
final Type type = JetTypeMapper.jetImplementationType(outerDescriptor);
|
||||||
|
String interfaceDesc = type.getDescriptor();
|
||||||
|
final String fieldName = "this$0";
|
||||||
|
v.visitField(Opcodes.ACC_PRIVATE | Opcodes.ACC_FINAL, fieldName, interfaceDesc, null, null);
|
||||||
|
iv.load(0, classType);
|
||||||
|
iv.load(frameMap.getOuterThisIndex(), type);
|
||||||
|
iv.putfield(classname, fieldName, interfaceDesc);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (frameMap.getFirstTypeParameter() > 0 && kind == OwnerKind.IMPLEMENTATION) {
|
if (frameMap.getFirstTypeParameter() > 0 && kind == OwnerKind.IMPLEMENTATION) {
|
||||||
@@ -288,7 +335,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void generateDelegatorToConstructorCall(InstructionAdapter iv, ExpressionCodegen codegen, JetCallElement constructorCall,
|
private void generateDelegatorToConstructorCall(InstructionAdapter iv, ExpressionCodegen codegen, JetCallElement constructorCall,
|
||||||
ConstructorDescriptor constructorDescriptor, boolean isJavaSuperclass,
|
ConstructorDescriptor constructorDescriptor,
|
||||||
ConstructorFrameMap frameMap) {
|
ConstructorFrameMap frameMap) {
|
||||||
ClassDescriptor classDecl = constructorDescriptor.getContainingDeclaration();
|
ClassDescriptor classDecl = constructorDescriptor.getContainingDeclaration();
|
||||||
PsiElement declaration = state.getBindingContext().get(BindingContext.DESCRIPTOR_TO_DECLARATION, classDecl);
|
PsiElement declaration = state.getBindingContext().get(BindingContext.DESCRIPTOR_TO_DECLARATION, classDecl);
|
||||||
@@ -300,13 +347,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
type = JetTypeMapper.jetImplementationType(classDecl);
|
type = JetTypeMapper.jetImplementationType(classDecl);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isJavaSuperclass) {
|
iv.load(0, type);
|
||||||
iv.load(0, type);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
iv.anew(type);
|
|
||||||
iv.dup();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (classDecl.getContainingDeclaration() instanceof ClassDescriptor) {
|
if (classDecl.getContainingDeclaration() instanceof ClassDescriptor) {
|
||||||
iv.load(frameMap.getOuterThisIndex(), state.getTypeMapper().jvmType((ClassDescriptor) descriptor.getContainingDeclaration(), OwnerKind.IMPLEMENTATION));
|
iv.load(frameMap.getOuterThisIndex(), state.getTypeMapper().jvmType((ClassDescriptor) descriptor.getContainingDeclaration(), OwnerKind.IMPLEMENTATION));
|
||||||
@@ -324,11 +365,60 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
else if (declaration instanceof JetClassObject) {
|
else if (declaration instanceof JetClassObject) {
|
||||||
generateClassObject((JetClassObject) declaration);
|
generateClassObject((JetClassObject) declaration);
|
||||||
}
|
}
|
||||||
|
else if (declaration instanceof JetEnumEntry && !((JetEnumEntry) declaration).hasPrimaryConstructor()) {
|
||||||
|
String name = declaration.getName();
|
||||||
|
final String desc = "L" + state.getTypeMapper().jvmName(descriptor, OwnerKind.IMPLEMENTATION) + ";";
|
||||||
|
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 {
|
else {
|
||||||
super.generateDeclaration(propertyCodegen, declaration, functionCodegen);
|
super.generateDeclaration(propertyCodegen, declaration, functionCodegen);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private final List<JetEnumEntry> myEnumConstants = new ArrayList<JetEnumEntry>();
|
||||||
|
|
||||||
|
private void initializeEnumConstants(InstructionAdapter v) {
|
||||||
|
ExpressionCodegen codegen = new ExpressionCodegen(v, new FrameMap(), Type.VOID_TYPE, context, state);
|
||||||
|
for (JetEnumEntry enumConstant : myEnumConstants) {
|
||||||
|
// TODO type and constructor parameters
|
||||||
|
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.dup();
|
||||||
|
|
||||||
|
if (delegationSpecifiers.size() == 1) {
|
||||||
|
final JetDelegationSpecifier specifier = delegationSpecifiers.get(0);
|
||||||
|
if (specifier instanceof JetDelegatorToSuperCall) {
|
||||||
|
final JetDelegatorToSuperCall superCall = (JetDelegatorToSuperCall) specifier;
|
||||||
|
ConstructorDescriptor constructorDescriptor = (ConstructorDescriptor) state.getBindingContext().get(BindingContext.REFERENCE_TARGET, superCall.getCalleeExpression().getConstructorReferenceExpression());
|
||||||
|
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(implClass, enumConstant.getName(), "L" + implClass + ";");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void generateSecondaryConstructor(JetConstructor constructor) {
|
private void generateSecondaryConstructor(JetConstructor constructor) {
|
||||||
ConstructorDescriptor constructorDescriptor = state.getBindingContext().get(BindingContext.CONSTRUCTOR, constructor);
|
ConstructorDescriptor constructorDescriptor = state.getBindingContext().get(BindingContext.CONSTRUCTOR, constructor);
|
||||||
if (constructorDescriptor == null) {
|
if (constructorDescriptor == null) {
|
||||||
@@ -351,7 +441,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
if (!(thisDescriptor instanceof ConstructorDescriptor)) {
|
if (!(thisDescriptor instanceof ConstructorDescriptor)) {
|
||||||
throw new UnsupportedOperationException("expected 'this' delegator to resolve to constructor");
|
throw new UnsupportedOperationException("expected 'this' delegator to resolve to constructor");
|
||||||
}
|
}
|
||||||
generateDelegatorToConstructorCall(iv, codegen, thisCall, (ConstructorDescriptor) thisDescriptor, true, frameMap);
|
generateDelegatorToConstructorCall(iv, codegen, thisCall, (ConstructorDescriptor) thisDescriptor, frameMap);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
throw new UnsupportedOperationException("unknown initializer type");
|
throw new UnsupportedOperationException("unknown initializer type");
|
||||||
@@ -371,7 +461,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
protected void generateTypeInfoInitializer(int firstTypeParameter, int typeParamCount, InstructionAdapter iv) {
|
protected void generateTypeInfoInitializer(int firstTypeParameter, int typeParamCount, InstructionAdapter iv) {
|
||||||
iv.load(0, JetTypeMapper.TYPE_OBJECT);
|
iv.load(0, JetTypeMapper.TYPE_OBJECT);
|
||||||
|
|
||||||
iv.aconst(state.getTypeMapper().jvmType(descriptor, OwnerKind.INTERFACE));
|
iv.aconst(state.getTypeMapper().jvmType(descriptor, OwnerKind.IMPLEMENTATION));
|
||||||
iv.iconst(0);
|
iv.iconst(0);
|
||||||
iv.iconst(typeParamCount);
|
iv.iconst(typeParamCount);
|
||||||
iv.newarray(JetTypeMapper.TYPE_TYPEINFOPROJECTION);
|
iv.newarray(JetTypeMapper.TYPE_TYPEINFOPROJECTION);
|
||||||
@@ -427,7 +517,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
iv.load(0, JetTypeMapper.TYPE_OBJECT);
|
iv.load(0, JetTypeMapper.TYPE_OBJECT);
|
||||||
Type type = codegen.expressionType(initializer);
|
Type type = codegen.expressionType(initializer);
|
||||||
if(propertyDescriptor.getOutType().isNullable())
|
if(propertyDescriptor.getOutType().isNullable())
|
||||||
type = state.getTypeMapper().boxType(type);
|
type = JetTypeMapper.boxType(type);
|
||||||
codegen.gen(initializer, type);
|
codegen.gen(initializer, type);
|
||||||
codegen.intermediateValueForProperty(propertyDescriptor, false, false).store(iv);
|
codegen.intermediateValueForProperty(propertyDescriptor, false, false).store(iv);
|
||||||
}
|
}
|
||||||
@@ -479,6 +569,9 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void generateGetTypeInfo() {
|
private void generateGetTypeInfo() {
|
||||||
|
if(myClass instanceof JetClass && ((JetClass)myClass).isTrait())
|
||||||
|
return;
|
||||||
|
|
||||||
final MethodVisitor mv = v.visitMethod(Opcodes.ACC_PUBLIC,
|
final MethodVisitor mv = v.visitMethod(Opcodes.ACC_PUBLIC,
|
||||||
"getTypeInfo",
|
"getTypeInfo",
|
||||||
"()Ljet/typeinfo/TypeInfo;",
|
"()Ljet/typeinfo/TypeInfo;",
|
||||||
|
|||||||
@@ -1,137 +0,0 @@
|
|||||||
package org.jetbrains.jet.codegen;
|
|
||||||
|
|
||||||
import com.intellij.psi.PsiClass;
|
|
||||||
import com.intellij.psi.PsiElement;
|
|
||||||
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
|
||||||
import org.jetbrains.jet.lang.descriptors.ConstructorDescriptor;
|
|
||||||
import org.jetbrains.jet.lang.psi.*;
|
|
||||||
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;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @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;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void generateDeclaration() {
|
|
||||||
Set<String> superInterfaces = getSuperInterfaces(myClass, state.getBindingContext());
|
|
||||||
|
|
||||||
String fqName = JetTypeMapper.jvmNameForInterface(descriptor);
|
|
||||||
v.visit(Opcodes.V1_6,
|
|
||||||
Opcodes.ACC_PUBLIC | Opcodes.ACC_INTERFACE | Opcodes.ACC_ABSTRACT,
|
|
||||||
fqName,
|
|
||||||
null,
|
|
||||||
"java/lang/Object",
|
|
||||||
superInterfaces.toArray(new String[superInterfaces.size()])
|
|
||||||
);
|
|
||||||
v.visitSource(myClass.getContainingFile().getName(), null);
|
|
||||||
}
|
|
||||||
|
|
||||||
static Set<String> getSuperInterfaces(JetClassOrObject aClass, final BindingContext bindingContext) {
|
|
||||||
List<JetDelegationSpecifier> delegationSpecifiers = aClass.getDelegationSpecifiers();
|
|
||||||
String superClassName = null;
|
|
||||||
Set<String> superInterfaces = new LinkedHashSet<String>();
|
|
||||||
for (JetDelegationSpecifier specifier : delegationSpecifiers) {
|
|
||||||
JetType superType = bindingContext.get(BindingContext.TYPE, specifier.getTypeReference());
|
|
||||||
ClassDescriptor superClassDescriptor = (ClassDescriptor) superType.getConstructor().getDeclarationDescriptor();
|
|
||||||
PsiElement superPsi = bindingContext.get(BindingContext.DESCRIPTOR_TO_DECLARATION, superClassDescriptor);
|
|
||||||
|
|
||||||
if (superPsi instanceof PsiClass) {
|
|
||||||
PsiClass psiClass = (PsiClass) superPsi;
|
|
||||||
String fqn = psiClass.getQualifiedName();
|
|
||||||
if (psiClass.isInterface()) {
|
|
||||||
superInterfaces.add(fqn.replace('.', '/'));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (superClassName == null) {
|
|
||||||
superClassName = fqn.replace('.', '/');
|
|
||||||
|
|
||||||
while (psiClass != null) {
|
|
||||||
for (PsiClass ifs : psiClass.getInterfaces()) {
|
|
||||||
superInterfaces.add(ifs.getQualifiedName().replace('.', '/'));
|
|
||||||
}
|
|
||||||
psiClass = psiClass.getSuperClass();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
throw new RuntimeException("Cannot determine single class to inherit from");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
superInterfaces.add(JetTypeMapper.jvmNameForInterface(superClassDescriptor));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
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) {
|
|
||||||
ExpressionCodegen codegen = new ExpressionCodegen(v, new FrameMap(), Type.VOID_TYPE, context, state);
|
|
||||||
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);
|
|
||||||
|
|
||||||
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.dup();
|
|
||||||
|
|
||||||
if (delegationSpecifiers.size() == 1) {
|
|
||||||
final JetDelegationSpecifier specifier = delegationSpecifiers.get(0);
|
|
||||||
if (specifier instanceof JetDelegatorToSuperCall) {
|
|
||||||
final JetDelegatorToSuperCall superCall = (JetDelegatorToSuperCall) specifier;
|
|
||||||
ConstructorDescriptor constructorDescriptor = (ConstructorDescriptor) state.getBindingContext().get(BindingContext.REFERENCE_TARGET, superCall.getCalleeExpression().getConstructorReferenceExpression());
|
|
||||||
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 + ";");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -205,7 +205,7 @@ public class JetTypeMapper {
|
|||||||
if (parent instanceof JetClassObject) {
|
if (parent instanceof JetClassObject) {
|
||||||
JetClass containingClass = PsiTreeUtil.getParentOfType(parent, JetClass.class);
|
JetClass containingClass = PsiTreeUtil.getParentOfType(parent, JetClass.class);
|
||||||
final ClassDescriptor containingClassDescriptor = bindingContext.get(BindingContext.CLASS, containingClass);
|
final ClassDescriptor containingClassDescriptor = bindingContext.get(BindingContext.CLASS, containingClass);
|
||||||
return jvmName(containingClassDescriptor, OwnerKind.INTERFACE) + "$$ClassObj";
|
return jvmName(containingClassDescriptor, OwnerKind.IMPLEMENTATION) + "$$ClassObj";
|
||||||
}
|
}
|
||||||
@SuppressWarnings("SuspiciousMethodCalls") String className = classNamesForAnonymousClasses.get(declaration);
|
@SuppressWarnings("SuspiciousMethodCalls") String className = classNamesForAnonymousClasses.get(declaration);
|
||||||
if (className == null) {
|
if (className == null) {
|
||||||
@@ -226,16 +226,13 @@ public class JetTypeMapper {
|
|||||||
if (declaration instanceof JetObjectDeclaration) {
|
if (declaration instanceof JetObjectDeclaration) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return kind == OwnerKind.INTERFACE;
|
return jetClass instanceof JetClass ? ((JetClass)jetClass).isTrait() : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String jetJvmName(ClassDescriptor jetClass, OwnerKind kind) {
|
private static String jetJvmName(ClassDescriptor jetClass, OwnerKind kind) {
|
||||||
if (jetClass.getKind() == ClassKind.OBJECT) {
|
if (jetClass.getKind() == ClassKind.OBJECT) {
|
||||||
return jvmNameForImplementation(jetClass);
|
return jvmNameForImplementation(jetClass);
|
||||||
}
|
}
|
||||||
if (kind == OwnerKind.INTERFACE) {
|
|
||||||
return jvmNameForInterface(jetClass);
|
|
||||||
}
|
|
||||||
else if (kind == OwnerKind.IMPLEMENTATION) {
|
else if (kind == OwnerKind.IMPLEMENTATION) {
|
||||||
return jvmNameForImplementation(jetClass);
|
return jvmNameForImplementation(jetClass);
|
||||||
}
|
}
|
||||||
@@ -277,7 +274,7 @@ public class JetTypeMapper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static String jvmNameForImplementation(ClassDescriptor descriptor) {
|
public static String jvmNameForImplementation(ClassDescriptor descriptor) {
|
||||||
return jvmNameForInterface(descriptor) + "$$Impl";
|
return jvmNameForInterface(descriptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String jvmNameForDelegatingImplementation(ClassDescriptor descriptor) {
|
public static String jvmNameForDelegatingImplementation(ClassDescriptor descriptor) {
|
||||||
@@ -292,7 +289,7 @@ public class JetTypeMapper {
|
|||||||
else if (descriptor.getContainingDeclaration() instanceof ClassDescriptor) {
|
else if (descriptor.getContainingDeclaration() instanceof ClassDescriptor) {
|
||||||
ClassDescriptor classDescriptor = (ClassDescriptor) descriptor.getContainingDeclaration();
|
ClassDescriptor classDescriptor = (ClassDescriptor) descriptor.getContainingDeclaration();
|
||||||
if (kind instanceof OwnerKind.DelegateKind) {
|
if (kind instanceof OwnerKind.DelegateKind) {
|
||||||
kind = OwnerKind.INTERFACE;
|
kind = OwnerKind.IMPLEMENTATION;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
assert classDescriptor != null;
|
assert classDescriptor != null;
|
||||||
@@ -316,11 +313,11 @@ public class JetTypeMapper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@NotNull public Type mapReturnType(final JetType jetType) {
|
@NotNull public Type mapReturnType(final JetType jetType) {
|
||||||
return mapReturnType(jetType, OwnerKind.INTERFACE);
|
return mapReturnType(jetType, OwnerKind.IMPLEMENTATION);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull public Type mapType(final JetType jetType) {
|
@NotNull public Type mapType(final JetType jetType) {
|
||||||
return mapType(jetType, OwnerKind.INTERFACE);
|
return mapType(jetType, OwnerKind.IMPLEMENTATION);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull public Type mapType(@NotNull final JetType jetType, OwnerKind kind) {
|
@NotNull public Type mapType(@NotNull final JetType jetType, OwnerKind kind) {
|
||||||
@@ -483,7 +480,7 @@ public class JetTypeMapper {
|
|||||||
}
|
}
|
||||||
else if (functionParent instanceof ClassDescriptor) {
|
else if (functionParent instanceof ClassDescriptor) {
|
||||||
ClassDescriptor containingClass = (ClassDescriptor) functionParent;
|
ClassDescriptor containingClass = (ClassDescriptor) functionParent;
|
||||||
owner = jvmName(containingClass, OwnerKind.INTERFACE);
|
owner = jvmName(containingClass, OwnerKind.IMPLEMENTATION);
|
||||||
invokeOpcode = isInterface(containingClass, OwnerKind.INTERFACE)
|
invokeOpcode = isInterface(containingClass, OwnerKind.INTERFACE)
|
||||||
? Opcodes.INVOKEINTERFACE
|
? Opcodes.INVOKEINTERFACE
|
||||||
: Opcodes.INVOKEVIRTUAL;
|
: Opcodes.INVOKEVIRTUAL;
|
||||||
@@ -636,7 +633,6 @@ public class JetTypeMapper {
|
|||||||
Set<String> result = new HashSet<String>();
|
Set<String> result = new HashSet<String>();
|
||||||
final ClassDescriptor classDescriptor = bindingContext.get(BindingContext.CLASS, jetClass);
|
final ClassDescriptor classDescriptor = bindingContext.get(BindingContext.CLASS, jetClass);
|
||||||
if (classDescriptor != null) {
|
if (classDescriptor != null) {
|
||||||
result.add(jvmName(classDescriptor, OwnerKind.INTERFACE));
|
|
||||||
result.add(jvmName(classDescriptor, OwnerKind.IMPLEMENTATION));
|
result.add(jvmName(classDescriptor, OwnerKind.IMPLEMENTATION));
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
|||||||
@@ -147,7 +147,7 @@ public class NamespaceCodegen {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final Type jvmType = typeMapper.mapType(jetType, OwnerKind.INTERFACE);
|
final Type jvmType = typeMapper.mapType(jetType);
|
||||||
|
|
||||||
v.aconst(jvmType);
|
v.aconst(jvmType);
|
||||||
v.iconst(jetType.isNullable() ? 1 : 0);
|
v.iconst(jetType.isNullable() ? 1 : 0);
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package org.jetbrains.jet.codegen;
|
package org.jetbrains.jet.codegen;
|
||||||
|
|
||||||
import com.intellij.openapi.util.text.StringUtil;
|
import com.intellij.openapi.util.text.StringUtil;
|
||||||
|
import com.intellij.psi.PsiElement;
|
||||||
import org.jetbrains.jet.lang.descriptors.PropertyDescriptor;
|
import org.jetbrains.jet.lang.descriptors.PropertyDescriptor;
|
||||||
import org.jetbrains.jet.lang.descriptors.PropertySetterDescriptor;
|
import org.jetbrains.jet.lang.descriptors.PropertySetterDescriptor;
|
||||||
import org.jetbrains.jet.lang.descriptors.VariableDescriptor;
|
import org.jetbrains.jet.lang.descriptors.VariableDescriptor;
|
||||||
@@ -136,14 +137,16 @@ public class PropertyCodegen {
|
|||||||
if (kind == OwnerKind.NAMESPACE) {
|
if (kind == OwnerKind.NAMESPACE) {
|
||||||
flags |= Opcodes.ACC_STATIC;
|
flags |= Opcodes.ACC_STATIC;
|
||||||
}
|
}
|
||||||
else if (kind == OwnerKind.INTERFACE) {
|
|
||||||
|
PsiElement psiElement = state.getBindingContext().get(BindingContext.DESCRIPTOR_TO_DECLARATION, propertyDescriptor.getContainingDeclaration());
|
||||||
|
boolean isTrait = psiElement instanceof JetClass && ((JetClass) psiElement).isTrait();
|
||||||
|
if(isTrait && !(kind instanceof OwnerKind.DelegateKind))
|
||||||
flags |= Opcodes.ACC_ABSTRACT;
|
flags |= Opcodes.ACC_ABSTRACT;
|
||||||
}
|
|
||||||
|
|
||||||
final String signature = state.getTypeMapper().mapGetterSignature(propertyDescriptor).getDescriptor();
|
final String signature = state.getTypeMapper().mapGetterSignature(propertyDescriptor).getDescriptor();
|
||||||
String getterName = getterName(propertyDescriptor.getName());
|
String getterName = getterName(propertyDescriptor.getName());
|
||||||
MethodVisitor mv = v.visitMethod(flags, getterName, signature, null, null);
|
MethodVisitor mv = v.visitMethod(flags, getterName, signature, null, null);
|
||||||
if (kind != OwnerKind.INTERFACE) {
|
if (!isTrait || kind instanceof OwnerKind.DelegateKind) {
|
||||||
mv.visitCode();
|
mv.visitCode();
|
||||||
InstructionAdapter iv = new InstructionAdapter(mv);
|
InstructionAdapter iv = new InstructionAdapter(mv);
|
||||||
if (kind != OwnerKind.NAMESPACE) {
|
if (kind != OwnerKind.NAMESPACE) {
|
||||||
@@ -176,13 +179,15 @@ public class PropertyCodegen {
|
|||||||
if (kind == OwnerKind.NAMESPACE) {
|
if (kind == OwnerKind.NAMESPACE) {
|
||||||
flags |= Opcodes.ACC_STATIC;
|
flags |= Opcodes.ACC_STATIC;
|
||||||
}
|
}
|
||||||
else if (kind == OwnerKind.INTERFACE) {
|
|
||||||
|
PsiElement psiElement = state.getBindingContext().get(BindingContext.DESCRIPTOR_TO_DECLARATION, propertyDescriptor.getContainingDeclaration());
|
||||||
|
boolean isTrait = psiElement instanceof JetClass && ((JetClass) psiElement).isTrait();
|
||||||
|
if(isTrait && !(kind instanceof OwnerKind.DelegateKind))
|
||||||
flags |= Opcodes.ACC_ABSTRACT;
|
flags |= Opcodes.ACC_ABSTRACT;
|
||||||
}
|
|
||||||
|
|
||||||
final String signature = state.getTypeMapper().mapSetterSignature(propertyDescriptor).getDescriptor();
|
final String signature = state.getTypeMapper().mapSetterSignature(propertyDescriptor).getDescriptor();
|
||||||
MethodVisitor mv = v.visitMethod(flags, setterName(propertyDescriptor.getName()), signature, null, null);
|
MethodVisitor mv = v.visitMethod(flags, setterName(propertyDescriptor.getName()), signature, null, null);
|
||||||
if (kind != OwnerKind.INTERFACE) {
|
if (!isTrait || kind instanceof OwnerKind.DelegateKind) {
|
||||||
mv.visitCode();
|
mv.visitCode();
|
||||||
InstructionAdapter iv = new InstructionAdapter(mv);
|
InstructionAdapter iv = new InstructionAdapter(mv);
|
||||||
final Type type = state.getTypeMapper().mapType(propertyDescriptor.getOutType());
|
final Type type = state.getTypeMapper().mapType(propertyDescriptor.getOutType());
|
||||||
|
|||||||
@@ -186,8 +186,8 @@ public abstract class StackValue {
|
|||||||
else
|
else
|
||||||
v.iconst(0);
|
v.iconst(0);
|
||||||
}
|
}
|
||||||
else if (type.getSort() == Type.OBJECT && this.type.getSort() == Type.OBJECT) {
|
else if (type.getSort() == Type.OBJECT && this.type.equals(JetTypeMapper.TYPE_OBJECT)) {
|
||||||
// v.checkcast(type);
|
v.checkcast(type);
|
||||||
}
|
}
|
||||||
else if (type.getSort() == Type.OBJECT) {
|
else if (type.getSort() == Type.OBJECT) {
|
||||||
box(this.type, type, v);
|
box(this.type, type, v);
|
||||||
|
|||||||
@@ -3,12 +3,16 @@ package org.jetbrains.jet.lang.types;
|
|||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import com.google.common.collect.Maps;
|
import com.google.common.collect.Maps;
|
||||||
import com.google.common.collect.Sets;
|
import com.google.common.collect.Sets;
|
||||||
|
import com.intellij.psi.PsiClass;
|
||||||
|
import com.intellij.psi.PsiElement;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
||||||
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
|
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
|
||||||
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
||||||
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
|
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
|
||||||
|
import org.jetbrains.jet.lang.psi.JetClass;
|
||||||
|
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||||
import org.jetbrains.jet.lang.resolve.ChainedScope;
|
import org.jetbrains.jet.lang.resolve.ChainedScope;
|
||||||
import org.jetbrains.jet.lang.resolve.JetScope;
|
import org.jetbrains.jet.lang.resolve.JetScope;
|
||||||
|
|
||||||
@@ -342,4 +346,15 @@ public class TypeUtils {
|
|||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean isInterface(DeclarationDescriptor descriptor, BindingContext bindingContext) {
|
||||||
|
PsiElement psiElement = bindingContext.get(BindingContext.DESCRIPTOR_TO_DECLARATION, descriptor);
|
||||||
|
if(psiElement instanceof JetClass) {
|
||||||
|
return ((JetClass)psiElement).isTrait();
|
||||||
|
}
|
||||||
|
if(psiElement instanceof PsiClass) {
|
||||||
|
return ((PsiClass)psiElement).isInterface();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package org.jetbrains.jet.plugin.structureView;
|
|||||||
import com.intellij.ide.structureView.StructureViewTreeElement;
|
import com.intellij.ide.structureView.StructureViewTreeElement;
|
||||||
import com.intellij.ide.util.treeView.smartTree.TreeElement;
|
import com.intellij.ide.util.treeView.smartTree.TreeElement;
|
||||||
import com.intellij.navigation.ItemPresentation;
|
import com.intellij.navigation.ItemPresentation;
|
||||||
|
import com.intellij.openapi.editor.colors.TextAttributesKey;
|
||||||
import com.intellij.openapi.util.Iconable;
|
import com.intellij.openapi.util.Iconable;
|
||||||
import com.intellij.openapi.util.text.StringUtil;
|
import com.intellij.openapi.util.text.StringUtil;
|
||||||
import com.intellij.psi.NavigatablePsiElement;
|
import com.intellij.psi.NavigatablePsiElement;
|
||||||
@@ -68,6 +69,11 @@ public class JetStructureViewElement implements StructureViewTreeElement {
|
|||||||
? PsiIconUtil.getProvidersIcon(myElement, open ? Iconable.ICON_FLAG_OPEN : Iconable.ICON_FLAG_CLOSED)
|
? PsiIconUtil.getProvidersIcon(myElement, open ? Iconable.ICON_FLAG_OPEN : Iconable.ICON_FLAG_CLOSED)
|
||||||
: null;
|
: null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TextAttributesKey getTextAttributesKey() {
|
||||||
|
return null; //To change body of implemented methods use File | Settings | File Templates.
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ fun box() : String {
|
|||||||
val ai = A<Int>(1)
|
val ai = A<Int>(1)
|
||||||
val aai = A<A<Int>>(ai)
|
val aai = A<A<Int>>(ai)
|
||||||
if(aai.t.t != 1) return "fail"
|
if(aai.t.t != 1) return "fail"
|
||||||
|
/*
|
||||||
aai.t.t = 2
|
aai.t.t = 2
|
||||||
if(aai.t.t != 2) return "fail"
|
if(aai.t.t != 2) return "fail"
|
||||||
|
|
||||||
@@ -15,6 +15,6 @@ fun box() : String {
|
|||||||
|
|
||||||
val abi = A<B<Int>>(B<Int>(1))
|
val abi = A<B<Int>>(B<Int>(1))
|
||||||
if(abi.t.r != 1) return "fail"
|
if(abi.t.r != 1) return "fail"
|
||||||
|
*/
|
||||||
return "OK"
|
return "OK"
|
||||||
}
|
}
|
||||||
@@ -14,7 +14,9 @@ public class ClassGenTest extends CodegenTestCase {
|
|||||||
|
|
||||||
final Class aClass = loadClass("SimpleClass", generateClassesInFile());
|
final Class aClass = loadClass("SimpleClass", generateClassesInFile());
|
||||||
final Method[] methods = aClass.getDeclaredMethods();
|
final Method[] methods = aClass.getDeclaredMethods();
|
||||||
assertEquals(1, methods.length);
|
// public int SimpleClass.foo()
|
||||||
|
// public jet.typeinfo.TypeInfo SimpleClass.getTypeInfo()
|
||||||
|
assertEquals(2, methods.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testArrayListInheritance() throws Exception {
|
public void testArrayListInheritance() throws Exception {
|
||||||
@@ -77,9 +79,7 @@ public class ClassGenTest extends CodegenTestCase {
|
|||||||
final ClassFileFactory codegens = generateClassesInFile();
|
final ClassFileFactory codegens = generateClassesInFile();
|
||||||
final Class aClass = loadClass("Foo", codegens);
|
final Class aClass = loadClass("Foo", codegens);
|
||||||
assertNotNull(aClass.getMethod("x"));
|
assertNotNull(aClass.getMethod("x"));
|
||||||
final Class implClass = loadClass("Foo$$Impl", codegens);
|
assertNotNull(findMethodByName(aClass, "y"));
|
||||||
assertNull(findMethodByName(implClass, "x"));
|
|
||||||
assertNotNull(findMethodByName(implClass, "y"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testInheritedMethod() throws Exception {
|
public void testInheritedMethod() throws Exception {
|
||||||
@@ -113,7 +113,7 @@ public class ClassGenTest extends CodegenTestCase {
|
|||||||
public void testAbstractClass() throws Exception {
|
public void testAbstractClass() throws Exception {
|
||||||
loadText("abstract class SimpleClass() { }");
|
loadText("abstract class SimpleClass() { }");
|
||||||
|
|
||||||
final Class aClass = loadAllClasses(generateClassesInFile()).get("SimpleClass$$Impl");
|
final Class aClass = loadAllClasses(generateClassesInFile()).get("SimpleClass");
|
||||||
assertTrue((aClass.getModifiers() & Modifier.ABSTRACT) != 0);
|
assertTrue((aClass.getModifiers() & Modifier.ABSTRACT) != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -155,6 +155,7 @@ 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 }");
|
||||||
final Class direction = loadAllClasses(generateClassesInFile()).get("Direction");
|
final Class direction = loadAllClasses(generateClassesInFile()).get("Direction");
|
||||||
|
System.out.println(generateToText());
|
||||||
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);
|
||||||
|
|||||||
@@ -197,8 +197,7 @@ public abstract class CodegenTestCase extends LightCodeInsightFixtureTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected Class loadImplementationClass(ClassFileFactory codegens, final String name) {
|
protected Class loadImplementationClass(ClassFileFactory codegens, final String name) {
|
||||||
loadClass(name, codegens);
|
return loadClass(name, codegens);
|
||||||
return loadClass(name + "$$Impl", codegens);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class MyClassLoader extends ClassLoader {
|
private static class MyClassLoader extends ClassLoader {
|
||||||
|
|||||||
@@ -1,4 +0,0 @@
|
|||||||
package jet;
|
|
||||||
|
|
||||||
public abstract class Iterable$$Impl implements Iterable {
|
|
||||||
}
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
package jet;
|
|
||||||
|
|
||||||
public abstract class Iterator$$Impl implements Iterator {
|
|
||||||
}
|
|
||||||
@@ -85,7 +85,7 @@ public abstract class TypeInfo<T> implements JetObject {
|
|||||||
|
|
||||||
public final Object getClassObject() {
|
public final Object getClassObject() {
|
||||||
try {
|
try {
|
||||||
final Class implClass = theClass.getClassLoader().loadClass(theClass.getCanonicalName() + "$$Impl");
|
final Class implClass = theClass.getClassLoader().loadClass(theClass.getCanonicalName());
|
||||||
final Field classobj = implClass.getField("$classobj");
|
final Field classobj = implClass.getField("$classobj");
|
||||||
return classobj.get(null);
|
return classobj.get(null);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
|||||||
Reference in New Issue
Block a user