From f33669bc834a5c29eca214657d0646c9654d0822 Mon Sep 17 00:00:00 2001 From: Evgeny Gerashchenko Date: Wed, 3 Oct 2012 23:02:51 +0400 Subject: [PATCH] KT-1973 Loading object declarations from compiled classes. #KT-1973 in progress --- .../JavaDescriptorPropertiesResolver.java | 20 +++++--- .../resolve/java/JavaDescriptorResolver.java | 31 +++++++++---- .../java/JavaDescriptorResolverHelper.java | 46 ++++++++++++------- .../resolve/java/scope/JavaPackageScope.java | 3 +- 4 files changed, 66 insertions(+), 34 deletions(-) diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorPropertiesResolver.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorPropertiesResolver.java index b2dfda55299..20fc7b7659e 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorPropertiesResolver.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorPropertiesResolver.java @@ -116,10 +116,11 @@ public final class JavaDescriptorPropertiesResolver { DeclarationDescriptor realOwner = getRealOwner(owner, scopeData, characteristicMember.getMember().isStatic()); boolean isEnumEntry = DescriptorUtils.isEnumClassObject(realOwner); + boolean isPropertyForNamedObject = members.field != null && JvmAbi.INSTANCE_FIELD.equals(members.field.getMember().getName()); PropertyDescriptor propertyDescriptor = new PropertyDescriptor( realOwner, javaDescriptorResolver.resolveAnnotations(characteristicMember.getMember().getPsiMember()), - JavaDescriptorResolver.resolveModality(characteristicMember.getMember(), isFinal || isEnumEntry), + JavaDescriptorResolver.resolveModality(characteristicMember.getMember(), isFinal || isEnumEntry || isPropertyForNamedObject), visibility, isVar, propertyName, @@ -206,6 +207,16 @@ public final class JavaDescriptorPropertiesResolver { 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); } @@ -377,11 +388,8 @@ public final class JavaDescriptorPropertiesResolver { @NotNull ResolverScopeData scopeData, boolean isStatic ) { - final PsiClass psiClass = scopeData.getPsiClass(); - assert psiClass != null; - - boolean isEnum = psiClass.isEnum(); - if (isEnum && isStatic) { + PsiClass psiClass = scopeData.getPsiClass(); + if (psiClass != null && psiClass.isEnum() && isStatic) { final String qualifiedName = psiClass.getQualifiedName(); assert qualifiedName != null; final ClassDescriptor classDescriptor = javaDescriptorResolver.resolveClass(new FqName(qualifiedName)); diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java index 59e6e8653f6..f024b446079 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java @@ -230,7 +230,8 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes checkPsiClassIsNotJet(psiClass); 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); // class may be resolved during resolution of parent @@ -257,7 +258,7 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes classData.getClassDescriptor().setTypeParameterDescriptors(typeParameters); classData.getClassDescriptor().setSupertypes(supertypes); - classData.getClassDescriptor().setVisibility(resolveVisibility(psiClass, JetClassAnnotation.get(psiClass))); + classData.getClassDescriptor().setVisibility(resolveVisibility(psiClass, jetClassAnnotation)); Modality modality; if (classData.getClassDescriptor().getKind() == ClassKind.ANNOTATION_CLASS) { modality = Modality.FINAL; @@ -289,6 +290,20 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes 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 public Collection resolveConstructors(@NotNull ResolverClassData classData) { Collection constructors = Lists.newArrayList(); @@ -892,11 +907,7 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes public Set resolveFieldGroupByName(@NotNull Name fieldName, @NotNull ResolverScopeData scopeData) { - final PsiClass psiClass = scopeData.getPsiClass(); - if (psiClass == null) { - return Collections.emptySet(); - } - + PsiClass psiClass = scopeData.getPsiClass(); getResolverScopeData(scopeData); NamedMembers namedMembers = scopeData.getNamedMembersMap().get(fieldName); @@ -904,9 +915,9 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes return Collections.emptySet(); } - final String qualifiedName = psiClass.getQualifiedName(); - javaDescriptorPropertiesResolver.resolveNamedGroupProperties( - scopeData.getClassOrNamespaceDescriptor(), scopeData, namedMembers, fieldName, + //noinspection ConstantConditions + String qualifiedName = psiClass == null ? scopeData.getPsiPackage().getQualifiedName() : psiClass.getQualifiedName(); + javaDescriptorPropertiesResolver.resolveNamedGroupProperties(scopeData.getClassOrNamespaceDescriptor(), scopeData, namedMembers, fieldName, "class or namespace " + qualifiedName); return namedMembers.propertyDescriptors; diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolverHelper.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolverHelper.java index 12050bd0d60..1bb4098c234 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolverHelper.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolverHelper.java @@ -16,9 +16,7 @@ package org.jetbrains.jet.lang.resolve.java; -import com.intellij.psi.PsiField; -import com.intellij.psi.PsiMethod; -import com.intellij.psi.PsiType; +import com.intellij.psi.*; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolveData.ResolverScopeData; 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.name.Name; -import java.util.Collections; import java.util.HashMap; import java.util.Map; @@ -39,20 +36,27 @@ class JavaDescriptorResolverHelper { private static class Builder { private final PsiClassWrapper psiClass; + private final PsiPackage psiPackage; private final boolean staticMembers; private final boolean kotlin; private final Map namedMembersMap = new HashMap(); - private Builder(PsiClassWrapper psiClass, boolean staticMembers, boolean kotlin) { + private Builder(PsiClassWrapper psiClass, PsiPackage psiPackage, boolean staticMembers, boolean kotlin) { this.psiClass = psiClass; + this.psiPackage = psiPackage; this.staticMembers = staticMembers; this.kotlin = kotlin; } public void run() { - processFields(); - processMethods(); + if (psiClass != null) { + processFields(); + processMethods(); + } + if (psiPackage != null) { + processNeighborClasses(); + } } 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 static Map getNamedMembers(@NotNull ResolverScopeData resolverScopeData) { - if (resolverScopeData.getPsiClass() != null) { - @SuppressWarnings("ConstantConditions") - Builder builder = new Builder(new PsiClassWrapper(resolverScopeData.getPsiClass()), resolverScopeData.isStaticMembers(), resolverScopeData.isKotlin()); - builder.run(); - return builder.namedMembersMap; - } - else { - return Collections.emptyMap(); - } + PsiClassWrapper aClass = resolverScopeData.getPsiClass() != null ? new PsiClassWrapper(resolverScopeData.getPsiClass()) : null; + Builder builder = new Builder(aClass, resolverScopeData.getPsiPackage(), resolverScopeData.isStaticMembers(), resolverScopeData.isKotlin()); + builder.run(); + return builder.namedMembersMap; } diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/scope/JavaPackageScope.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/scope/JavaPackageScope.java index 093f92d2c57..b680e9107dc 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/scope/JavaPackageScope.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/scope/JavaPackageScope.java @@ -53,8 +53,7 @@ public class JavaPackageScope extends JavaClassOrPackageScope { @Override public ClassDescriptor getObjectDescriptor(@NotNull Name name) { - // TODO - return null; + return semanticServices.getDescriptorResolver().resolveClass(packageFQN.child(name), DescriptorSearchRule.IGNORE_IF_FOUND_IN_KOTLIN); } @Override