removing unnneded InstructionAdapterEx
This commit is contained in:
@@ -89,6 +89,7 @@ public abstract class ClassBodyCodegen {
|
||||
propertyCodegen.generateDefaultSetter(propertyDescriptor, Opcodes.ACC_PUBLIC);
|
||||
}
|
||||
|
||||
//noinspection ConstantConditions
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -20,13 +20,7 @@ public class ClassCodegen {
|
||||
public void generate(ClassContext parentContext, JetClassOrObject aClass) {
|
||||
GenerationState.prepareAnonymousClasses((JetElement) aClass, state.getTypeMapper());
|
||||
|
||||
if (aClass instanceof JetObjectDeclaration) {
|
||||
generateImplementation(parentContext, aClass, OwnerKind.IMPLEMENTATION);
|
||||
}
|
||||
else {
|
||||
generateInterface(parentContext, aClass);
|
||||
generateImplementation(parentContext, aClass, OwnerKind.IMPLEMENTATION);
|
||||
}
|
||||
generateImplementation(parentContext, aClass, OwnerKind.IMPLEMENTATION);
|
||||
|
||||
ClassDescriptor descriptor = state.getBindingContext().get(BindingContext.CLASS, aClass);
|
||||
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) {
|
||||
ClassDescriptor descriptor = state.getBindingContext().get(BindingContext.CLASS, aClass);
|
||||
ClassVisitor v = kind == OwnerKind.IMPLEMENTATION
|
||||
? state.forClassImplementation(descriptor)
|
||||
: state.forClassDelegatingImplementation(descriptor);
|
||||
ClassVisitor v = state.forClassImplementation(descriptor);
|
||||
new ImplementationBodyCodegen(aClass, parentContext.intoClass(descriptor, kind), v, state).generate();
|
||||
}
|
||||
|
||||
|
||||
@@ -154,7 +154,7 @@ public class ClassContext {
|
||||
public Type enclosingClassType(JetTypeMapper mapper) {
|
||||
DeclarationDescriptor descriptor = getContextDescriptor();
|
||||
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) {
|
||||
|
||||
@@ -730,6 +730,13 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
||||
}
|
||||
JetType receiverType = bindingContext.get(BindingContext.EXPRESSION_TYPE, r);
|
||||
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;
|
||||
}
|
||||
@@ -752,8 +759,11 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
||||
}
|
||||
}
|
||||
else if (descriptor instanceof TypeParameterDescriptor) {
|
||||
loadTypeParameterTypeInfo((TypeParameterDescriptor) descriptor);
|
||||
TypeParameterDescriptor typeParameterDescriptor = (TypeParameterDescriptor) descriptor;
|
||||
loadTypeParameterTypeInfo(typeParameterDescriptor);
|
||||
v.invokevirtual("jet/typeinfo/TypeInfo", "getClassObject", "()Ljava/lang/Object;");
|
||||
v.checkcast(typeMapper.mapType(typeParameterDescriptor.getClassObjectType()));
|
||||
|
||||
return StackValue.onStack(OBJECT_TYPE);
|
||||
}
|
||||
else {
|
||||
@@ -786,14 +796,20 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
||||
isInterface = false;
|
||||
}
|
||||
else {
|
||||
owner = typeMapper.getOwner(functionDescriptor, OwnerKind.INTERFACE);
|
||||
owner = typeMapper.getOwner(functionDescriptor, OwnerKind.IMPLEMENTATION);
|
||||
if(containingDeclaration instanceof JavaClassDescriptor) {
|
||||
PsiClass psiElement = (PsiClass) bindingContext.get(BindingContext.DESCRIPTOR_TO_DECLARATION, containingDeclaration);
|
||||
assert psiElement != null;
|
||||
isInterface = psiElement.isInterface();
|
||||
}
|
||||
else
|
||||
isInterface = !(containingDeclaration instanceof ClassDescriptor && ((ClassDescriptor) containingDeclaration).getKind() == ClassKind.OBJECT);
|
||||
else {
|
||||
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());
|
||||
@@ -827,8 +843,13 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
||||
isInterface = false;
|
||||
}
|
||||
else {
|
||||
owner = typeMapper.getOwner(propertyDescriptor, OwnerKind.INTERFACE);
|
||||
isInterface = !(containingDeclaration instanceof ClassDescriptor && ((ClassDescriptor) containingDeclaration).getKind() == ClassKind.OBJECT);
|
||||
owner = typeMapper.getOwner(propertyDescriptor, OwnerKind.IMPLEMENTATION);
|
||||
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);
|
||||
@@ -971,7 +992,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
||||
|
||||
for (JetType superType : allSuperTypes) {
|
||||
final DeclarationDescriptor descriptor = superType.getConstructor().getDeclarationDescriptor();
|
||||
if (descriptor != null && superOriginal == descriptor.getOriginal()) {
|
||||
if (descriptor != null && superOriginal.equals(descriptor.getOriginal())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -1795,7 +1816,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
||||
if (!(descriptor instanceof ClassDescriptor)) {
|
||||
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);
|
||||
Label isInstance = new Label();
|
||||
v.ifne(isInstance);
|
||||
@@ -1921,7 +1942,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
||||
if (leaveExpressionOnStack) {
|
||||
v.dup();
|
||||
}
|
||||
Type type = JetTypeMapper.boxType(typeMapper.mapType(jetType, OwnerKind.INTERFACE));
|
||||
Type type = JetTypeMapper.boxType(typeMapper.mapType(jetType));
|
||||
if(jetType.isNullable()) {
|
||||
Label nope = new Label();
|
||||
Label end = new Label();
|
||||
@@ -1967,7 +1988,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
||||
return;
|
||||
}
|
||||
|
||||
final Type jvmType = typeMapper.mapType(jetType, OwnerKind.INTERFACE);
|
||||
final Type jvmType = typeMapper.mapType(jetType);
|
||||
|
||||
v.aconst(jvmType);
|
||||
v.iconst(jetType.isNullable()?1:0);
|
||||
|
||||
@@ -89,15 +89,11 @@ public class FunctionCodegen {
|
||||
boolean isStatic = kind == OwnerKind.NAMESPACE;
|
||||
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 && (kind == OwnerKind.IMPLEMENTATION )) {
|
||||
return;
|
||||
}
|
||||
|
||||
final MethodVisitor mv = v.visitMethod(flags, jvmSignature.getName(), jvmSignature.getDescriptor(), null, null);
|
||||
if (kind != OwnerKind.INTERFACE) {
|
||||
if (!isAbstract) {
|
||||
mv.visitCode();
|
||||
FrameMap frameMap = context.prepareFrame();
|
||||
|
||||
|
||||
@@ -22,29 +22,77 @@ import java.util.*;
|
||||
/**
|
||||
* @author max
|
||||
* @author yole
|
||||
* @author alex.tkachman
|
||||
*/
|
||||
public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
private JetDelegationSpecifier superCall;
|
||||
private String superClass = "java/lang/Object";
|
||||
|
||||
public ImplementationBodyCodegen(JetClassOrObject aClass, ClassContext context, ClassVisitor v, GenerationState 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
|
||||
protected void generateDeclaration() {
|
||||
String superClass = getSuperClass();
|
||||
getSuperClass();
|
||||
|
||||
List<String> interfaces = new ArrayList<String>();
|
||||
interfaces.add("jet/JetObject");
|
||||
if (!(myClass instanceof JetObjectDeclaration)) {
|
||||
interfaces.add(JetTypeMapper.jvmNameForInterface(descriptor));
|
||||
}
|
||||
else {
|
||||
interfaces.addAll(InterfaceBodyCodegen.getSuperInterfaces(myClass, state.getBindingContext()));
|
||||
}
|
||||
interfaces.addAll(getSuperInterfaces(myClass));
|
||||
|
||||
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,
|
||||
Opcodes.ACC_PUBLIC | (isAbstract ? Opcodes.ACC_ABSTRACT : 0),
|
||||
Opcodes.ACC_PUBLIC | (isAbstract ? Opcodes.ACC_ABSTRACT : 0) | (isInterface ? Opcodes.ACC_INTERFACE : 0),
|
||||
jvmName(),
|
||||
null,
|
||||
superClass,
|
||||
@@ -57,23 +105,34 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
return state.getTypeMapper().jvmName(descriptor, kind);
|
||||
}
|
||||
|
||||
protected String getSuperClass() {
|
||||
protected void getSuperClass() {
|
||||
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);
|
||||
if (first instanceof JetDelegatorToSuperClass || first instanceof JetDelegatorToSuperCall) {
|
||||
JetType superType = state.getBindingContext().get(BindingContext.TYPE, first.getTypeReference());
|
||||
ClassDescriptor superClassDescriptor = (ClassDescriptor) superType.getConstructor().getDeclarationDescriptor();
|
||||
final PsiElement declaration = state.getBindingContext().get(BindingContext.DESCRIPTOR_TO_DECLARATION, superClassDescriptor);
|
||||
if (declaration instanceof PsiClass && ((PsiClass) declaration).isInterface()) {
|
||||
return "java/lang/Object";
|
||||
for (JetDelegationSpecifier specifier : delegationSpecifiers) {
|
||||
if (specifier instanceof JetDelegatorToSuperClass || specifier instanceof JetDelegatorToSuperCall) {
|
||||
JetType superType = state.getBindingContext().get(BindingContext.TYPE, specifier.getTypeReference());
|
||||
ClassDescriptor superClassDescriptor = (ClassDescriptor) superType.getConstructor().getDeclarationDescriptor();
|
||||
final PsiElement declaration = state.getBindingContext().get(BindingContext.DESCRIPTOR_TO_DECLARATION, superClassDescriptor);
|
||||
if (declaration != null) {
|
||||
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
|
||||
@@ -93,6 +152,9 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
}
|
||||
|
||||
private void generateFieldForTypeInfo() {
|
||||
if(myClass instanceof JetClass && ((JetClass)myClass).isTrait())
|
||||
return;
|
||||
|
||||
final boolean typeInfoIsStatic = descriptor.getTypeConstructor().getParameters().size() == 0;
|
||||
v.visitField(Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL | (typeInfoIsStatic ? Opcodes.ACC_STATIC : 0), "$typeInfo",
|
||||
"Ljet/typeinfo/TypeInfo;", null, null);
|
||||
@@ -101,7 +163,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
@Override
|
||||
public void generate(InstructionAdapter v) {
|
||||
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;");
|
||||
}
|
||||
});
|
||||
@@ -149,8 +211,11 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
}
|
||||
|
||||
protected void generatePrimaryConstructor() {
|
||||
if(myClass instanceof JetClass && ((JetClass) myClass).isTrait())
|
||||
return;
|
||||
|
||||
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;
|
||||
CallableMethod callableMethod;
|
||||
@@ -166,7 +231,6 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
final MethodVisitor mv = v.visitMethod(flags, "<init>", method.getDescriptor(), null, null);
|
||||
mv.visitCode();
|
||||
|
||||
Type[] argTypes = method.getArgumentTypes();
|
||||
List<ValueParameterDescriptor> paramDescrs = constructorDescriptor != null
|
||||
? constructorDescriptor.getValueParameters()
|
||||
: Collections.<ValueParameterDescriptor>emptyList();
|
||||
@@ -179,58 +243,32 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
String classname = state.getTypeMapper().jvmName(descriptor, kind);
|
||||
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>();
|
||||
for (JetDeclaration declaration : myClass.getDeclarations()) {
|
||||
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;
|
||||
for (JetDelegationSpecifier specifier : specifiers) {
|
||||
boolean delegateOnStack = specifier instanceof JetDelegatorToSuperCall && n > 0 ||
|
||||
specifier instanceof JetDelegatorByExpressionSpecifier;
|
||||
for (JetDelegationSpecifier specifier : myClass.getDelegationSpecifiers()) {
|
||||
if(specifier == superCall)
|
||||
continue;
|
||||
|
||||
if (delegateOnStack) {
|
||||
if (specifier instanceof JetDelegatorByExpressionSpecifier) {
|
||||
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());
|
||||
}
|
||||
|
||||
if (delegateOnStack) {
|
||||
JetType superType = state.getBindingContext().get(BindingContext.TYPE, specifier.getTypeReference());
|
||||
ClassDescriptor superClassDescriptor = (ClassDescriptor) superType.getConstructor().getDeclarationDescriptor();
|
||||
String delegateField = "$delegate_" + n;
|
||||
@@ -245,8 +283,17 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
JetTypeMapper.jvmNameForInterface(superClassDescriptor)));
|
||||
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) {
|
||||
@@ -288,7 +335,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
}
|
||||
|
||||
private void generateDelegatorToConstructorCall(InstructionAdapter iv, ExpressionCodegen codegen, JetCallElement constructorCall,
|
||||
ConstructorDescriptor constructorDescriptor, boolean isJavaSuperclass,
|
||||
ConstructorDescriptor constructorDescriptor,
|
||||
ConstructorFrameMap frameMap) {
|
||||
ClassDescriptor classDecl = constructorDescriptor.getContainingDeclaration();
|
||||
PsiElement declaration = state.getBindingContext().get(BindingContext.DESCRIPTOR_TO_DECLARATION, classDecl);
|
||||
@@ -300,13 +347,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
type = JetTypeMapper.jetImplementationType(classDecl);
|
||||
}
|
||||
|
||||
if (isJavaSuperclass) {
|
||||
iv.load(0, type);
|
||||
}
|
||||
else {
|
||||
iv.anew(type);
|
||||
iv.dup();
|
||||
}
|
||||
iv.load(0, type);
|
||||
|
||||
if (classDecl.getContainingDeclaration() instanceof ClassDescriptor) {
|
||||
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) {
|
||||
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 {
|
||||
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) {
|
||||
ConstructorDescriptor constructorDescriptor = state.getBindingContext().get(BindingContext.CONSTRUCTOR, constructor);
|
||||
if (constructorDescriptor == null) {
|
||||
@@ -351,7 +441,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
if (!(thisDescriptor instanceof ConstructorDescriptor)) {
|
||||
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 {
|
||||
throw new UnsupportedOperationException("unknown initializer type");
|
||||
@@ -371,7 +461,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
protected void generateTypeInfoInitializer(int firstTypeParameter, int typeParamCount, InstructionAdapter iv) {
|
||||
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(typeParamCount);
|
||||
iv.newarray(JetTypeMapper.TYPE_TYPEINFOPROJECTION);
|
||||
@@ -427,7 +517,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
iv.load(0, JetTypeMapper.TYPE_OBJECT);
|
||||
Type type = codegen.expressionType(initializer);
|
||||
if(propertyDescriptor.getOutType().isNullable())
|
||||
type = state.getTypeMapper().boxType(type);
|
||||
type = JetTypeMapper.boxType(type);
|
||||
codegen.gen(initializer, type);
|
||||
codegen.intermediateValueForProperty(propertyDescriptor, false, false).store(iv);
|
||||
}
|
||||
@@ -479,6 +569,9 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
}
|
||||
|
||||
private void generateGetTypeInfo() {
|
||||
if(myClass instanceof JetClass && ((JetClass)myClass).isTrait())
|
||||
return;
|
||||
|
||||
final MethodVisitor mv = v.visitMethod(Opcodes.ACC_PUBLIC,
|
||||
"getTypeInfo",
|
||||
"()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) {
|
||||
JetClass containingClass = PsiTreeUtil.getParentOfType(parent, JetClass.class);
|
||||
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);
|
||||
if (className == null) {
|
||||
@@ -226,16 +226,13 @@ public class JetTypeMapper {
|
||||
if (declaration instanceof JetObjectDeclaration) {
|
||||
return false;
|
||||
}
|
||||
return kind == OwnerKind.INTERFACE;
|
||||
return jetClass instanceof JetClass ? ((JetClass)jetClass).isTrait() : false;
|
||||
}
|
||||
|
||||
private static String jetJvmName(ClassDescriptor jetClass, OwnerKind kind) {
|
||||
if (jetClass.getKind() == ClassKind.OBJECT) {
|
||||
return jvmNameForImplementation(jetClass);
|
||||
}
|
||||
if (kind == OwnerKind.INTERFACE) {
|
||||
return jvmNameForInterface(jetClass);
|
||||
}
|
||||
else if (kind == OwnerKind.IMPLEMENTATION) {
|
||||
return jvmNameForImplementation(jetClass);
|
||||
}
|
||||
@@ -277,7 +274,7 @@ public class JetTypeMapper {
|
||||
}
|
||||
|
||||
public static String jvmNameForImplementation(ClassDescriptor descriptor) {
|
||||
return jvmNameForInterface(descriptor) + "$$Impl";
|
||||
return jvmNameForInterface(descriptor);
|
||||
}
|
||||
|
||||
public static String jvmNameForDelegatingImplementation(ClassDescriptor descriptor) {
|
||||
@@ -292,7 +289,7 @@ public class JetTypeMapper {
|
||||
else if (descriptor.getContainingDeclaration() instanceof ClassDescriptor) {
|
||||
ClassDescriptor classDescriptor = (ClassDescriptor) descriptor.getContainingDeclaration();
|
||||
if (kind instanceof OwnerKind.DelegateKind) {
|
||||
kind = OwnerKind.INTERFACE;
|
||||
kind = OwnerKind.IMPLEMENTATION;
|
||||
}
|
||||
else {
|
||||
assert classDescriptor != null;
|
||||
@@ -316,11 +313,11 @@ public class JetTypeMapper {
|
||||
}
|
||||
|
||||
@NotNull public Type mapReturnType(final JetType jetType) {
|
||||
return mapReturnType(jetType, OwnerKind.INTERFACE);
|
||||
return mapReturnType(jetType, OwnerKind.IMPLEMENTATION);
|
||||
}
|
||||
|
||||
@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) {
|
||||
@@ -483,7 +480,7 @@ public class JetTypeMapper {
|
||||
}
|
||||
else if (functionParent instanceof ClassDescriptor) {
|
||||
ClassDescriptor containingClass = (ClassDescriptor) functionParent;
|
||||
owner = jvmName(containingClass, OwnerKind.INTERFACE);
|
||||
owner = jvmName(containingClass, OwnerKind.IMPLEMENTATION);
|
||||
invokeOpcode = isInterface(containingClass, OwnerKind.INTERFACE)
|
||||
? Opcodes.INVOKEINTERFACE
|
||||
: Opcodes.INVOKEVIRTUAL;
|
||||
@@ -636,7 +633,6 @@ public class JetTypeMapper {
|
||||
Set<String> result = new HashSet<String>();
|
||||
final ClassDescriptor classDescriptor = bindingContext.get(BindingContext.CLASS, jetClass);
|
||||
if (classDescriptor != null) {
|
||||
result.add(jvmName(classDescriptor, OwnerKind.INTERFACE));
|
||||
result.add(jvmName(classDescriptor, OwnerKind.IMPLEMENTATION));
|
||||
}
|
||||
return result;
|
||||
|
||||
@@ -147,7 +147,7 @@ public class NamespaceCodegen {
|
||||
return;
|
||||
}
|
||||
|
||||
final Type jvmType = typeMapper.mapType(jetType, OwnerKind.INTERFACE);
|
||||
final Type jvmType = typeMapper.mapType(jetType);
|
||||
|
||||
v.aconst(jvmType);
|
||||
v.iconst(jetType.isNullable() ? 1 : 0);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package org.jetbrains.jet.codegen;
|
||||
|
||||
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.PropertySetterDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.VariableDescriptor;
|
||||
@@ -136,14 +137,16 @@ public class PropertyCodegen {
|
||||
if (kind == OwnerKind.NAMESPACE) {
|
||||
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;
|
||||
}
|
||||
|
||||
final String signature = state.getTypeMapper().mapGetterSignature(propertyDescriptor).getDescriptor();
|
||||
String getterName = getterName(propertyDescriptor.getName());
|
||||
MethodVisitor mv = v.visitMethod(flags, getterName, signature, null, null);
|
||||
if (kind != OwnerKind.INTERFACE) {
|
||||
if (!isTrait || kind instanceof OwnerKind.DelegateKind) {
|
||||
mv.visitCode();
|
||||
InstructionAdapter iv = new InstructionAdapter(mv);
|
||||
if (kind != OwnerKind.NAMESPACE) {
|
||||
@@ -176,13 +179,15 @@ public class PropertyCodegen {
|
||||
if (kind == OwnerKind.NAMESPACE) {
|
||||
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;
|
||||
}
|
||||
|
||||
final String signature = state.getTypeMapper().mapSetterSignature(propertyDescriptor).getDescriptor();
|
||||
MethodVisitor mv = v.visitMethod(flags, setterName(propertyDescriptor.getName()), signature, null, null);
|
||||
if (kind != OwnerKind.INTERFACE) {
|
||||
if (!isTrait || kind instanceof OwnerKind.DelegateKind) {
|
||||
mv.visitCode();
|
||||
InstructionAdapter iv = new InstructionAdapter(mv);
|
||||
final Type type = state.getTypeMapper().mapType(propertyDescriptor.getOutType());
|
||||
|
||||
@@ -186,8 +186,8 @@ public abstract class StackValue {
|
||||
else
|
||||
v.iconst(0);
|
||||
}
|
||||
else if (type.getSort() == Type.OBJECT && this.type.getSort() == Type.OBJECT) {
|
||||
// v.checkcast(type);
|
||||
else if (type.getSort() == Type.OBJECT && this.type.equals(JetTypeMapper.TYPE_OBJECT)) {
|
||||
v.checkcast(type);
|
||||
}
|
||||
else if (type.getSort() == Type.OBJECT) {
|
||||
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.Maps;
|
||||
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.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
||||
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.JetScope;
|
||||
|
||||
@@ -342,4 +346,15 @@ public class TypeUtils {
|
||||
|
||||
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.util.treeView.smartTree.TreeElement;
|
||||
import com.intellij.navigation.ItemPresentation;
|
||||
import com.intellij.openapi.editor.colors.TextAttributesKey;
|
||||
import com.intellij.openapi.util.Iconable;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
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)
|
||||
: 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 aai = A<A<Int>>(ai)
|
||||
if(aai.t.t != 1) return "fail"
|
||||
|
||||
/*
|
||||
aai.t.t = 2
|
||||
if(aai.t.t != 2) return "fail"
|
||||
|
||||
@@ -15,6 +15,6 @@ fun box() : String {
|
||||
|
||||
val abi = A<B<Int>>(B<Int>(1))
|
||||
if(abi.t.r != 1) return "fail"
|
||||
|
||||
*/
|
||||
return "OK"
|
||||
}
|
||||
@@ -14,7 +14,9 @@ public class ClassGenTest extends CodegenTestCase {
|
||||
|
||||
final Class aClass = loadClass("SimpleClass", generateClassesInFile());
|
||||
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 {
|
||||
@@ -77,9 +79,7 @@ public class ClassGenTest extends CodegenTestCase {
|
||||
final ClassFileFactory codegens = generateClassesInFile();
|
||||
final Class aClass = loadClass("Foo", codegens);
|
||||
assertNotNull(aClass.getMethod("x"));
|
||||
final Class implClass = loadClass("Foo$$Impl", codegens);
|
||||
assertNull(findMethodByName(implClass, "x"));
|
||||
assertNotNull(findMethodByName(implClass, "y"));
|
||||
assertNotNull(findMethodByName(aClass, "y"));
|
||||
}
|
||||
|
||||
public void testInheritedMethod() throws Exception {
|
||||
@@ -113,7 +113,7 @@ public class ClassGenTest extends CodegenTestCase {
|
||||
public void testAbstractClass() throws Exception {
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -155,6 +155,7 @@ public class ClassGenTest extends CodegenTestCase {
|
||||
public void testEnumClass() throws Exception {
|
||||
loadText("enum class Direction { NORTH; SOUTH; EAST; WEST }");
|
||||
final Class direction = loadAllClasses(generateClassesInFile()).get("Direction");
|
||||
System.out.println(generateToText());
|
||||
final Field north = direction.getField("NORTH");
|
||||
assertEquals(direction, north.getType());
|
||||
assertInstanceOf(north.get(null), direction);
|
||||
|
||||
@@ -197,8 +197,7 @@ public abstract class CodegenTestCase extends LightCodeInsightFixtureTestCase {
|
||||
}
|
||||
|
||||
protected Class loadImplementationClass(ClassFileFactory codegens, final String name) {
|
||||
loadClass(name, codegens);
|
||||
return loadClass(name + "$$Impl", codegens);
|
||||
return loadClass(name, codegens);
|
||||
}
|
||||
|
||||
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() {
|
||||
try {
|
||||
final Class implClass = theClass.getClassLoader().loadClass(theClass.getCanonicalName() + "$$Impl");
|
||||
final Class implClass = theClass.getClassLoader().loadClass(theClass.getCanonicalName());
|
||||
final Field classobj = implClass.getField("$classobj");
|
||||
return classobj.get(null);
|
||||
} catch (Exception e) {
|
||||
|
||||
Reference in New Issue
Block a user