From 1a6f1af0e5d2bda2f8636530f3d844ab68563188 Mon Sep 17 00:00:00 2001 From: Nikolay Krasko Date: Fri, 28 Sep 2012 22:30:28 +0400 Subject: [PATCH] Move ResolverData classes and property resolve to separate classes from JavaDescriptorResolver --- .../java/ClassDescriptorFromJvmBytecode.java | 7 +- .../resolve/java/JavaClassMembersScope.java | 3 +- .../resolve/java/JavaClassOrPackageScope.java | 5 +- .../JavaDescriptorPropertiesResolver.java | 411 +++++++++++++ .../java/JavaDescriptorResolveData.java | 203 +++++++ .../resolve/java/JavaDescriptorResolver.java | 542 +----------------- .../java/JavaDescriptorResolverHelper.java | 4 +- .../java/JavaDescriptorSignatureResolver.java | 12 +- .../lang/resolve/java/JavaPackageScope.java | 3 +- .../resolve/java/prop/PropertyNameUtils.java | 3 + 10 files changed, 664 insertions(+), 529 deletions(-) create mode 100644 compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorPropertiesResolver.java create mode 100644 compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolveData.java diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/ClassDescriptorFromJvmBytecode.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/ClassDescriptorFromJvmBytecode.java index e2224749753..50e47588b90 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/ClassDescriptorFromJvmBytecode.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/ClassDescriptorFromJvmBytecode.java @@ -37,7 +37,7 @@ public class ClassDescriptorFromJvmBytecode extends MutableClassDescriptorLite { @NotNull private final JavaDescriptorResolver javaDescriptorResolver; @NotNull - private final JavaDescriptorResolver.ResolverClassData resolverBinaryClassData; + private final JavaDescriptorResolveData.ResolverClassData resolverBinaryClassData; // lazy @@ -49,15 +49,14 @@ public class ClassDescriptorFromJvmBytecode extends MutableClassDescriptorLite { @NotNull JavaDescriptorResolver javaDescriptorResolver) { super(containingDeclaration, kind); this.javaDescriptorResolver = javaDescriptorResolver; - this.resolverBinaryClassData = new JavaDescriptorResolver.ResolverBinaryClassData(psiClass, fqName, this); + this.resolverBinaryClassData = new JavaDescriptorResolveData.ResolverBinaryClassData(psiClass, fqName, this); } @NotNull - public JavaDescriptorResolver.ResolverClassData getResolverBinaryClassData() { + public JavaDescriptorResolveData.ResolverClassData getResolverBinaryClassData() { return resolverBinaryClassData; } - @NotNull @Override public Collection getConstructors() { diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaClassMembersScope.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaClassMembersScope.java index 0265534a097..a1d9b78fe00 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaClassMembersScope.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaClassMembersScope.java @@ -24,6 +24,7 @@ import org.jetbrains.jet.lang.descriptors.ClassDescriptor; import org.jetbrains.jet.lang.descriptors.ClassifierDescriptor; import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor; +import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolveData.ResolverScopeData; import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.jet.lang.resolve.name.LabelName; import org.jetbrains.jet.lang.resolve.name.Name; @@ -41,7 +42,7 @@ public class JavaClassMembersScope extends JavaClassOrPackageScope { public JavaClassMembersScope( @NotNull JavaSemanticServices semanticServices, - @NotNull JavaDescriptorResolver.ResolverScopeData resolverScopeData) { + @NotNull ResolverScopeData resolverScopeData) { super(semanticServices, resolverScopeData); if (resolverScopeData.psiClass == null) { diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaClassOrPackageScope.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaClassOrPackageScope.java index faf0c4f0fa3..96350d57c0f 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaClassOrPackageScope.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaClassOrPackageScope.java @@ -23,6 +23,7 @@ import com.intellij.psi.PsiModifier; import com.intellij.psi.PsiPackage; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.descriptors.*; +import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolveData.ResolverScopeData; import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.lang.resolve.scopes.JetScopeImpl; @@ -37,14 +38,14 @@ public abstract class JavaClassOrPackageScope extends JetScopeImpl { @NotNull protected final JavaSemanticServices semanticServices; @NotNull - protected final JavaDescriptorResolver.ResolverScopeData resolverScopeData; + protected final ResolverScopeData resolverScopeData; // cache private Collection allDescriptors; protected JavaClassOrPackageScope( @NotNull JavaSemanticServices semanticServices, - @NotNull JavaDescriptorResolver.ResolverScopeData resolverScopeData) { + @NotNull ResolverScopeData resolverScopeData) { this.semanticServices = semanticServices; this.resolverScopeData = resolverScopeData; } 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 new file mode 100644 index 00000000000..60bea38f7a2 --- /dev/null +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorPropertiesResolver.java @@ -0,0 +1,411 @@ +/* + * Copyright 2010-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.lang.resolve.java; + +import com.google.common.collect.Sets; +import com.intellij.openapi.util.Pair; +import com.intellij.psi.*; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.lang.descriptors.*; +import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; +import org.jetbrains.jet.lang.resolve.BindingContext; +import org.jetbrains.jet.lang.resolve.BindingTrace; +import org.jetbrains.jet.lang.resolve.DescriptorUtils; +import org.jetbrains.jet.lang.resolve.OverrideResolver; +import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolveData.ResolverScopeData; +import org.jetbrains.jet.lang.resolve.java.kt.DescriptorKindUtils; +import org.jetbrains.jet.lang.resolve.java.kt.JetMethodAnnotation; +import org.jetbrains.jet.lang.resolve.name.FqName; +import org.jetbrains.jet.lang.resolve.name.Name; +import org.jetbrains.jet.lang.resolve.scopes.JetScope; +import org.jetbrains.jet.lang.types.JetType; +import org.jetbrains.jet.lang.types.TypeUtils; + +import java.util.*; + +public final class JavaDescriptorPropertiesResolver { + private final JavaDescriptorResolver javaDescriptorResolver; + private JavaSemanticServices semanticServices; + private JavaDescriptorSignatureResolver javaDescriptorSignatureResolver; + private BindingTrace trace; + + /* internal */ JavaDescriptorPropertiesResolver(JavaDescriptorResolver resolver) { + this.javaDescriptorResolver = resolver; + } + + /* internal */ void setSemanticServices(JavaSemanticServices semanticServices) { + this.semanticServices = semanticServices; + } + + /* internal */ void setTrace(BindingTrace trace) { + this.trace = trace; + } + + /* internal */ void setJavaDescriptorSignatureResolver(JavaDescriptorSignatureResolver javaDescriptorSignatureResolver) { + this.javaDescriptorSignatureResolver = javaDescriptorSignatureResolver; + } + + void resolveNamedGroupProperties( + @NotNull ClassOrNamespaceDescriptor owner, + @NotNull ResolverScopeData scopeData, + @NotNull NamedMembers namedMembers, @NotNull Name propertyName, + @NotNull String context + ) { + JavaDescriptorResolver.getResolverScopeData(scopeData); + + if (namedMembers.propertyDescriptors != null) { + return; + } + + if (namedMembers.propertyAccessors == null) { + namedMembers.propertyAccessors = Collections.emptyList(); + } + + class GroupingValue { + PropertyAccessorData getter; + PropertyAccessorData setter; + PropertyAccessorData field; + boolean ext; + } + + Map map = new HashMap(); + + for (PropertyAccessorData propertyAccessor : namedMembers.propertyAccessors) { + + Object key = propertyKeyForGrouping(propertyAccessor); + + GroupingValue value = map.get(key); + if (value == null) { + value = new GroupingValue(); + value.ext = propertyAccessor.getReceiverType() != null; + map.put(key, value); + } + + if (value.ext != (propertyAccessor.getReceiverType() != null)) { + throw new IllegalStateException("internal error, incorrect key"); + } + + if (propertyAccessor.isGetter()) { + if (value.getter != null) { + throw new IllegalStateException("oops, duplicate key"); + } + value.getter = propertyAccessor; + } + else if (propertyAccessor.isSetter()) { + if (value.setter != null) { + throw new IllegalStateException("oops, duplicate key"); + } + value.setter = propertyAccessor; + } + else if (propertyAccessor.isField()) { + if (value.field != null) { + throw new IllegalStateException("oops, duplicate key"); + } + value.field = propertyAccessor; + } + else { + throw new IllegalStateException(); + } + } + + + Set propertiesFromCurrent = new HashSet(1); + + int regularProperitesCount = 0; + for (GroupingValue members : map.values()) { + if (!members.ext) { + ++regularProperitesCount; + } + } + + for (GroupingValue members : map.values()) { + + // we cannot have more then one property with given name even if java code + // has several fields, getters and setter of different types + if (!members.ext && regularProperitesCount > 1) { + continue; + } + + boolean isFinal; + if (!scopeData.kotlin) { + isFinal = true; + } + else if (members.setter == null && members.getter == null) { + isFinal = false; + } + else if (members.getter != null) { + isFinal = members.getter.getMember().isFinal(); + } + else if (members.setter != null) { + isFinal = members.setter.getMember().isFinal(); + } + else { + isFinal = false; + } + + PropertyAccessorData anyMember; + if (members.getter != null) { + anyMember = members.getter; + } + else if (members.field != null) { + anyMember = members.field; + } + else if (members.setter != null) { + anyMember = members.setter; + } + else { + throw new IllegalStateException(); + } + + boolean isVar; + if (members.getter == null && members.setter == null) { + isVar = !members.field.getMember().isFinal(); + } + else { + isVar = members.setter != null; + } + + Visibility visibility = JavaDescriptorResolver.resolveVisibility(anyMember.getMember().psiMember, null); + CallableMemberDescriptor.Kind kind = CallableMemberDescriptor.Kind.DECLARATION; + + if (members.getter != null && members.getter.getMember() instanceof PsiMethodWrapper) { + JetMethodAnnotation jetMethod = ((PsiMethodWrapper) members.getter.getMember()).getJetMethod(); + visibility = JavaDescriptorResolver.resolveVisibility(anyMember.getMember().psiMember, jetMethod); + kind = DescriptorKindUtils.flagsToKind(jetMethod.kind()); + } + + DeclarationDescriptor realOwner = getRealOwner(owner, scopeData, anyMember.getMember().isStatic()); + + boolean isEnumEntry = DescriptorUtils.isEnumClassObject(realOwner); + PropertyDescriptor propertyDescriptor = new PropertyDescriptor( + realOwner, + javaDescriptorResolver.resolveAnnotations(anyMember.getMember().psiMember), + JavaDescriptorResolver.resolveModality(anyMember.getMember(), isFinal || isEnumEntry), + visibility, + isVar, + propertyName, + kind); + + //TODO: this is a hack to indicate that this enum entry is an object + // class descriptor for enum entries is not used by backends so for now this should be safe to use + // remove this when JavaDescriptorResolver gets rewritten + if (isEnumEntry) { + ClassDescriptorImpl dummyClassDescriptorForEnumEntryObject = + new ClassDescriptorImpl(realOwner, Collections.emptyList(), Modality.FINAL, propertyName); + dummyClassDescriptorForEnumEntryObject.initialize( + true, + Collections.emptyList(), + Collections.emptyList(), JetScope.EMPTY, + Collections.emptySet(), null); + trace.record(BindingContext.OBJECT_DECLARATION_CLASS, propertyDescriptor, dummyClassDescriptorForEnumEntryObject); + } + + PropertyGetterDescriptor getterDescriptor = null; + PropertySetterDescriptor setterDescriptor = null; + if (members.getter != null) { + getterDescriptor = new PropertyGetterDescriptor( + propertyDescriptor, + javaDescriptorResolver.resolveAnnotations(members.getter.getMember().psiMember), + Modality.OPEN, + visibility, + true, + false, + kind); + } + if (members.setter != null) { + Visibility setterVisibility = JavaDescriptorResolver.resolveVisibility(members.setter.getMember().psiMember, null); + if (members.setter.getMember() instanceof PsiMethodWrapper) { + setterVisibility = JavaDescriptorResolver.resolveVisibility(members.setter.getMember().psiMember, + ((PsiMethodWrapper) members.setter.getMember()) + .getJetMethod()); + } + setterDescriptor = new PropertySetterDescriptor( + propertyDescriptor, + javaDescriptorResolver.resolveAnnotations(members.setter.getMember().psiMember), + Modality.OPEN, + setterVisibility, + true, + false, + kind); + } + + propertyDescriptor.initialize(getterDescriptor, setterDescriptor); + + List typeParameters = new ArrayList(0); + + if (members.setter != null) { + PsiMethodWrapper method = (PsiMethodWrapper) members.setter.getMember(); + + if (anyMember == members.setter) { + typeParameters = javaDescriptorSignatureResolver.resolveMethodTypeParameters(method, propertyDescriptor); + } + } + if (members.getter != null) { + PsiMethodWrapper method = (PsiMethodWrapper) members.getter.getMember(); + + if (anyMember == members.getter) { + typeParameters = javaDescriptorSignatureResolver.resolveMethodTypeParameters(method, propertyDescriptor); + } + } + + TypeVariableResolver typeVariableResolverForPropertyInternals = TypeVariableResolvers.typeVariableResolverFromTypeParameters(typeParameters, propertyDescriptor, "property " + propertyName + " in " + context); + + JetType propertyType; + if (anyMember.getType().getTypeString().length() > 0) { + propertyType = semanticServices.getTypeTransformer().transformToType(anyMember.getType().getTypeString(), typeVariableResolverForPropertyInternals); + } + else { + propertyType = semanticServices.getTypeTransformer().transformToType(anyMember.getType().getPsiType(), typeVariableResolverForPropertyInternals); + if (JavaDescriptorResolver.findAnnotation(anyMember.getType().getPsiNotNullOwner(), JvmAbi.JETBRAINS_NOT_NULL_ANNOTATION.getFqName().getFqName()) != null) { + propertyType = TypeUtils.makeNullableAsSpecified(propertyType, false); + } + else if (members.getter == null && members.setter == null && members.field.getMember().isFinal() && members.field.getMember().isStatic()) { + // http://youtrack.jetbrains.com/issue/KT-1388 + propertyType = TypeUtils.makeNotNullable(propertyType); + } + } + + JetType receiverType; + if (anyMember.getReceiverType() == null) { + receiverType = null; + } + else if (anyMember.getReceiverType().getTypeString().length() > 0) { + receiverType = semanticServices.getTypeTransformer().transformToType(anyMember.getReceiverType().getTypeString(), typeVariableResolverForPropertyInternals); + } + else { + receiverType = semanticServices.getTypeTransformer().transformToType(anyMember.getReceiverType().getPsiType(), typeVariableResolverForPropertyInternals); + } + + propertyDescriptor.setType( + propertyType, + typeParameters, + DescriptorUtils.getExpectedThisObjectIfNeeded(realOwner), + receiverType + ); + if (getterDescriptor != null) { + getterDescriptor.initialize(propertyType); + } + if (setterDescriptor != null) { + setterDescriptor.initialize(new ValueParameterDescriptorImpl(setterDescriptor, 0, Collections.emptyList(), Name.identifier("p0") /*TODO*/, false, propertyDescriptor.getType(), false, null)); + } + + if (kind == CallableMemberDescriptor.Kind.DECLARATION) { + trace.record(BindingContext.VARIABLE, anyMember.getMember().psiMember, propertyDescriptor); + } + + propertiesFromCurrent.add(propertyDescriptor); + } + + + Set propertiesFromSupertypes = getPropertiesFromSupertypes(scopeData, propertyName); + + final Set properties = Sets.newHashSet(); + + if (owner instanceof ClassDescriptor) { + ClassDescriptor classDescriptor = (ClassDescriptor) owner; + + OverrideResolver + .generateOverridesInFunctionGroup(propertyName, propertiesFromSupertypes, propertiesFromCurrent, classDescriptor, + new OverrideResolver.DescriptorSink() { + @Override + public void addToScope(@NotNull CallableMemberDescriptor fakeOverride) { + properties.add((PropertyDescriptor) fakeOverride); + } + + @Override + public void conflict( + @NotNull CallableMemberDescriptor fromSuper, + @NotNull CallableMemberDescriptor fromCurrent + ) { + // nop + } + }); + } + + OverrideResolver.resolveUnknownVisibilities(properties, trace); + properties.addAll(propertiesFromCurrent); + + namedMembers.propertyDescriptors = Sets.newHashSet(properties); + } + + private static Set getPropertiesFromSupertypes(ResolverScopeData scopeData, Name propertyName) { + Set r = new HashSet(); + for (JetType supertype : JavaDescriptorResolver.getSupertypes(scopeData)) { + for (VariableDescriptor property : supertype.getMemberScope().getProperties(propertyName)) { + r.add((PropertyDescriptor) property); + } + } + return r; + } + + private static Object key(TypeSource typeSource) { + if (typeSource == null) { + return ""; + } + else if (typeSource.getTypeString().length() > 0) { + return typeSource.getTypeString(); + } + else { + return psiTypeToKey(typeSource.getPsiType()); + } + } + + private static Object psiTypeToKey(PsiType psiType) { + if (psiType instanceof PsiClassType) { + return ((PsiClassType) psiType).getClassName(); + } + else if (psiType instanceof PsiPrimitiveType) { + return psiType.getPresentableText(); + } + else if (psiType instanceof PsiArrayType) { + return Pair.create("[", psiTypeToKey(((PsiArrayType) psiType).getComponentType())); + } + else { + throw new IllegalStateException(psiType.getClass().toString()); + } + } + + private static Object propertyKeyForGrouping(PropertyAccessorData propertyAccessor) { + Object type = key(propertyAccessor.getType()); + Object receiverType = key(propertyAccessor.getReceiverType()); + return Pair.create(type, receiverType); + } + + @NotNull + private ClassOrNamespaceDescriptor getRealOwner( + @NotNull ClassOrNamespaceDescriptor owner, + @NotNull ResolverScopeData scopeData, + boolean isStatic + ) { + final PsiClass psiClass = scopeData.psiClass; + assert psiClass != null; + + boolean isEnum = psiClass.isEnum(); + if (isEnum && isStatic) { + final String qualifiedName = psiClass.getQualifiedName(); + assert qualifiedName != null; + final ClassDescriptor classDescriptor = javaDescriptorResolver.resolveClass(new FqName(qualifiedName)); + assert classDescriptor != null; + final ClassDescriptor classObjectDescriptor = classDescriptor.getClassObjectDescriptor(); + assert classObjectDescriptor != null; + return classObjectDescriptor; + } + else { + return owner; + } + } +} diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolveData.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolveData.java new file mode 100644 index 00000000000..60d57b1e2a0 --- /dev/null +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolveData.java @@ -0,0 +1,203 @@ +/* + * Copyright 2010-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.lang.resolve.java; + +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiPackage; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.lang.descriptors.ClassDescriptor; +import org.jetbrains.jet.lang.descriptors.ClassOrNamespaceDescriptor; +import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor; +import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor; +import org.jetbrains.jet.lang.resolve.name.FqName; +import org.jetbrains.jet.lang.resolve.name.Name; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +class JavaDescriptorResolveData { + static abstract class ResolverScopeData { + @Nullable + final PsiClass psiClass; + @Nullable + final PsiPackage psiPackage; + @Nullable + final FqName fqName; + final boolean staticMembers; + final boolean kotlin; + final ClassOrNamespaceDescriptor classOrNamespaceDescriptor; + + protected ResolverScopeData(@Nullable PsiClass psiClass, @Nullable PsiPackage psiPackage, @Nullable FqName fqName, boolean staticMembers, @NotNull ClassOrNamespaceDescriptor descriptor) { + JavaDescriptorResolver.checkPsiClassIsNotJet(psiClass); + + this.psiClass = psiClass; + this.psiPackage = psiPackage; + this.fqName = fqName; + + if (psiClass == null && psiPackage == null) { + throw new IllegalStateException("both psiClass and psiPackage cannot be null"); + } + + this.staticMembers = staticMembers; + this.kotlin = psiClass != null && JavaDescriptorResolver.isKotlinClass(psiClass); + classOrNamespaceDescriptor = descriptor; + + if (fqName != null && fqName.lastSegmentIs(Name.identifier(JvmAbi.PACKAGE_CLASS)) && psiClass != null && kotlin) { + throw new IllegalStateException("Kotlin namespace cannot have last segment " + JvmAbi.PACKAGE_CLASS + ": " + fqName); + } + } + + protected ResolverScopeData(boolean negative) { + if (!negative) { + throw new IllegalStateException(); + } + this.psiClass = null; + this.psiPackage = null; + this.fqName = null; + this.staticMembers = false; + this.kotlin = false; + this.classOrNamespaceDescriptor = null; + } + + @NotNull + public PsiElement getPsiPackageOrPsiClass() { + if (psiPackage != null) { + return psiPackage; + } + else { + assert psiClass != null; + return psiClass; + } + } + + private Map namedMembersMap; + + Map getNamedMembersMap() { + return namedMembersMap; + } + + void setNamedMembersMap(Map namedMembersMap) { + this.namedMembersMap = namedMembersMap; + } + + @NotNull + public abstract List getTypeParameters(); + } + + /** Class with instance members */ + static class ResolverBinaryClassData extends ResolverClassData { + + ResolverBinaryClassData(@NotNull PsiClass psiClass, @Nullable FqName fqName, @NotNull ClassDescriptorFromJvmBytecode classDescriptor) { + super(psiClass, null, fqName, false, classDescriptor); + } + + ResolverBinaryClassData(boolean negative) { + super(negative); + } + + static final ResolverClassData NEGATIVE = new ResolverBinaryClassData(true); + + } + + static class ResolverClassData extends ResolverScopeData { + + final ClassDescriptorFromJvmBytecode classDescriptor; + + List typeParameters; + + protected ResolverClassData(boolean negative) { + super(negative); + this.classDescriptor = null; + } + + + protected ResolverClassData( + @Nullable PsiClass psiClass, + @Nullable PsiPackage psiPackage, + @Nullable FqName fqName, + boolean staticMembers, + @NotNull ClassDescriptorFromJvmBytecode descriptor + ) { + super(psiClass, psiPackage, fqName, staticMembers, descriptor); + classDescriptor = descriptor; + } + + @NotNull + public ClassDescriptor getClassDescriptor() { + return classDescriptor; + } + + @NotNull + @Override + public List getTypeParameters() { + return getClassDescriptor().getTypeConstructor().getParameters(); + } + + } + + + static class ResolverSyntheticClassObjectClassData extends ResolverClassData { + + protected ResolverSyntheticClassObjectClassData( + @Nullable PsiClass psiClass, + @Nullable FqName fqName, + @NotNull ClassDescriptorFromJvmBytecode descriptor + ) { + super(psiClass, null, fqName, true, descriptor); + } + } + + /** Either package or class with static members */ + static class ResolverNamespaceData extends ResolverScopeData { + static final ResolverNamespaceData NEGATIVE = new ResolverNamespaceData(true); + + private final NamespaceDescriptor namespaceDescriptor; + + private JavaPackageScope memberScope; + + ResolverNamespaceData(@Nullable PsiClass psiClass, @Nullable PsiPackage psiPackage, @NotNull FqName fqName, @NotNull NamespaceDescriptor namespaceDescriptor) { + super(psiClass, psiPackage, fqName, true, namespaceDescriptor); + this.namespaceDescriptor = namespaceDescriptor; + } + + private ResolverNamespaceData(boolean negative) { + super(negative); + this.namespaceDescriptor = null; + } + + JavaPackageScope getMemberScope() { + return memberScope; + } + + public NamespaceDescriptor getNamespaceDescriptor() { + return namespaceDescriptor; + } + + public void setMemberScope(JavaPackageScope memberScope) { + this.memberScope = memberScope; + } + + @NotNull + @Override + public List getTypeParameters() { + return new ArrayList(0); + } + } +} 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 f69406f5b86..41a2597a901 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 @@ -21,7 +21,6 @@ import com.google.common.collect.Maps; import com.google.common.collect.Sets; import com.intellij.codeInsight.ExternalAnnotationsManager; import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.Pair; import com.intellij.psi.*; import gnu.trove.THashMap; import gnu.trove.TObjectHashingStrategy; @@ -33,9 +32,9 @@ import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; import org.jetbrains.jet.lang.resolve.*; import org.jetbrains.jet.lang.resolve.constants.*; import org.jetbrains.jet.lang.resolve.constants.StringValue; +import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolveData.*; import org.jetbrains.jet.lang.resolve.java.kt.DescriptorKindUtils; import org.jetbrains.jet.lang.resolve.java.kt.JetClassAnnotation; -import org.jetbrains.jet.lang.resolve.java.kt.JetMethodAnnotation; import org.jetbrains.jet.lang.resolve.java.kt.PsiAnnotationWithFlags; import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.jet.lang.resolve.name.FqNameBase; @@ -88,155 +87,6 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes } }; - - static abstract class ResolverScopeData { - @Nullable - final PsiClass psiClass; - @Nullable - final PsiPackage psiPackage; - @Nullable - final FqName fqName; - final boolean staticMembers; - final boolean kotlin; - final ClassOrNamespaceDescriptor classOrNamespaceDescriptor; - - protected ResolverScopeData(@Nullable PsiClass psiClass, @Nullable PsiPackage psiPackage, @Nullable FqName fqName, boolean staticMembers, @NotNull ClassOrNamespaceDescriptor descriptor) { - checkPsiClassIsNotJet(psiClass); - - this.psiClass = psiClass; - this.psiPackage = psiPackage; - this.fqName = fqName; - - if (psiClass == null && psiPackage == null) { - throw new IllegalStateException("both psiClass and psiPackage cannot be null"); - } - - this.staticMembers = staticMembers; - this.kotlin = psiClass != null && isKotlinClass(psiClass); - classOrNamespaceDescriptor = descriptor; - - if (fqName != null && fqName.lastSegmentIs(Name.identifier(JvmAbi.PACKAGE_CLASS)) && psiClass != null && kotlin) { - throw new IllegalStateException("Kotlin namespace cannot have last segment " + JvmAbi.PACKAGE_CLASS + ": " + fqName); - } - } - - protected ResolverScopeData(boolean negative) { - if (!negative) { - throw new IllegalStateException(); - } - this.psiClass = null; - this.psiPackage = null; - this.fqName = null; - this.staticMembers = false; - this.kotlin = false; - this.classOrNamespaceDescriptor = null; - } - - @NotNull - public PsiElement getPsiPackageOrPsiClass() { - if (psiPackage != null) { - return psiPackage; - } - else { - assert psiClass != null; - return psiClass; - } - } - - private Map namedMembersMap; - - @NotNull - public abstract List getTypeParameters(); - } - - /** Class with instance members */ - static class ResolverBinaryClassData extends ResolverClassData { - - ResolverBinaryClassData(@NotNull PsiClass psiClass, @Nullable FqName fqName, @NotNull ClassDescriptorFromJvmBytecode classDescriptor) { - super(psiClass, null, fqName, false, classDescriptor); - } - - ResolverBinaryClassData(boolean negative) { - super(negative); - } - - static final ResolverClassData NEGATIVE = new ResolverBinaryClassData(true); - - } - - static class ResolverClassData extends ResolverScopeData { - - final ClassDescriptorFromJvmBytecode classDescriptor; - - List typeParameters; - - protected ResolverClassData(boolean negative) { - super(negative); - this.classDescriptor = null; - } - - - protected ResolverClassData( - @Nullable PsiClass psiClass, - @Nullable PsiPackage psiPackage, - @Nullable FqName fqName, - boolean staticMembers, - @NotNull ClassDescriptorFromJvmBytecode descriptor - ) { - super(psiClass, psiPackage, fqName, staticMembers, descriptor); - classDescriptor = descriptor; - } - - @NotNull - public ClassDescriptor getClassDescriptor() { - return classDescriptor; - } - - @NotNull - @Override - public List getTypeParameters() { - return getClassDescriptor().getTypeConstructor().getParameters(); - } - - } - - - static class ResolverSyntheticClassObjectClassData extends ResolverClassData { - - protected ResolverSyntheticClassObjectClassData( - @Nullable PsiClass psiClass, - @Nullable FqName fqName, - @NotNull ClassDescriptorFromJvmBytecode descriptor - ) { - super(psiClass, null, fqName, true, descriptor); - } - } - - /** Either package or class with static members */ - static class ResolverNamespaceData extends ResolverScopeData { - private final NamespaceDescriptor namespaceDescriptor; - - ResolverNamespaceData(@Nullable PsiClass psiClass, @Nullable PsiPackage psiPackage, @NotNull FqName fqName, @NotNull NamespaceDescriptor namespaceDescriptor) { - super(psiClass, psiPackage, fqName, true, namespaceDescriptor); - this.namespaceDescriptor = namespaceDescriptor; - } - - private ResolverNamespaceData(boolean negative) { - super(negative); - this.namespaceDescriptor = null; - } - - static final ResolverNamespaceData NEGATIVE = new ResolverNamespaceData(true); - - private JavaPackageScope memberScope; - - @NotNull - @Override - public List getTypeParameters() { - return new ArrayList(0); - } - } - // NOTE: this complexity is introduced because class descriptors do not always have valid fqnames (class objects) protected final Map classDescriptorCache = new THashMap(new TObjectHashingStrategy() { @Override @@ -260,6 +110,7 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes private BindingTrace trace; private PsiClassFinder psiClassFinder; private JavaDescriptorSignatureResolver javaDescriptorSignatureResolver; + private JavaDescriptorPropertiesResolver javaDescriptorPropertiesResolver = new JavaDescriptorPropertiesResolver(this); @Inject public void setProject(Project project) { @@ -269,11 +120,13 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes @Inject public void setSemanticServices(JavaSemanticServices semanticServices) { this.semanticServices = semanticServices; + this.javaDescriptorPropertiesResolver.setSemanticServices(semanticServices); } @Inject public void setTrace(BindingTrace trace) { this.trace = trace; + this.javaDescriptorPropertiesResolver.setTrace(trace); } @Inject @@ -284,6 +137,7 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes @Inject public void setJavaDescriptorSignatureResolver(JavaDescriptorSignatureResolver javaDescriptorSignatureResolver) { this.javaDescriptorSignatureResolver = javaDescriptorSignatureResolver; + this.javaDescriptorPropertiesResolver.setJavaDescriptorSignatureResolver(javaDescriptorSignatureResolver); } @@ -613,7 +467,7 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes return classObjectDescriptor; } - private static boolean isKotlinClass(@NotNull PsiClass psiClass) { + static boolean isKotlinClass(@NotNull PsiClass psiClass) { return new PsiClassWrapper(psiClass).getJetClass().isDefined() || psiClass.getName().equals(JvmAbi.PACKAGE_CLASS); } @@ -816,7 +670,7 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes ResolverNamespaceData namespaceData = namespaceDescriptorCacheByFqn.get(qualifiedName); if (namespaceData != null) { - return namespaceData.namespaceDescriptor; + return namespaceData.getNamespaceDescriptor(); } NamespaceDescriptorParent parentNs = resolveParentNamespace(qualifiedName); @@ -837,9 +691,9 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes trace.record(BindingContext.NAMESPACE, scopeData.getPsiPackageOrPsiClass(), ns); - ns.setMemberScope(scopeData.memberScope); + ns.setMemberScope(scopeData.getMemberScope()); - return scopeData.namespaceDescriptor; + return scopeData.getNamespaceDescriptor(); } @Override @@ -885,7 +739,7 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes ResolverNamespaceData namespaceData = new ResolverNamespaceData(psiClass, psiPackage, fqName, ns); - namespaceData.memberScope = new JavaPackageScope(fqName, semanticServices, namespaceData); + namespaceData.setMemberScope(new JavaPackageScope(fqName, semanticServices, namespaceData)); ResolverNamespaceData oldValue = namespaceDescriptorCacheByFqn.put(fqName, namespaceData); if (oldValue != null) { @@ -907,7 +761,7 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes if (resolverNamespaceData == ResolverNamespaceData.NEGATIVE) { throw new IllegalStateException("This means that we are trying to create a Java package, but have a package with the same FQN defined in Kotlin: " + fqName); } - JavaPackageScope scope = resolverNamespaceData.memberScope; + JavaPackageScope scope = resolverNamespaceData.getMemberScope(); if (scope == null) { throw new IllegalStateException("fqn: " + fqName); } @@ -1035,13 +889,14 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes getResolverScopeData(scopeData); - NamedMembers namedMembers = scopeData.namedMembersMap.get(fieldName); + NamedMembers namedMembers = scopeData.getNamedMembersMap().get(fieldName); if (namedMembers == null) { return Collections.emptySet(); } final String qualifiedName = psiClass.getQualifiedName(); - resolveNamedGroupProperties(scopeData.classOrNamespaceDescriptor, scopeData, namedMembers, fieldName, + javaDescriptorPropertiesResolver.resolveNamedGroupProperties( + scopeData.classOrNamespaceDescriptor, scopeData, namedMembers, fieldName, "class or namespace " + qualifiedName); return namedMembers.propertyDescriptors; @@ -1055,353 +910,20 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes assert psiClass != null; Set descriptors = Sets.newHashSet(); - Map membersForProperties = scopeData.namedMembersMap; + Map membersForProperties = scopeData.getNamedMembersMap(); for (Map.Entry entry : membersForProperties.entrySet()) { NamedMembers namedMembers = entry.getValue(); Name propertyName = entry.getKey(); - resolveNamedGroupProperties(scopeData.classOrNamespaceDescriptor, scopeData, namedMembers, propertyName, - "class or namespace " + psiClass.getQualifiedName()); + javaDescriptorPropertiesResolver.resolveNamedGroupProperties( + scopeData.classOrNamespaceDescriptor, scopeData, namedMembers, propertyName, + "class or namespace " + psiClass.getQualifiedName()); descriptors.addAll(namedMembers.propertyDescriptors); } return descriptors; } - private static Object key(TypeSource typeSource) { - if (typeSource == null) { - return ""; - } - else if (typeSource.getTypeString().length() > 0) { - return typeSource.getTypeString(); - } - else { - return psiTypeToKey(typeSource.getPsiType()); - } - } - - private static Object psiTypeToKey(PsiType psiType) { - if (psiType instanceof PsiClassType) { - return ((PsiClassType) psiType).getClassName(); - } - else if (psiType instanceof PsiPrimitiveType) { - return psiType.getPresentableText(); - } - else if (psiType instanceof PsiArrayType) { - return Pair.create("[", psiTypeToKey(((PsiArrayType) psiType).getComponentType())); - } - else { - throw new IllegalStateException(psiType.getClass().toString()); - } - } - - private static Object propertyKeyForGrouping(PropertyAccessorData propertyAccessor) { - Object type = key(propertyAccessor.getType()); - Object receiverType = key(propertyAccessor.getReceiverType()); - return Pair.create(type, receiverType); - } - - private void resolveNamedGroupProperties( - @NotNull ClassOrNamespaceDescriptor owner, - @NotNull ResolverScopeData scopeData, - @NotNull NamedMembers namedMembers, @NotNull Name propertyName, - @NotNull String context) { - getResolverScopeData(scopeData); - - if (namedMembers.propertyDescriptors != null) { - return; - } - - if (namedMembers.propertyAccessors == null) { - namedMembers.propertyAccessors = Collections.emptyList(); - } - - class GroupingValue { - PropertyAccessorData getter; - PropertyAccessorData setter; - PropertyAccessorData field; - boolean ext; - } - - Map map = new HashMap(); - - for (PropertyAccessorData propertyAccessor : namedMembers.propertyAccessors) { - - Object key = propertyKeyForGrouping(propertyAccessor); - - GroupingValue value = map.get(key); - if (value == null) { - value = new GroupingValue(); - value.ext = propertyAccessor.getReceiverType() != null; - map.put(key, value); - } - - if (value.ext != (propertyAccessor.getReceiverType() != null)) { - throw new IllegalStateException("internal error, incorrect key"); - } - - if (propertyAccessor.isGetter()) { - if (value.getter != null) { - throw new IllegalStateException("oops, duplicate key"); - } - value.getter = propertyAccessor; - } - else if (propertyAccessor.isSetter()) { - if (value.setter != null) { - throw new IllegalStateException("oops, duplicate key"); - } - value.setter = propertyAccessor; - } - else if (propertyAccessor.isField()) { - if (value.field != null) { - throw new IllegalStateException("oops, duplicate key"); - } - value.field = propertyAccessor; - } - else { - throw new IllegalStateException(); - } - } - - - Set propertiesFromCurrent = new HashSet(1); - - int regularProperitesCount = 0; - for (GroupingValue members : map.values()) { - if (!members.ext) { - ++regularProperitesCount; - } - } - - for (GroupingValue members : map.values()) { - - // we cannot have more then one property with given name even if java code - // has several fields, getters and setter of different types - if (!members.ext && regularProperitesCount > 1) { - continue; - } - - boolean isFinal; - if (!scopeData.kotlin) { - isFinal = true; - } - else if (members.setter == null && members.getter == null) { - isFinal = false; - } - else if (members.getter != null) { - isFinal = members.getter.getMember().isFinal(); - } - else if (members.setter != null) { - isFinal = members.setter.getMember().isFinal(); - } - else { - isFinal = false; - } - - PropertyAccessorData anyMember; - if (members.getter != null) { - anyMember = members.getter; - } - else if (members.field != null) { - anyMember = members.field; - } - else if (members.setter != null) { - anyMember = members.setter; - } - else { - throw new IllegalStateException(); - } - - boolean isVar; - if (members.getter == null && members.setter == null) { - isVar = !members.field.getMember().isFinal(); - } - else { - isVar = members.setter != null; - } - - Visibility visibility = resolveVisibility(anyMember.getMember().psiMember, null); - CallableMemberDescriptor.Kind kind = CallableMemberDescriptor.Kind.DECLARATION; - - if (members.getter != null && members.getter.getMember() instanceof PsiMethodWrapper) { - JetMethodAnnotation jetMethod = ((PsiMethodWrapper) members.getter.getMember()).getJetMethod(); - visibility = resolveVisibility(anyMember.getMember().psiMember, jetMethod); - kind = DescriptorKindUtils.flagsToKind(jetMethod.kind()); - } - - DeclarationDescriptor realOwner = getRealOwner(owner, scopeData, anyMember.getMember().isStatic()); - - boolean isEnumEntry = DescriptorUtils.isEnumClassObject(realOwner); - PropertyDescriptor propertyDescriptor = new PropertyDescriptor( - realOwner, - resolveAnnotations(anyMember.getMember().psiMember), - resolveModality(anyMember.getMember(), isFinal || isEnumEntry), - visibility, - isVar, - propertyName, - kind); - - //TODO: this is a hack to indicate that this enum entry is an object - // class descriptor for enum entries is not used by backends so for now this should be safe to use - // remove this when JavaDescriptorResolver gets rewritten - if (isEnumEntry) { - ClassDescriptorImpl dummyClassDescriptorForEnumEntryObject = - new ClassDescriptorImpl(realOwner, Collections.emptyList(), Modality.FINAL, propertyName); - dummyClassDescriptorForEnumEntryObject.initialize( - true, - Collections.emptyList(), - Collections.emptyList(), JetScope.EMPTY, - Collections.emptySet(), null); - trace.record(BindingContext.OBJECT_DECLARATION_CLASS, propertyDescriptor, dummyClassDescriptorForEnumEntryObject); - } - - PropertyGetterDescriptor getterDescriptor = null; - PropertySetterDescriptor setterDescriptor = null; - if (members.getter != null) { - getterDescriptor = new PropertyGetterDescriptor( - propertyDescriptor, - resolveAnnotations(members.getter.getMember().psiMember), - Modality.OPEN, - visibility, - true, - false, - kind); - } - if (members.setter != null) { - Visibility setterVisibility = resolveVisibility(members.setter.getMember().psiMember, null); - if (members.setter.getMember() instanceof PsiMethodWrapper) { - setterVisibility = resolveVisibility(members.setter.getMember().psiMember, - ((PsiMethodWrapper) members.setter.getMember()).getJetMethod()); - } - setterDescriptor = new PropertySetterDescriptor( - propertyDescriptor, - resolveAnnotations(members.setter.getMember().psiMember), - Modality.OPEN, - setterVisibility, - true, - false, - kind); - } - - propertyDescriptor.initialize(getterDescriptor, setterDescriptor); - - List typeParameters = new ArrayList(0); - - if (members.setter != null) { - PsiMethodWrapper method = (PsiMethodWrapper) members.setter.getMember(); - - if (anyMember == members.setter) { - typeParameters = javaDescriptorSignatureResolver.resolveMethodTypeParameters(method, propertyDescriptor); - } - } - if (members.getter != null) { - PsiMethodWrapper method = (PsiMethodWrapper) members.getter.getMember(); - - if (anyMember == members.getter) { - typeParameters = javaDescriptorSignatureResolver.resolveMethodTypeParameters(method, propertyDescriptor); - } - } - - TypeVariableResolver typeVariableResolverForPropertyInternals = TypeVariableResolvers.typeVariableResolverFromTypeParameters(typeParameters, propertyDescriptor, "property " + propertyName + " in " + context); - - JetType propertyType; - if (anyMember.getType().getTypeString().length() > 0) { - propertyType = semanticServices.getTypeTransformer().transformToType(anyMember.getType().getTypeString(), typeVariableResolverForPropertyInternals); - } - else { - propertyType = semanticServices.getTypeTransformer().transformToType(anyMember.getType().getPsiType(), typeVariableResolverForPropertyInternals); - if (findAnnotation(anyMember.getType().getPsiNotNullOwner(), JvmAbi.JETBRAINS_NOT_NULL_ANNOTATION.getFqName().getFqName()) != null) { - propertyType = TypeUtils.makeNullableAsSpecified(propertyType, false); - } - else if (members.getter == null && members.setter == null && members.field.getMember().isFinal() && members.field.getMember().isStatic()) { - // http://youtrack.jetbrains.com/issue/KT-1388 - propertyType = TypeUtils.makeNotNullable(propertyType); - } - } - - JetType receiverType; - if (anyMember.getReceiverType() == null) { - receiverType = null; - } - else if (anyMember.getReceiverType().getTypeString().length() > 0) { - receiverType = semanticServices.getTypeTransformer().transformToType(anyMember.getReceiverType().getTypeString(), typeVariableResolverForPropertyInternals); - } - else { - receiverType = semanticServices.getTypeTransformer().transformToType(anyMember.getReceiverType().getPsiType(), typeVariableResolverForPropertyInternals); - } - - propertyDescriptor.setType( - propertyType, - typeParameters, - DescriptorUtils.getExpectedThisObjectIfNeeded(realOwner), - receiverType - ); - if (getterDescriptor != null) { - getterDescriptor.initialize(propertyType); - } - if (setterDescriptor != null) { - setterDescriptor.initialize(new ValueParameterDescriptorImpl(setterDescriptor, 0, Collections.emptyList(), Name.identifier("p0") /*TODO*/, false, propertyDescriptor.getType(), false, null)); - } - - if (kind == CallableMemberDescriptor.Kind.DECLARATION) { - trace.record(BindingContext.VARIABLE, anyMember.getMember().psiMember, propertyDescriptor); - } - - propertiesFromCurrent.add(propertyDescriptor); - } - - - Set propertiesFromSupertypes = getPropertiesFromSupertypes(scopeData, propertyName); - - final Set properties = Sets.newHashSet(); - - if (owner instanceof ClassDescriptor) { - ClassDescriptor classDescriptor = (ClassDescriptor) owner; - - OverrideResolver.generateOverridesInFunctionGroup(propertyName, propertiesFromSupertypes, propertiesFromCurrent, classDescriptor, - new OverrideResolver.DescriptorSink() { - @Override - public void addToScope(@NotNull CallableMemberDescriptor fakeOverride) { - properties.add((PropertyDescriptor) fakeOverride); - } - - @Override - public void conflict(@NotNull CallableMemberDescriptor fromSuper, @NotNull CallableMemberDescriptor fromCurrent) { - // nop - } - }); - } - - OverrideResolver.resolveUnknownVisibilities(properties, trace); - properties.addAll(propertiesFromCurrent); - - namedMembers.propertyDescriptors = Sets.newHashSet(properties); - } - - @NotNull - private ClassOrNamespaceDescriptor getRealOwner( - @NotNull ClassOrNamespaceDescriptor owner, - @NotNull ResolverScopeData scopeData, - boolean isStatic - ) { - final PsiClass psiClass = scopeData.psiClass; - assert psiClass != null; - - boolean isEnum = psiClass.isEnum(); - if (isEnum && isStatic) { - final String qualifiedName = psiClass.getQualifiedName(); - assert qualifiedName != null; - final ClassDescriptor classDescriptor = resolveClass(new FqName(qualifiedName)); - assert classDescriptor != null; - final ClassDescriptor classObjectDescriptor = classDescriptor.getClassObjectDescriptor(); - assert classObjectDescriptor != null; - return classObjectDescriptor; - } - else { - return owner; - } - } - private void resolveNamedGroupFunctions( @NotNull ClassOrNamespaceDescriptor owner, PsiClass psiClass, NamedMembers namedMembers, Name methodName, ResolverScopeData scopeData @@ -1463,19 +985,9 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes return r; } - private static Set getPropertiesFromSupertypes(ResolverScopeData scopeData, Name propertyName) { - Set r = new HashSet(); - for (JetType supertype : getSupertypes(scopeData)) { - for (VariableDescriptor property : supertype.getMemberScope().getProperties(propertyName)) { - r.add((PropertyDescriptor) property); - } - } - return r; - } - - private static void getResolverScopeData(@NotNull ResolverScopeData scopeData) { - if (scopeData.namedMembersMap == null) { - scopeData.namedMembersMap = JavaDescriptorResolverHelper.getNamedMembers(scopeData); + static void getResolverScopeData(@NotNull ResolverScopeData scopeData) { + if (scopeData.getNamedMembersMap() == null) { + scopeData.setNamedMembersMap(JavaDescriptorResolverHelper.getNamedMembers(scopeData)); } } @@ -1484,7 +996,7 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes getResolverScopeData(scopeData); - Map namedMembersMap = scopeData.namedMembersMap; + Map namedMembersMap = scopeData.getNamedMembersMap(); NamedMembers namedMembers = namedMembersMap.get(methodName); if (namedMembers != null && namedMembers.methods != null) { @@ -1632,7 +1144,7 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes return r; } - private List resolveAnnotations(PsiModifierListOwner owner) { + List resolveAnnotations(PsiModifierListOwner owner) { List tasks = Lists.newArrayList(); List annotations = resolveAnnotations(owner, tasks); for (Runnable task : tasks) { @@ -1849,7 +1361,7 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes List functions = new ArrayList(); - for (Map.Entry entry : scopeData.namedMembersMap.entrySet()) { + for (Map.Entry entry : scopeData.getNamedMembersMap().entrySet()) { Name methodName = entry.getKey(); NamedMembers namedMembers = entry.getValue(); resolveNamedGroupFunctions(scopeData.classOrNamespaceDescriptor, scopeData.psiClass, @@ -1860,7 +1372,7 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes return functions; } - private static Collection getSupertypes(ResolverScopeData scope) { + static Collection getSupertypes(ResolverScopeData scope) { if (scope instanceof ResolverClassData) { return ((ResolverClassData) scope).classDescriptor.getSupertypes(); } @@ -1894,7 +1406,7 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes } } - private static Modality resolveModality(PsiMemberWrapper memberWrapper, boolean isFinal) { + static Modality resolveModality(PsiMemberWrapper memberWrapper, boolean isFinal) { if (memberWrapper instanceof PsiMethodWrapper) { PsiMethodWrapper method = (PsiMethodWrapper) memberWrapper; if (method.getJetMethod().hasForceOpenFlag()) { @@ -1908,7 +1420,7 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes return Modality.convertFromFlags(memberWrapper.isAbstract(), !isFinal); } - private static Visibility resolveVisibility(PsiModifierListOwner modifierListOwner, + static Visibility resolveVisibility(PsiModifierListOwner modifierListOwner, @Nullable PsiAnnotationWithFlags annotation) { if (annotation != null) { if (annotation.hasPrivateFlag()) { 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 e07c218cb2a..e9bab8f098c 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 @@ -20,6 +20,7 @@ import com.intellij.psi.PsiField; import com.intellij.psi.PsiMethod; import com.intellij.psi.PsiType; import org.jetbrains.annotations.NotNull; +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.PropertyParseResult; import org.jetbrains.jet.lang.resolve.name.Name; @@ -103,7 +104,6 @@ class JavaDescriptorResolverHelper { } private void processMethods() { - for (PsiMethod method : psiClass.getPsiClass().getAllMethods()) { getNamedMembers(Name.identifier(method.getName())); @@ -207,7 +207,7 @@ class JavaDescriptorResolverHelper { @NotNull - static Map getNamedMembers(@NotNull JavaDescriptorResolver.ResolverScopeData resolverScopeData) { + static Map getNamedMembers(@NotNull ResolverScopeData resolverScopeData) { if (resolverScopeData.psiClass != null) { @SuppressWarnings("ConstantConditions") Builder builder = new Builder(new PsiClassWrapper(resolverScopeData.psiClass), resolverScopeData.staticMembers, resolverScopeData.kotlin); diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorSignatureResolver.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorSignatureResolver.java index be657a1a28f..fc4fa485404 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorSignatureResolver.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorSignatureResolver.java @@ -26,6 +26,7 @@ import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor; import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptorImpl; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; +import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolveData.ResolverClassData; import org.jetbrains.jet.lang.resolve.java.kt.JetClassAnnotation; import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.lang.types.JetType; @@ -78,7 +79,7 @@ public class JavaDescriptorSignatureResolver { private TypeParameterDescriptorInitialization( @NotNull TypeParameterDescriptorImpl descriptor, @NotNull PsiTypeParameter psiTypeParameter, - List upperBoundsForKotlin + @Nullable List upperBoundsForKotlin ) { this.origin = TypeParameterDescriptorOrigin.KOTLIN; this.descriptor = descriptor; @@ -112,8 +113,11 @@ public class JavaDescriptorSignatureResolver { @NotNull private final TypeParameterDescriptorImpl typeParameterDescriptor; - protected JetSignatureTypeParameterVisitor(PsiTypeParameterListOwner psiOwner, - String name, TypeVariableResolver typeVariableResolver, TypeParameterDescriptorImpl typeParameterDescriptor) + protected JetSignatureTypeParameterVisitor( + @NotNull PsiTypeParameterListOwner psiOwner, + @NotNull String name, + @NotNull TypeVariableResolver typeVariableResolver, + @NotNull TypeParameterDescriptorImpl typeParameterDescriptor) { if (name.isEmpty()) { throw new IllegalStateException(); @@ -309,7 +313,7 @@ public class JavaDescriptorSignatureResolver { } - List createUninitializedClassTypeParameters(PsiClass psiClass, JavaDescriptorResolver.ResolverClassData classData) { + List createUninitializedClassTypeParameters(PsiClass psiClass, ResolverClassData classData) { JetClassAnnotation jetClassAnnotation = JetClassAnnotation.get(psiClass); if (jetClassAnnotation.signature().length() > 0) { diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaPackageScope.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaPackageScope.java index c34cee0c0c0..88949b8c8eb 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaPackageScope.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaPackageScope.java @@ -20,6 +20,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.descriptors.ClassDescriptor; import org.jetbrains.jet.lang.descriptors.ClassifierDescriptor; import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor; +import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolveData.ResolverScopeData; import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.jet.lang.resolve.name.Name; @@ -34,7 +35,7 @@ public class JavaPackageScope extends JavaClassOrPackageScope { public JavaPackageScope( @NotNull FqName packageFQN, @NotNull JavaSemanticServices semanticServices, - @NotNull JavaDescriptorResolver.ResolverScopeData resolverNamespaceData) { + @NotNull ResolverScopeData resolverNamespaceData) { super(semanticServices, resolverNamespaceData); this.packageFQN = packageFQN; diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/prop/PropertyNameUtils.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/prop/PropertyNameUtils.java index 0ee0dd0e2a3..c597ae0214d 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/prop/PropertyNameUtils.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/prop/PropertyNameUtils.java @@ -26,6 +26,9 @@ import org.jetbrains.jet.lang.resolve.java.JvmAbi; */ public class PropertyNameUtils { + private PropertyNameUtils() { + } + @Nullable public static PropertyParseResult parseMethodToProperty(@NotNull String methodName) { // TODO: support is properties