read kotlin class objects from binary classes
This commit is contained in:
@@ -135,9 +135,15 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
v.visitInnerClass(innerClassInternalName, outerClassInernalName, innerClass.getName(), innerClassAccess);
|
||||
}
|
||||
|
||||
if (descriptor.getClassObjectDescriptor() != null) {
|
||||
int innerClassAccess = ACC_PUBLIC | ACC_FINAL | ACC_STATIC;
|
||||
String outerClassInernalName = typeMapper.mapType(descriptor.getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName();
|
||||
v.visitInnerClass(outerClassInernalName + JvmAbi.CLASS_OBJECT_SUFFIX, outerClassInernalName, JvmAbi.CLASS_OBJECT_CLASS_NAME, innerClassAccess);
|
||||
}
|
||||
|
||||
AnnotationCodegen.forClass(v.getVisitor()).genAnnotations(descriptor, typeMapper);
|
||||
|
||||
if(myClass instanceof JetClass && signature.getKotlinGenericSignature() != null) {
|
||||
if (signature.getKotlinGenericSignature() != null) {
|
||||
AnnotationVisitor annotationVisitor = v.newAnnotation(myClass, JvmStdlibNames.JET_CLASS.getDescriptor(), true);
|
||||
annotationVisitor.visit(JvmStdlibNames.JET_CLASS_SIGNATURE, signature.getKotlinGenericSignature());
|
||||
annotationVisitor.visitEnd();
|
||||
|
||||
@@ -170,7 +170,7 @@ public class JetTypeMapper {
|
||||
public static String getLocalNameForObject(JetObjectDeclaration object) {
|
||||
PsiElement parent = object.getParent();
|
||||
if (parent instanceof JetClassObject) {
|
||||
return "ClassObject$";
|
||||
return JvmAbi.CLASS_OBJECT_CLASS_NAME;
|
||||
}
|
||||
|
||||
return null;
|
||||
@@ -755,7 +755,7 @@ public class JetTypeMapper {
|
||||
|
||||
ClassDescriptor myClass = bindingContext.get(BindingContext.CLASS, expression);
|
||||
if(CodegenUtil.isClassObject(myClass)) {
|
||||
return mapType(aClass.getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName() + "$ClassObject$";
|
||||
return mapType(aClass.getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName() + JvmAbi.CLASS_OBJECT_SUFFIX;
|
||||
}
|
||||
else
|
||||
baseName = classNameForAnonymousClass((JetElement) container);
|
||||
|
||||
+45
-10
@@ -31,6 +31,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
|
||||
import org.jetbrains.jet.lang.psi.JetPsiUtil;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
|
||||
import org.jetbrains.jet.lang.resolve.OverrideResolver;
|
||||
@@ -406,8 +407,10 @@ public class JavaDescriptorResolver {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO
|
||||
//classData.classDescriptor.setClassObjectDescriptor(createClassObjectDescriptor(classData.classDescriptor));
|
||||
MutableClassDescriptorLite classObject = createClassObjectDescriptor(classData.classDescriptor, psiClass);
|
||||
if (classObject != null) {
|
||||
classData.classDescriptor.setClassObjectDescriptor(classObject);
|
||||
}
|
||||
|
||||
semanticServices.getTrace().record(BindingContext.CLASS, psiClass, classData.classDescriptor);
|
||||
|
||||
@@ -420,19 +423,47 @@ public class JavaDescriptorResolver {
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private PsiClass getInnerClassClassObject(@NotNull PsiClass outer) {
|
||||
for (PsiClass inner : outer.getInnerClasses()) {
|
||||
if (inner.getName().equals(JvmAbi.CLASS_OBJECT_CLASS_NAME)) {
|
||||
return inner;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
* @see #createJavaNamespaceDescriptor(com.intellij.psi.PsiClass)
|
||||
*/
|
||||
@Nullable
|
||||
private MutableClassDescriptorLite createClassObjectDescriptor(@NotNull ClassDescriptor containing, @NotNull PsiClass psiClass) {
|
||||
MutableClassDescriptorLite classObjectDescriptor = new MutableClassDescriptorLite(containing, ClassKind.OBJECT);
|
||||
classObjectDescriptor.setName("<TODO>"); // TODO
|
||||
classObjectDescriptor.setModality(Modality.FINAL);
|
||||
classObjectDescriptor.setTypeParameterDescriptors(new ArrayList<TypeParameterDescriptor>(0));
|
||||
classObjectDescriptor.createTypeConstructor();
|
||||
classObjectDescriptor.setScopeForMemberLookup(new JavaClassMembersScope(classObjectDescriptor, psiClass, semanticServices, true));
|
||||
return classObjectDescriptor;
|
||||
PsiClass classObjectPsiClass = getInnerClassClassObject(psiClass);
|
||||
if (classObjectPsiClass == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
ResolverBinaryClassData classData = new ResolverBinaryClassData();
|
||||
classData.kotlin = true;
|
||||
classData.classDescriptor = new MutableClassDescriptorLite(containing, ClassKind.OBJECT);
|
||||
|
||||
classDescriptorCache.put(classObjectPsiClass.getQualifiedName(), classData);
|
||||
|
||||
classData.classDescriptor.setSupertypes(getSupertypes(new PsiClassWrapper(classObjectPsiClass), classData.classDescriptor, new ArrayList<TypeParameterDescriptor>(0)));
|
||||
classData.classDescriptor.setName(JetPsiUtil.NO_NAME_PROVIDED); // TODO
|
||||
classData.classDescriptor.setModality(Modality.FINAL);
|
||||
classData.classDescriptor.setTypeParameterDescriptors(new ArrayList<TypeParameterDescriptor>(0));
|
||||
classData.classDescriptor.createTypeConstructor();
|
||||
classData.classDescriptor.setScopeForMemberLookup(new JavaClassMembersScope(classData.classDescriptor, classObjectPsiClass, semanticServices, false));
|
||||
|
||||
// TODO: wrong: class objects do not need visible constructors
|
||||
ConstructorDescriptorImpl constructor = new ConstructorDescriptorImpl(classData.classDescriptor, new ArrayList<AnnotationDescriptor>(0), true);
|
||||
constructor.setReturnType(classData.classDescriptor.getDefaultType());
|
||||
constructor.initialize(new ArrayList<TypeParameterDescriptor>(0), new ArrayList<ValueParameterDescriptor>(0), Visibility.PUBLIC);
|
||||
|
||||
classData.classDescriptor.addConstructor(constructor, null);
|
||||
return classData.classDescriptor;
|
||||
}
|
||||
|
||||
private List<TypeParameterDescriptorInitialization> createUninitializedClassTypeParameters(PsiClass psiClass, ResolverBinaryClassData classData, TypeVariableResolver typeVariableResolver) {
|
||||
@@ -679,7 +710,7 @@ public class JavaDescriptorResolver {
|
||||
}
|
||||
}
|
||||
|
||||
private Collection<? extends JetType> getSupertypes(PsiClassWrapper psiClass, ClassDescriptor classDescriptor, List<TypeParameterDescriptor> typeParameters) {
|
||||
private Collection<JetType> getSupertypes(PsiClassWrapper psiClass, ClassDescriptor classDescriptor, List<TypeParameterDescriptor> typeParameters) {
|
||||
final List<JetType> result = new ArrayList<JetType>();
|
||||
|
||||
if (psiClass.getJetClass().signature().length() > 0) {
|
||||
@@ -1271,6 +1302,7 @@ public class JavaDescriptorResolver {
|
||||
}
|
||||
|
||||
private ResolverScopeData getResolverScopeData(@NotNull ClassOrNamespaceDescriptor owner, PsiClassWrapper psiClass) {
|
||||
// TODO: store scopeData in Java*Scope
|
||||
ResolverScopeData scopeData;
|
||||
boolean staticMembers;
|
||||
if (owner instanceof JavaNamespaceDescriptor) {
|
||||
@@ -1576,6 +1608,9 @@ public class JavaDescriptorResolver {
|
||||
// TODO: hack against inner classes
|
||||
continue;
|
||||
}
|
||||
if (innerPsiClass.getName().equals(JvmAbi.CLASS_OBJECT_CLASS_NAME)) {
|
||||
continue;
|
||||
}
|
||||
r.add(resolveClass(innerPsiClass));
|
||||
}
|
||||
return r;
|
||||
|
||||
@@ -25,6 +25,8 @@ public class JvmAbi {
|
||||
public static final String GETTER_PREFIX = "get";
|
||||
public static final String SETTER_PREFIX = "set";
|
||||
public static final String PACKAGE_CLASS = "namespace";
|
||||
public static final String CLASS_OBJECT_SUFFIX = "$ClassObject$";
|
||||
public static final String CLASS_OBJECT_CLASS_NAME = "ClassObject$";
|
||||
|
||||
public static final JvmClassName JETBRAINS_NOT_NULL_ANNOTATION = new JvmClassName("org.jetbrains.annotations.NotNull");
|
||||
}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
package test
|
||||
|
||||
class ClassObjectDeclaresProperty {
|
||||
class object {
|
||||
val i = 1
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
namespace test
|
||||
|
||||
final class test.ClassObjectDeclaresProperty : jet.Any {
|
||||
final /*constructor*/ fun <init>(): test.ClassObjectDeclaresProperty
|
||||
final object test.ClassObjectDeclaresProperty.<no name provided> : jet.Any {
|
||||
final /*constructor*/ fun <init>(): test.ClassObjectDeclaresProperty.<no name provided>
|
||||
val i: jet.Int
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package test
|
||||
|
||||
class ClassObjectDeclaresProperty {
|
||||
class object {
|
||||
var s = ""
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
namespace test
|
||||
|
||||
final class test.ClassObjectDeclaresProperty : jet.Any {
|
||||
final /*constructor*/ fun <init>(): test.ClassObjectDeclaresProperty
|
||||
final object test.ClassObjectDeclaresProperty.<no name provided> : jet.Any {
|
||||
final /*constructor*/ fun <init>(): test.ClassObjectDeclaresProperty.<no name provided>
|
||||
var s: jet.String
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package test
|
||||
|
||||
trait Bbb
|
||||
|
||||
class ClassObjectextendsTrait {
|
||||
class object : Bbb {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
namespace test
|
||||
|
||||
abstract trait test.Bbb : jet.Any {
|
||||
}
|
||||
final class test.ClassObjectextendsTrait : jet.Any {
|
||||
final /*constructor*/ fun <init>(): test.ClassObjectextendsTrait
|
||||
final object test.ClassObjectextendsTrait.<no name provided> : test.Bbb {
|
||||
final /*constructor*/ fun <init>(): test.ClassObjectextendsTrait.<no name provided>
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package test
|
||||
|
||||
trait Bbb<P>
|
||||
|
||||
class ClassObjectExtendsTraitWithTP {
|
||||
class object : Bbb<String> {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
namespace test
|
||||
|
||||
final class test.ClassObjectExtendsTraitWithTP : jet.Any {
|
||||
final /*constructor*/ fun <init>(): test.ClassObjectExtendsTraitWithTP
|
||||
final object test.ClassObjectExtendsTraitWithTP.<no name provided> : test.Bbb<jet.String> {
|
||||
final /*constructor*/ fun <init>(): test.ClassObjectExtendsTraitWithTP.<no name provided>
|
||||
}
|
||||
}
|
||||
abstract trait test.Bbb</*0,r*/ P : jet.Any?> : jet.Any {
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package test
|
||||
|
||||
class SimpleClassObject() {
|
||||
class object {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
namespace test
|
||||
|
||||
final class test.SimpleClassObject : jet.Any {
|
||||
final /*constructor*/ fun <init>(): test.SimpleClassObject
|
||||
final object test.SimpleClassObject.<no name provided> : jet.Any {
|
||||
final /*constructor*/ fun <init>(): test.SimpleClassObject.<no name provided>
|
||||
}
|
||||
}
|
||||
@@ -34,6 +34,7 @@ import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.VariableDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
|
||||
import org.jetbrains.jet.lang.psi.JetPsiUtil;
|
||||
import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolver;
|
||||
import org.jetbrains.jet.lang.resolve.java.JavaNamespaceDescriptor;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
||||
@@ -316,7 +317,7 @@ class NamespaceComparator {
|
||||
sb.append(modality.name().toLowerCase());
|
||||
}
|
||||
|
||||
public void serialize(JetType type) {
|
||||
public void serialize(@NotNull JetType type) {
|
||||
serialize(type.getConstructor().getDeclarationDescriptor());
|
||||
if (!type.getArguments().isEmpty()) {
|
||||
sb.append("<");
|
||||
|
||||
Reference in New Issue
Block a user