提交 e0fae55e 编写于 作者: S Stepan Koltsov

read kotlin class objects from binary classes

上级 b9ba7c6b
......@@ -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);
......
......@@ -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");
}
package test
class ClassObjectDeclaresProperty {
class object {
val i = 1
}
}
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
}
}
package test
class ClassObjectDeclaresProperty {
class object {
var s = ""
}
}
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
}
}
package test
trait Bbb
class ClassObjectextendsTrait {
class object : Bbb {
}
}
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>
}
}
package test
trait Bbb<P>
class ClassObjectExtendsTraitWithTP {
class object : Bbb<String> {
}
}
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 {
}
package test
class SimpleClassObject() {
class object {
}
}
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("<");
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册