correctly generate supertypes of class objects and object literals
This commit is contained in:
@@ -34,6 +34,9 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
if (!(myClass instanceof JetObjectDeclaration)) {
|
if (!(myClass instanceof JetObjectDeclaration)) {
|
||||||
interfaces.add(JetTypeMapper.jvmNameForInterface(descriptor));
|
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 = myClass instanceof JetClass && ((JetClass) myClass).hasModifier(JetTokens.ABSTRACT_KEYWORD);
|
||||||
|
|
||||||
@@ -59,6 +62,10 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
if (first instanceof JetDelegatorToSuperClass || first instanceof JetDelegatorToSuperCall) {
|
if (first instanceof JetDelegatorToSuperClass || first instanceof JetDelegatorToSuperCall) {
|
||||||
JetType superType = state.getBindingContext().resolveTypeReference(first.getTypeReference());
|
JetType superType = state.getBindingContext().resolveTypeReference(first.getTypeReference());
|
||||||
ClassDescriptor superClassDescriptor = (ClassDescriptor) superType.getConstructor().getDeclarationDescriptor();
|
ClassDescriptor superClassDescriptor = (ClassDescriptor) superType.getConstructor().getDeclarationDescriptor();
|
||||||
|
final PsiElement declaration = state.getBindingContext().getDeclarationPsiElement(superClassDescriptor);
|
||||||
|
if (declaration instanceof PsiClass && ((PsiClass) declaration).isInterface()) {
|
||||||
|
return "java/lang/Object";
|
||||||
|
}
|
||||||
return state.getTypeMapper().jvmName(superClassDescriptor, kind);
|
return state.getTypeMapper().jvmName(superClassDescriptor, kind);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ 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.psi.JetClassOrObject;
|
||||||
import org.jetbrains.jet.lang.psi.JetDelegationSpecifier;
|
import org.jetbrains.jet.lang.psi.JetDelegationSpecifier;
|
||||||
|
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;
|
||||||
import org.objectweb.asm.Opcodes;
|
import org.objectweb.asm.Opcodes;
|
||||||
@@ -23,7 +24,7 @@ public class InterfaceBodyCodegen extends ClassBodyCodegen {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected void generateDeclaration() {
|
protected void generateDeclaration() {
|
||||||
Set<String> superInterfaces = getSuperInterfaces();
|
Set<String> superInterfaces = getSuperInterfaces(myClass, state.getBindingContext());
|
||||||
|
|
||||||
String fqName = JetTypeMapper.jvmNameForInterface(descriptor);
|
String fqName = JetTypeMapper.jvmNameForInterface(descriptor);
|
||||||
v.visit(Opcodes.V1_6,
|
v.visit(Opcodes.V1_6,
|
||||||
@@ -35,20 +36,20 @@ public class InterfaceBodyCodegen extends ClassBodyCodegen {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Set<String> getSuperInterfaces() {
|
static Set<String> getSuperInterfaces(JetClassOrObject aClass, final BindingContext bindingContext) {
|
||||||
List<JetDelegationSpecifier> delegationSpecifiers = myClass.getDelegationSpecifiers();
|
List<JetDelegationSpecifier> delegationSpecifiers = aClass.getDelegationSpecifiers();
|
||||||
String superClassName = null;
|
String superClassName = null;
|
||||||
Set<String> superInterfaces = new LinkedHashSet<String>();
|
Set<String> superInterfaces = new LinkedHashSet<String>();
|
||||||
for (JetDelegationSpecifier specifier : delegationSpecifiers) {
|
for (JetDelegationSpecifier specifier : delegationSpecifiers) {
|
||||||
JetType superType = state.getBindingContext().resolveTypeReference(specifier.getTypeReference());
|
JetType superType = bindingContext.resolveTypeReference(specifier.getTypeReference());
|
||||||
ClassDescriptor superClassDescriptor = (ClassDescriptor) superType.getConstructor().getDeclarationDescriptor();
|
ClassDescriptor superClassDescriptor = (ClassDescriptor) superType.getConstructor().getDeclarationDescriptor();
|
||||||
PsiElement superPsi = state.getBindingContext().getDeclarationPsiElement(superClassDescriptor);
|
PsiElement superPsi = bindingContext.getDeclarationPsiElement(superClassDescriptor);
|
||||||
|
|
||||||
if (superPsi instanceof PsiClass) {
|
if (superPsi instanceof PsiClass) {
|
||||||
PsiClass psiClass = (PsiClass) superPsi;
|
PsiClass psiClass = (PsiClass) superPsi;
|
||||||
String fqn = psiClass.getQualifiedName();
|
String fqn = psiClass.getQualifiedName();
|
||||||
if (psiClass.isInterface()) {
|
if (psiClass.isInterface()) {
|
||||||
superInterfaces.add(fqn);
|
superInterfaces.add(fqn.replace('.', '/'));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (superClassName == null) {
|
if (superClassName == null) {
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
class C() {
|
||||||
|
fun getInstance(): Runnable = C
|
||||||
|
|
||||||
|
class object: Runnable {
|
||||||
|
fun run(): Unit { }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun foo() = C().getInstance()
|
||||||
@@ -123,4 +123,11 @@ public class ClassGenTest extends CodegenTestCase {
|
|||||||
public void testClassObjectMethod() throws Exception {
|
public void testClassObjectMethod() throws Exception {
|
||||||
blackBoxFile("classes/classObjectMethod.jet");
|
blackBoxFile("classes/classObjectMethod.jet");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testClassObjectInterface() throws Exception {
|
||||||
|
loadFile("classes/classObjectInterface.jet");
|
||||||
|
final Method method = generateFunction();
|
||||||
|
Object result = method.invoke(null);
|
||||||
|
assertInstanceOf(result, Runnable.class);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user