Move ResolverData classes and property resolve to separate classes from JavaDescriptorResolver

This commit is contained in:
Nikolay Krasko
2012-09-28 22:30:28 +04:00
parent 58c05afa87
commit 1a6f1af0e5
10 changed files with 664 additions and 529 deletions
@@ -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<ConstructorDescriptor> getConstructors() {
@@ -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) {
@@ -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<DeclarationDescriptor> allDescriptors;
protected JavaClassOrPackageScope(
@NotNull JavaSemanticServices semanticServices,
@NotNull JavaDescriptorResolver.ResolverScopeData resolverScopeData) {
@NotNull ResolverScopeData resolverScopeData) {
this.semanticServices = semanticServices;
this.resolverScopeData = resolverScopeData;
}
@@ -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<Object, GroupingValue> map = new HashMap<Object, GroupingValue>();
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<PropertyDescriptor> propertiesFromCurrent = new HashSet<PropertyDescriptor>(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.<AnnotationDescriptor>emptyList(), Modality.FINAL, propertyName);
dummyClassDescriptorForEnumEntryObject.initialize(
true,
Collections.<TypeParameterDescriptor>emptyList(),
Collections.<JetType>emptyList(), JetScope.EMPTY,
Collections.<ConstructorDescriptor>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<TypeParameterDescriptor> typeParameters = new ArrayList<TypeParameterDescriptor>(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.<AnnotationDescriptor>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<PropertyDescriptor> propertiesFromSupertypes = getPropertiesFromSupertypes(scopeData, propertyName);
final Set<PropertyDescriptor> 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.<VariableDescriptor>newHashSet(properties);
}
private static Set<PropertyDescriptor> getPropertiesFromSupertypes(ResolverScopeData scopeData, Name propertyName) {
Set<PropertyDescriptor> r = new HashSet<PropertyDescriptor>();
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;
}
}
}
@@ -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<Name, NamedMembers> namedMembersMap;
Map<Name, NamedMembers> getNamedMembersMap() {
return namedMembersMap;
}
void setNamedMembersMap(Map<Name, NamedMembers> namedMembersMap) {
this.namedMembersMap = namedMembersMap;
}
@NotNull
public abstract List<TypeParameterDescriptor> 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<JavaDescriptorSignatureResolver.TypeParameterDescriptorInitialization> 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<TypeParameterDescriptor> 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<TypeParameterDescriptor> getTypeParameters() {
return new ArrayList<TypeParameterDescriptor>(0);
}
}
}
@@ -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<Name, NamedMembers> namedMembersMap;
@NotNull
public abstract List<TypeParameterDescriptor> 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<JavaDescriptorSignatureResolver.TypeParameterDescriptorInitialization> 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<TypeParameterDescriptor> 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<TypeParameterDescriptor> getTypeParameters() {
return new ArrayList<TypeParameterDescriptor>(0);
}
}
// NOTE: this complexity is introduced because class descriptors do not always have valid fqnames (class objects)
protected final Map<FqNameBase, ResolverClassData> classDescriptorCache = new THashMap<FqNameBase, ResolverClassData>(new TObjectHashingStrategy<FqNameBase>() {
@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<VariableDescriptor> descriptors = Sets.newHashSet();
Map<Name, NamedMembers> membersForProperties = scopeData.namedMembersMap;
Map<Name, NamedMembers> membersForProperties = scopeData.getNamedMembersMap();
for (Map.Entry<Name, NamedMembers> 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<Object, GroupingValue> map = new HashMap<Object, GroupingValue>();
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<PropertyDescriptor> propertiesFromCurrent = new HashSet<PropertyDescriptor>(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.<AnnotationDescriptor>emptyList(), Modality.FINAL, propertyName);
dummyClassDescriptorForEnumEntryObject.initialize(
true,
Collections.<TypeParameterDescriptor>emptyList(),
Collections.<JetType>emptyList(), JetScope.EMPTY,
Collections.<ConstructorDescriptor>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<TypeParameterDescriptor> typeParameters = new ArrayList<TypeParameterDescriptor>(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.<AnnotationDescriptor>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<PropertyDescriptor> propertiesFromSupertypes = getPropertiesFromSupertypes(scopeData, propertyName);
final Set<PropertyDescriptor> 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.<VariableDescriptor>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<PropertyDescriptor> getPropertiesFromSupertypes(ResolverScopeData scopeData, Name propertyName) {
Set<PropertyDescriptor> r = new HashSet<PropertyDescriptor>();
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<Name, NamedMembers> namedMembersMap = scopeData.namedMembersMap;
Map<Name, NamedMembers> 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<AnnotationDescriptor> resolveAnnotations(PsiModifierListOwner owner) {
List<AnnotationDescriptor> resolveAnnotations(PsiModifierListOwner owner) {
List<Runnable> tasks = Lists.newArrayList();
List<AnnotationDescriptor> annotations = resolveAnnotations(owner, tasks);
for (Runnable task : tasks) {
@@ -1849,7 +1361,7 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes
List<FunctionDescriptor> functions = new ArrayList<FunctionDescriptor>();
for (Map.Entry<Name, NamedMembers> entry : scopeData.namedMembersMap.entrySet()) {
for (Map.Entry<Name, NamedMembers> 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<JetType> getSupertypes(ResolverScopeData scope) {
static Collection<JetType> 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()) {
@@ -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<Name, NamedMembers> getNamedMembers(@NotNull JavaDescriptorResolver.ResolverScopeData resolverScopeData) {
static Map<Name, NamedMembers> getNamedMembers(@NotNull ResolverScopeData resolverScopeData) {
if (resolverScopeData.psiClass != null) {
@SuppressWarnings("ConstantConditions")
Builder builder = new Builder(new PsiClassWrapper(resolverScopeData.psiClass), resolverScopeData.staticMembers, resolverScopeData.kotlin);
@@ -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<JetType> upperBoundsForKotlin
@Nullable List<JetType> 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<TypeParameterDescriptorInitialization> createUninitializedClassTypeParameters(PsiClass psiClass, JavaDescriptorResolver.ResolverClassData classData) {
List<TypeParameterDescriptorInitialization> createUninitializedClassTypeParameters(PsiClass psiClass, ResolverClassData classData) {
JetClassAnnotation jetClassAnnotation = JetClassAnnotation.get(psiClass);
if (jetClassAnnotation.signature().length() > 0) {
@@ -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;
@@ -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