KT-1973 Loading object declarations from compiled classes.

#KT-1973 in progress
This commit is contained in:
Evgeny Gerashchenko
2012-10-03 23:02:51 +04:00
parent 998095c55c
commit f33669bc83
4 changed files with 66 additions and 34 deletions
@@ -116,10 +116,11 @@ public final class JavaDescriptorPropertiesResolver {
DeclarationDescriptor realOwner = getRealOwner(owner, scopeData, characteristicMember.getMember().isStatic()); DeclarationDescriptor realOwner = getRealOwner(owner, scopeData, characteristicMember.getMember().isStatic());
boolean isEnumEntry = DescriptorUtils.isEnumClassObject(realOwner); boolean isEnumEntry = DescriptorUtils.isEnumClassObject(realOwner);
boolean isPropertyForNamedObject = members.field != null && JvmAbi.INSTANCE_FIELD.equals(members.field.getMember().getName());
PropertyDescriptor propertyDescriptor = new PropertyDescriptor( PropertyDescriptor propertyDescriptor = new PropertyDescriptor(
realOwner, realOwner,
javaDescriptorResolver.resolveAnnotations(characteristicMember.getMember().getPsiMember()), javaDescriptorResolver.resolveAnnotations(characteristicMember.getMember().getPsiMember()),
JavaDescriptorResolver.resolveModality(characteristicMember.getMember(), isFinal || isEnumEntry), JavaDescriptorResolver.resolveModality(characteristicMember.getMember(), isFinal || isEnumEntry || isPropertyForNamedObject),
visibility, visibility,
isVar, isVar,
propertyName, propertyName,
@@ -206,6 +207,16 @@ public final class JavaDescriptorPropertiesResolver {
trace.record(BindingContext.VARIABLE, characteristicMember.getMember().getPsiMember(), propertyDescriptor); trace.record(BindingContext.VARIABLE, characteristicMember.getMember().getPsiMember(), propertyDescriptor);
} }
if (isPropertyForNamedObject) {
ClassDescriptor objectDescriptor = (ClassDescriptor) propertyType.getConstructor().getDeclarationDescriptor();
assert objectDescriptor.getKind() == ClassKind.OBJECT;
assert objectDescriptor.getContainingDeclaration() == realOwner;
trace.record(BindingContext.OBJECT_DECLARATION_CLASS, propertyDescriptor, objectDescriptor);
}
propertiesFromCurrent.add(propertyDescriptor); propertiesFromCurrent.add(propertyDescriptor);
} }
@@ -377,11 +388,8 @@ public final class JavaDescriptorPropertiesResolver {
@NotNull ResolverScopeData scopeData, @NotNull ResolverScopeData scopeData,
boolean isStatic boolean isStatic
) { ) {
final PsiClass psiClass = scopeData.getPsiClass(); PsiClass psiClass = scopeData.getPsiClass();
assert psiClass != null; if (psiClass != null && psiClass.isEnum() && isStatic) {
boolean isEnum = psiClass.isEnum();
if (isEnum && isStatic) {
final String qualifiedName = psiClass.getQualifiedName(); final String qualifiedName = psiClass.getQualifiedName();
assert qualifiedName != null; assert qualifiedName != null;
final ClassDescriptor classDescriptor = javaDescriptorResolver.resolveClass(new FqName(qualifiedName)); final ClassDescriptor classDescriptor = javaDescriptorResolver.resolveClass(new FqName(qualifiedName));
@@ -230,7 +230,8 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes
checkPsiClassIsNotJet(psiClass); checkPsiClassIsNotJet(psiClass);
Name name = Name.identifier(psiClass.getName()); Name name = Name.identifier(psiClass.getName());
ClassKind kind = psiClass.isInterface() ? (psiClass.isAnnotationType() ? ClassKind.ANNOTATION_CLASS : ClassKind.TRAIT) : (psiClass.isEnum() ? ClassKind.ENUM_CLASS : ClassKind.CLASS); JetClassAnnotation jetClassAnnotation = JetClassAnnotation.get(psiClass);
ClassKind kind = getClassKind(psiClass, jetClassAnnotation);
ClassOrNamespaceDescriptor containingDeclaration = resolveParentDescriptor(psiClass); ClassOrNamespaceDescriptor containingDeclaration = resolveParentDescriptor(psiClass);
// class may be resolved during resolution of parent // class may be resolved during resolution of parent
@@ -257,7 +258,7 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes
classData.getClassDescriptor().setTypeParameterDescriptors(typeParameters); classData.getClassDescriptor().setTypeParameterDescriptors(typeParameters);
classData.getClassDescriptor().setSupertypes(supertypes); classData.getClassDescriptor().setSupertypes(supertypes);
classData.getClassDescriptor().setVisibility(resolveVisibility(psiClass, JetClassAnnotation.get(psiClass))); classData.getClassDescriptor().setVisibility(resolveVisibility(psiClass, jetClassAnnotation));
Modality modality; Modality modality;
if (classData.getClassDescriptor().getKind() == ClassKind.ANNOTATION_CLASS) { if (classData.getClassDescriptor().getKind() == ClassKind.ANNOTATION_CLASS) {
modality = Modality.FINAL; modality = Modality.FINAL;
@@ -289,6 +290,20 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes
return classData; return classData;
} }
private static ClassKind getClassKind(@NotNull PsiClass psiClass, @NotNull JetClassAnnotation jetClassAnnotation) {
if (psiClass.isInterface()) {
return (psiClass.isAnnotationType() ? ClassKind.ANNOTATION_CLASS : ClassKind.TRAIT);
}
else {
if (psiClass.isEnum()) {
return ClassKind.ENUM_CLASS;
}
else {
return jetClassAnnotation.kind() == JvmStdlibNames.FLAG_CLASS_KIND_OBJECT ? ClassKind.OBJECT : ClassKind.CLASS;
}
}
}
@NotNull @NotNull
public Collection<ConstructorDescriptor> resolveConstructors(@NotNull ResolverClassData classData) { public Collection<ConstructorDescriptor> resolveConstructors(@NotNull ResolverClassData classData) {
Collection<ConstructorDescriptor> constructors = Lists.newArrayList(); Collection<ConstructorDescriptor> constructors = Lists.newArrayList();
@@ -892,11 +907,7 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes
public Set<VariableDescriptor> resolveFieldGroupByName(@NotNull Name fieldName, @NotNull ResolverScopeData scopeData) { public Set<VariableDescriptor> resolveFieldGroupByName(@NotNull Name fieldName, @NotNull ResolverScopeData scopeData) {
final PsiClass psiClass = scopeData.getPsiClass(); PsiClass psiClass = scopeData.getPsiClass();
if (psiClass == null) {
return Collections.emptySet();
}
getResolverScopeData(scopeData); getResolverScopeData(scopeData);
NamedMembers namedMembers = scopeData.getNamedMembersMap().get(fieldName); NamedMembers namedMembers = scopeData.getNamedMembersMap().get(fieldName);
@@ -904,9 +915,9 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes
return Collections.emptySet(); return Collections.emptySet();
} }
final String qualifiedName = psiClass.getQualifiedName(); //noinspection ConstantConditions
javaDescriptorPropertiesResolver.resolveNamedGroupProperties( String qualifiedName = psiClass == null ? scopeData.getPsiPackage().getQualifiedName() : psiClass.getQualifiedName();
scopeData.getClassOrNamespaceDescriptor(), scopeData, namedMembers, fieldName, javaDescriptorPropertiesResolver.resolveNamedGroupProperties(scopeData.getClassOrNamespaceDescriptor(), scopeData, namedMembers, fieldName,
"class or namespace " + qualifiedName); "class or namespace " + qualifiedName);
return namedMembers.propertyDescriptors; return namedMembers.propertyDescriptors;
@@ -16,9 +16,7 @@
package org.jetbrains.jet.lang.resolve.java; package org.jetbrains.jet.lang.resolve.java;
import com.intellij.psi.PsiField; import com.intellij.psi.*;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.PsiType;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolveData.ResolverScopeData; import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolveData.ResolverScopeData;
import org.jetbrains.jet.lang.resolve.java.prop.PropertyNameUtils; import org.jetbrains.jet.lang.resolve.java.prop.PropertyNameUtils;
@@ -26,7 +24,6 @@ import org.jetbrains.jet.lang.resolve.java.prop.PropertyParseResult;
import org.jetbrains.jet.lang.resolve.java.wrapper.*; import org.jetbrains.jet.lang.resolve.java.wrapper.*;
import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.lang.resolve.name.Name;
import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
@@ -39,20 +36,27 @@ class JavaDescriptorResolverHelper {
private static class Builder { private static class Builder {
private final PsiClassWrapper psiClass; private final PsiClassWrapper psiClass;
private final PsiPackage psiPackage;
private final boolean staticMembers; private final boolean staticMembers;
private final boolean kotlin; private final boolean kotlin;
private final Map<Name, NamedMembers> namedMembersMap = new HashMap<Name, NamedMembers>(); private final Map<Name, NamedMembers> namedMembersMap = new HashMap<Name, NamedMembers>();
private Builder(PsiClassWrapper psiClass, boolean staticMembers, boolean kotlin) { private Builder(PsiClassWrapper psiClass, PsiPackage psiPackage, boolean staticMembers, boolean kotlin) {
this.psiClass = psiClass; this.psiClass = psiClass;
this.psiPackage = psiPackage;
this.staticMembers = staticMembers; this.staticMembers = staticMembers;
this.kotlin = kotlin; this.kotlin = kotlin;
} }
public void run() { public void run() {
processFields(); if (psiClass != null) {
processMethods(); processFields();
processMethods();
}
if (psiPackage != null) {
processNeighborClasses();
}
} }
private NamedMembers getNamedMembers(Name name) { private NamedMembers getNamedMembers(Name name) {
@@ -204,20 +208,30 @@ class JavaDescriptorResolverHelper {
} }
} }
} }
private void processNeighborClasses() {
for (PsiClass neighborPsiClass : psiPackage.getClasses()) {
if (!neighborPsiClass.isPhysical()) { // to filter out JetLightClasses
continue;
}
PsiField instanceField = neighborPsiClass.findFieldByName(JvmAbi.INSTANCE_FIELD, false);
if (instanceField != null) {
NamedMembers namedMembers = getNamedMembers(Name.identifier(neighborPsiClass.getName()));
TypeSource type = new TypeSource("", instanceField.getType(), instanceField);
namedMembers.addPropertyAccessor(new PropertyAccessorData(new PsiFieldWrapper(instanceField), type, null));
}
}
}
} }
@NotNull @NotNull
static Map<Name, NamedMembers> getNamedMembers(@NotNull ResolverScopeData resolverScopeData) { static Map<Name, NamedMembers> getNamedMembers(@NotNull ResolverScopeData resolverScopeData) {
if (resolverScopeData.getPsiClass() != null) { PsiClassWrapper aClass = resolverScopeData.getPsiClass() != null ? new PsiClassWrapper(resolverScopeData.getPsiClass()) : null;
@SuppressWarnings("ConstantConditions") Builder builder = new Builder(aClass, resolverScopeData.getPsiPackage(), resolverScopeData.isStaticMembers(), resolverScopeData.isKotlin());
Builder builder = new Builder(new PsiClassWrapper(resolverScopeData.getPsiClass()), resolverScopeData.isStaticMembers(), resolverScopeData.isKotlin()); builder.run();
builder.run(); return builder.namedMembersMap;
return builder.namedMembersMap;
}
else {
return Collections.emptyMap();
}
} }
@@ -53,8 +53,7 @@ public class JavaPackageScope extends JavaClassOrPackageScope {
@Override @Override
public ClassDescriptor getObjectDescriptor(@NotNull Name name) { public ClassDescriptor getObjectDescriptor(@NotNull Name name) {
// TODO return semanticServices.getDescriptorResolver().resolveClass(packageFQN.child(name), DescriptorSearchRule.IGNORE_IF_FOUND_IN_KOTLIN);
return null;
} }
@Override @Override