Move methods from JavaDescriptorResolver to FunctionResolver

This commit is contained in:
Pavel V. Talanov
2012-10-06 19:31:45 +04:00
parent 6424e0fe22
commit 4f0ac287b3
3 changed files with 179 additions and 159 deletions
@@ -120,7 +120,7 @@ public class JavaDescriptorResolveData {
private Map<Name, NamedMembers> namedMembersMap; private Map<Name, NamedMembers> namedMembersMap;
Map<Name, NamedMembers> getNamedMembersMap() { public Map<Name, NamedMembers> getNamedMembersMap() {
return namedMembersMap; return namedMembersMap;
} }
@@ -16,7 +16,6 @@
package org.jetbrains.jet.lang.resolve.java; package org.jetbrains.jet.lang.resolve.java;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
import com.google.common.collect.Sets; import com.google.common.collect.Sets;
import com.intellij.openapi.project.Project; import com.intellij.openapi.project.Project;
@@ -31,7 +30,6 @@ import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.BindingTrace; import org.jetbrains.jet.lang.resolve.BindingTrace;
import org.jetbrains.jet.lang.resolve.DescriptorUtils; import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.OverrideResolver;
import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolveData.ResolverClassData; import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolveData.ResolverClassData;
import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolveData.ResolverNamespaceData; import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolveData.ResolverNamespaceData;
import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolveData.ResolverScopeData; import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolveData.ResolverScopeData;
@@ -56,7 +54,6 @@ import org.jetbrains.jet.lang.types.DependencyClassByQualifiedNameResolver;
import org.jetbrains.jet.lang.types.ErrorUtils; import org.jetbrains.jet.lang.types.ErrorUtils;
import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.TypeUtils; import org.jetbrains.jet.lang.types.TypeUtils;
import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
import org.jetbrains.jet.lang.types.lang.JetStandardClasses; import org.jetbrains.jet.lang.types.lang.JetStandardClasses;
import org.jetbrains.jet.lang.types.lang.JetStandardLibrary; import org.jetbrains.jet.lang.types.lang.JetStandardLibrary;
import org.jetbrains.jet.rt.signature.JetSignatureAdapter; import org.jetbrains.jet.rt.signature.JetSignatureAdapter;
@@ -100,21 +97,22 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes
}; };
// NOTE: this complexity is introduced because class descriptors do not always have valid fqnames (class objects) // 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>() { protected final Map<FqNameBase, ResolverClassData> classDescriptorCache =
@Override new THashMap<FqNameBase, ResolverClassData>(new TObjectHashingStrategy<FqNameBase>() {
public int computeHashCode(FqNameBase o) { @Override
if (o instanceof FqName) { public int computeHashCode(FqNameBase o) {
return ((FqName) o).toUnsafe().hashCode(); if (o instanceof FqName) {
} return ((FqName) o).toUnsafe().hashCode();
assert o instanceof FqNameUnsafe; }
return o.hashCode(); assert o instanceof FqNameUnsafe;
} return o.hashCode();
}
@Override @Override
public boolean equals(FqNameBase n1, FqNameBase n2) { public boolean equals(FqNameBase n1, FqNameBase n2) {
return n1.equalsTo(n2.toString()) && n2.equalsTo(n1.toString()); return n1.equalsTo(n2.toString()) && n2.equalsTo(n1.toString());
} }
}); });
protected final Map<FqName, ResolverNamespaceData> namespaceDescriptorCacheByFqn = Maps.newHashMap(); protected final Map<FqName, ResolverNamespaceData> namespaceDescriptorCacheByFqn = Maps.newHashMap();
protected Project project; protected Project project;
@@ -238,7 +236,7 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes
/** /**
* TODO * TODO
//* @see #createJavaNamespaceDescriptor(PsiClass) * //* @see #createJavaNamespaceDescriptor(PsiClass)
*/ */
@Nullable @Nullable
public MutableClassDescriptorLite createClassObjectDescriptor(@NotNull ClassDescriptor containing, @NotNull PsiClass psiClass) { public MutableClassDescriptorLite createClassObjectDescriptor(@NotNull ClassDescriptor containing, @NotNull PsiClass psiClass) {
@@ -269,7 +267,7 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes
FqName fqName = new FqName(qualifiedName); FqName fqName = new FqName(qualifiedName);
ResolverClassData classData = new ClassDescriptorFromJvmBytecode( ResolverClassData classData = new ClassDescriptorFromJvmBytecode(
containing, ClassKind.CLASS_OBJECT, classObjectPsiClass, fqName, this) containing, ClassKind.CLASS_OBJECT, classObjectPsiClass, fqName, this)
.getResolverBinaryClassData(); .getResolverBinaryClassData();
ClassDescriptorFromJvmBytecode classObjectDescriptor = classData.getClassDescriptor(); ClassDescriptorFromJvmBytecode classObjectDescriptor = classData.getClassDescriptor();
classObjectDescriptor.setSupertypes( classObjectDescriptor.setSupertypes(
@@ -328,7 +326,8 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes
classDescriptor.setTypeParameterDescriptors(Collections.<TypeParameterDescriptor>emptyList()); classDescriptor.setTypeParameterDescriptors(Collections.<TypeParameterDescriptor>emptyList());
classDescriptor.createTypeConstructor(); classDescriptor.createTypeConstructor();
JavaClassMembersScope classMembersScope = new JavaClassMembersScope(semanticServices, data); JavaClassMembersScope classMembersScope = new JavaClassMembersScope(semanticServices, data);
WritableScopeImpl writableScope = new WritableScopeImpl(classMembersScope, classDescriptor, RedeclarationHandler.THROW_EXCEPTION, fqName.toString()); WritableScopeImpl writableScope =
new WritableScopeImpl(classMembersScope, classDescriptor, RedeclarationHandler.THROW_EXCEPTION, fqName.toString());
writableScope.changeLockLevel(WritableScope.LockLevel.BOTH); writableScope.changeLockLevel(WritableScope.LockLevel.BOTH);
classDescriptor.setScopeForMemberLookup(writableScope); classDescriptor.setScopeForMemberLookup(writableScope);
} }
@@ -353,7 +352,8 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes
FqName containerFqName = new FqName(containingClassQualifiedName); FqName containerFqName = new FqName(containingClassQualifiedName);
ClassDescriptor clazz = classResolver.resolveClass(containerFqName, DescriptorSearchRule.INCLUDE_KOTLIN); ClassDescriptor clazz = classResolver.resolveClass(containerFqName, DescriptorSearchRule.INCLUDE_KOTLIN);
if (clazz == null) { if (clazz == null) {
throw new IllegalStateException("PsiClass not found by name " + containerFqName + ", required to be container declaration of " + fqName); throw new IllegalStateException(
"PsiClass not found by name " + containerFqName + ", required to be container declaration of " + fqName);
} }
if (isInnerEnum(psiClass, clazz) && isKotlinClass(psiClass)) { if (isInnerEnum(psiClass, clazz) && isKotlinClass(psiClass)) {
ClassDescriptor classObjectDescriptor = clazz.getClassObjectDescriptor(); ClassDescriptor classObjectDescriptor = clazz.getClassObjectDescriptor();
@@ -384,8 +384,9 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes
String context = "class " + psiClass.getQualifiedName(); String context = "class " + psiClass.getQualifiedName();
if (psiClass.getJetClass().signature().length() > 0) { if (psiClass.getJetClass().signature().length() > 0) {
final TypeVariableResolver typeVariableResolver = TypeVariableResolvers.typeVariableResolverFromTypeParameters(typeParameters, classDescriptor, context); final TypeVariableResolver typeVariableResolver =
TypeVariableResolvers.typeVariableResolverFromTypeParameters(typeParameters, classDescriptor, context);
new JetSignatureReader(psiClass.getJetClass().signature()).accept(new JetSignatureExceptionsAdapter() { new JetSignatureReader(psiClass.getJetClass().signature()).accept(new JetSignatureExceptionsAdapter() {
@Override @Override
public JetSignatureVisitor visitFormalTypeParameter(String name, TypeInfoVariance variance, boolean reified) { public JetSignatureVisitor visitFormalTypeParameter(String name, TypeInfoVariance variance, boolean reified) {
@@ -412,22 +413,23 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes
}); });
} }
else { else {
TypeVariableResolver typeVariableResolverForSupertypes = TypeVariableResolvers.typeVariableResolverFromTypeParameters(typeParameters, classDescriptor, context); TypeVariableResolver typeVariableResolverForSupertypes =
TypeVariableResolvers.typeVariableResolverFromTypeParameters(typeParameters, classDescriptor, context);
transformSupertypeList(result, psiClass.getPsiClass().getExtendsListTypes(), typeVariableResolverForSupertypes); transformSupertypeList(result, psiClass.getPsiClass().getExtendsListTypes(), typeVariableResolverForSupertypes);
transformSupertypeList(result, psiClass.getPsiClass().getImplementsListTypes(), typeVariableResolverForSupertypes); transformSupertypeList(result, psiClass.getPsiClass().getImplementsListTypes(), typeVariableResolverForSupertypes);
} }
for (JetType supertype : result) { for (JetType supertype : result) {
if (ErrorUtils.isErrorType(supertype)) { if (ErrorUtils.isErrorType(supertype)) {
trace.record(BindingContext.INCOMPLETE_HIERARCHY, classDescriptor); trace.record(BindingContext.INCOMPLETE_HIERARCHY, classDescriptor);
} }
} }
if (result.isEmpty()) { if (result.isEmpty()) {
if (classData.isKotlin() if (classData.isKotlin()
|| OBJECT_FQ_NAME.equalsTo(psiClass.getQualifiedName()) || OBJECT_FQ_NAME.equalsTo(psiClass.getQualifiedName())
// TODO: annotations // TODO: annotations
|| classDescriptor.getKind() == ClassKind.ANNOTATION_CLASS) { || classDescriptor.getKind() == ClassKind.ANNOTATION_CLASS) {
result.add(JetStandardClasses.getAnyType()); result.add(JetStandardClasses.getAnyType());
} }
else { else {
@@ -454,7 +456,8 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes
} }
} }
JetType transform = semanticServices.getTypeTransformer().transformToType(type, JavaTypeTransformer.TypeUsage.SUPERTYPE, typeVariableResolver); JetType transform = semanticServices.getTypeTransformer()
.transformToType(type, JavaTypeTransformer.TypeUsage.SUPERTYPE, typeVariableResolver);
if (ErrorUtils.isErrorType(transform)) { if (ErrorUtils.isErrorType(transform)) {
continue; continue;
} }
@@ -482,7 +485,8 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes
@Nullable @Nullable
public PsiClass getPsiClassForJavaPackageScope(@NotNull FqName packageFQN) { public PsiClass getPsiClassForJavaPackageScope(@NotNull FqName packageFQN) {
return psiClassFinder.findPsiClass(packageFQN.child(Name.identifier(JvmAbi.PACKAGE_CLASS)), PsiClassFinder.RuntimeClassesHandleMode.IGNORE); return psiClassFinder
.findPsiClass(packageFQN.child(Name.identifier(JvmAbi.PACKAGE_CLASS)), PsiClassFinder.RuntimeClassesHandleMode.IGNORE);
} }
public static class ValueParameterDescriptors { public static class ValueParameterDescriptors {
@@ -510,7 +514,7 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes
RECEIVER, RECEIVER,
TYPE_INFO, TYPE_INFO,
} }
private static class JvmMethodParameterMeaning { private static class JvmMethodParameterMeaning {
private final JvmMethodParameterKind kind; private final JvmMethodParameterKind kind;
private final JetType receiverType; private final JetType receiverType;
@@ -525,23 +529,25 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes
this.receiverType = receiverType; this.receiverType = receiverType;
this.valueParameterDescriptor = valueParameterDescriptor; this.valueParameterDescriptor = valueParameterDescriptor;
} }
public static JvmMethodParameterMeaning receiver(@NotNull JetType receiverType) { public static JvmMethodParameterMeaning receiver(@NotNull JetType receiverType) {
return new JvmMethodParameterMeaning(JvmMethodParameterKind.RECEIVER, receiverType, null); return new JvmMethodParameterMeaning(JvmMethodParameterKind.RECEIVER, receiverType, null);
} }
public static JvmMethodParameterMeaning regular(@NotNull ValueParameterDescriptor valueParameterDescriptor) { public static JvmMethodParameterMeaning regular(@NotNull ValueParameterDescriptor valueParameterDescriptor) {
return new JvmMethodParameterMeaning(JvmMethodParameterKind.REGULAR, null, valueParameterDescriptor); return new JvmMethodParameterMeaning(JvmMethodParameterKind.REGULAR, null, valueParameterDescriptor);
} }
public static JvmMethodParameterMeaning typeInfo() { public static JvmMethodParameterMeaning typeInfo() {
return new JvmMethodParameterMeaning(JvmMethodParameterKind.TYPE_INFO, null, null); return new JvmMethodParameterMeaning(JvmMethodParameterKind.TYPE_INFO, null, null);
} }
} }
@NotNull @NotNull
private JvmMethodParameterMeaning resolveParameterDescriptor(DeclarationDescriptor containingDeclaration, int i, private JvmMethodParameterMeaning resolveParameterDescriptor(
PsiParameterWrapper parameter, TypeVariableResolver typeVariableResolver) { DeclarationDescriptor containingDeclaration, int i,
PsiParameterWrapper parameter, TypeVariableResolver typeVariableResolver
) {
if (parameter.getJetTypeParameter().isDefined()) { if (parameter.getJetTypeParameter().isDefined()) {
return JvmMethodParameterMeaning.typeInfo(); return JvmMethodParameterMeaning.typeInfo();
@@ -555,7 +561,7 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes
if (parameter.getJetValueParameter().name().length() > 0) { if (parameter.getJetValueParameter().name().length() > 0) {
name = Name.identifier(parameter.getJetValueParameter().name()); name = Name.identifier(parameter.getJetValueParameter().name());
} }
String typeFromAnnotation = parameter.getJetValueParameter().type(); String typeFromAnnotation = parameter.getJetValueParameter().type();
boolean receiver = parameter.getJetValueParameter().receiver(); boolean receiver = parameter.getJetValueParameter().receiver();
boolean hasDefaultValue = parameter.getJetValueParameter().hasDefaultValue(); boolean hasDefaultValue = parameter.getJetValueParameter().hasDefaultValue();
@@ -565,7 +571,8 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes
outType = semanticServices.getTypeTransformer().transformToType(typeFromAnnotation, typeVariableResolver); outType = semanticServices.getTypeTransformer().transformToType(typeFromAnnotation, typeVariableResolver);
} }
else { else {
outType = semanticServices.getTypeTransformer().transformToType(psiType, JavaTypeTransformer.TypeUsage.MEMBER_SIGNATURE_CONTRAVARIANT, typeVariableResolver); outType = semanticServices.getTypeTransformer()
.transformToType(psiType, JavaTypeTransformer.TypeUsage.MEMBER_SIGNATURE_CONTRAVARIANT, typeVariableResolver);
} }
JetType varargElementType; JetType varargElementType;
@@ -584,7 +591,8 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes
JetType transformedType; JetType transformedType;
if (AnnotationResolver if (AnnotationResolver
.findAnnotation(parameter.getPsiParameter(), JvmAbi.JETBRAINS_NOT_NULL_ANNOTATION.getFqName().getFqName()) != null) { .findAnnotation(parameter.getPsiParameter(), JvmAbi.JETBRAINS_NOT_NULL_ANNOTATION.getFqName().getFqName()) !=
null) {
transformedType = TypeUtils.makeNullableAsSpecified(outType, false); transformedType = TypeUtils.makeNullableAsSpecified(outType, false);
} }
else { else {
@@ -616,11 +624,11 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes
//noinspection ConstantConditions //noinspection ConstantConditions
String qualifiedName = psiClass == null ? scopeData.getPsiPackage().getQualifiedName() : psiClass.getQualifiedName(); String qualifiedName = psiClass == null ? scopeData.getPsiPackage().getQualifiedName() : psiClass.getQualifiedName();
propertiesResolver.resolveNamedGroupProperties(scopeData.getClassOrNamespaceDescriptor(), scopeData, namedMembers, fieldName, propertiesResolver.resolveNamedGroupProperties(scopeData.getClassOrNamespaceDescriptor(), scopeData, namedMembers, fieldName,
"class or namespace " + qualifiedName); "class or namespace " + qualifiedName);
return namedMembers.getPropertyDescriptors(); return namedMembers.getPropertyDescriptors();
} }
@NotNull @NotNull
public Set<VariableDescriptor> resolveFieldGroup(@NotNull ResolverScopeData scopeData) { public Set<VariableDescriptor> resolveFieldGroup(@NotNull ResolverScopeData scopeData) {
@@ -642,67 +650,6 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes
return descriptors; return descriptors;
} }
private void resolveNamedGroupFunctions(
@NotNull ClassOrNamespaceDescriptor owner, PsiClass psiClass,
NamedMembers namedMembers, Name methodName, ResolverScopeData scopeData
) {
if (namedMembers.getFunctionDescriptors() != null) {
return;
}
final Set<FunctionDescriptor> functions = new HashSet<FunctionDescriptor>();
Set<SimpleFunctionDescriptor> functionsFromCurrent = Sets.newHashSet();
for (PsiMethodWrapper method : namedMembers.getMethods()) {
SimpleFunctionDescriptor function = functionResolver.resolveMethodToFunctionDescriptor(psiClass, method, scopeData);
if (function != null) {
functionsFromCurrent.add(function);
}
}
if (owner instanceof ClassDescriptor) {
ClassDescriptor classDescriptor = (ClassDescriptor) owner;
Set<SimpleFunctionDescriptor> functionsFromSupertypes = getFunctionsFromSupertypes(scopeData, methodName);
OverrideResolver.generateOverridesInFunctionGroup(methodName, functionsFromSupertypes, functionsFromCurrent, classDescriptor,
new OverrideResolver.DescriptorSink() {
@Override
public void addToScope(@NotNull CallableMemberDescriptor fakeOverride) {
functions.add((FunctionDescriptor) fakeOverride);
}
@Override
public void conflict(@NotNull CallableMemberDescriptor fromSuper, @NotNull CallableMemberDescriptor fromCurrent) {
// nop
}
});
}
OverrideResolver.resolveUnknownVisibilities(functions, trace);
functions.addAll(functionsFromCurrent);
if (DescriptorUtils.isEnumClassObject(owner)) {
for (FunctionDescriptor functionDescriptor : Lists.newArrayList(functions)) {
if (isEnumSpecialMethod(functionDescriptor)) {
functions.remove(functionDescriptor);
}
}
}
namedMembers.setFunctionDescriptors(functions);
}
private static Set<SimpleFunctionDescriptor> getFunctionsFromSupertypes(ResolverScopeData scopeData, Name methodName) {
Set<SimpleFunctionDescriptor> r = Sets.newLinkedHashSet();
for (JetType supertype : getSupertypes(scopeData)) {
for (FunctionDescriptor function : supertype.getMemberScope().getFunctions(methodName)) {
r.add((SimpleFunctionDescriptor) function);
}
}
return r;
}
public static void getResolverScopeData(@NotNull ResolverScopeData scopeData) { public static void getResolverScopeData(@NotNull ResolverScopeData scopeData) {
if (scopeData.getNamedMembersMap() == null) { if (scopeData.getNamedMembersMap() == null) {
@@ -712,21 +659,7 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes
@NotNull @NotNull
public Set<FunctionDescriptor> resolveFunctionGroup(@NotNull Name methodName, @NotNull ResolverScopeData scopeData) { public Set<FunctionDescriptor> resolveFunctionGroup(@NotNull Name methodName, @NotNull ResolverScopeData scopeData) {
return functionResolver.resolveFunctionGroup(methodName, scopeData);
getResolverScopeData(scopeData);
Map<Name, NamedMembers> namedMembersMap = scopeData.getNamedMembersMap();
NamedMembers namedMembers = namedMembersMap.get(methodName);
if (namedMembers != null) {
resolveNamedGroupFunctions(scopeData.getClassOrNamespaceDescriptor(), scopeData.getPsiClass(), namedMembers, methodName, scopeData);
return namedMembers.getFunctionDescriptors();
}
else {
return Collections.emptySet();
}
} }
public ValueParameterDescriptors resolveParameterDescriptors( public ValueParameterDescriptors resolveParameterDescriptors(
@@ -738,7 +671,8 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes
int indexDelta = 0; int indexDelta = 0;
for (int i = 0, parametersLength = parameters.size(); i < parametersLength; i++) { for (int i = 0, parametersLength = parameters.size(); i < parametersLength; i++) {
PsiParameterWrapper parameter = parameters.get(i); PsiParameterWrapper parameter = parameters.get(i);
JvmMethodParameterMeaning meaning = resolveParameterDescriptor(containingDeclaration, i + indexDelta, parameter, typeVariableResolver); JvmMethodParameterMeaning meaning =
resolveParameterDescriptor(containingDeclaration, i + indexDelta, parameter, typeVariableResolver);
if (meaning.kind == JvmMethodParameterKind.TYPE_INFO) { if (meaning.kind == JvmMethodParameterKind.TYPE_INFO) {
// TODO // TODO
--indexDelta; --indexDelta;
@@ -757,17 +691,6 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes
return new ValueParameterDescriptors(receiverType, result); return new ValueParameterDescriptors(receiverType, result);
} }
private static boolean isEnumSpecialMethod(@NotNull FunctionDescriptor functionDescriptor) {
List<ValueParameterDescriptor> methodTypeParameters = functionDescriptor.getValueParameters();
String methodName = functionDescriptor.getName().getName();
JetType nullableString = TypeUtils.makeNullable(JetStandardLibrary.getInstance().getStringType());
if (methodName.equals("valueOf") && methodTypeParameters.size() == 1
&& JetTypeChecker.INSTANCE.isSubtypeOf(methodTypeParameters.get(0).getType(), nullableString)) {
return true;
}
return (methodName.equals("values") && methodTypeParameters.isEmpty());
}
public List<AnnotationDescriptor> resolveAnnotations(PsiModifierListOwner owner, @NotNull List<Runnable> tasks) { public List<AnnotationDescriptor> resolveAnnotations(PsiModifierListOwner owner, @NotNull List<Runnable> tasks) {
return annotationResolver.resolveAnnotations(owner, tasks); return annotationResolver.resolveAnnotations(owner, tasks);
} }
@@ -778,10 +701,6 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes
@Nullable @Nullable
public AnnotationDescriptor resolveAnnotation(PsiAnnotation psiAnnotation, @NotNull List<Runnable> taskList) { public AnnotationDescriptor resolveAnnotation(PsiAnnotation psiAnnotation, @NotNull List<Runnable> taskList) {
// Don't process internal jet annotations and jetbrains NotNull annotations
return annotationResolver.resolveAnnotation(psiAnnotation, taskList); return annotationResolver.resolveAnnotation(psiAnnotation, taskList);
} }
@@ -804,20 +723,7 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes
} }
public List<FunctionDescriptor> resolveMethods(@NotNull ResolverScopeData scopeData) { public List<FunctionDescriptor> resolveMethods(@NotNull ResolverScopeData scopeData) {
return functionResolver.resolveMethods(scopeData);
getResolverScopeData(scopeData);
List<FunctionDescriptor> functions = new ArrayList<FunctionDescriptor>();
for (Map.Entry<Name, NamedMembers> entry : scopeData.getNamedMembersMap().entrySet()) {
Name methodName = entry.getKey();
NamedMembers namedMembers = entry.getValue();
resolveNamedGroupFunctions(scopeData.getClassOrNamespaceDescriptor(), scopeData.getPsiClass(),
namedMembers, methodName, scopeData);
functions.addAll(namedMembers.getFunctionDescriptors());
}
return functions;
} }
public static Collection<JetType> getSupertypes(ResolverScopeData scope) { public static Collection<JetType> getSupertypes(ResolverScopeData scope) {
@@ -848,7 +754,8 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes
returnType, JavaTypeTransformer.TypeUsage.MEMBER_SIGNATURE_COVARIANT, typeVariableResolver); returnType, JavaTypeTransformer.TypeUsage.MEMBER_SIGNATURE_COVARIANT, typeVariableResolver);
} }
if (AnnotationResolver.findAnnotation(method.getPsiMethod(), JvmAbi.JETBRAINS_NOT_NULL_ANNOTATION.getFqName().getFqName()) != null) { if (AnnotationResolver.findAnnotation(method.getPsiMethod(), JvmAbi.JETBRAINS_NOT_NULL_ANNOTATION.getFqName().getFqName()) !=
null) {
return TypeUtils.makeNullableAsSpecified(transformedType, false); return TypeUtils.makeNullableAsSpecified(transformedType, false);
} }
else { else {
@@ -16,29 +16,29 @@
package org.jetbrains.jet.lang.resolve.java.resolver; package org.jetbrains.jet.lang.resolve.java.resolver;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.intellij.psi.PsiClass; import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiMethod; import com.intellij.psi.PsiMethod;
import com.intellij.psi.PsiType; import com.intellij.psi.PsiType;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.CallableMemberDescriptor; import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.descriptors.SimpleFunctionDescriptor;
import org.jetbrains.jet.lang.descriptors.SimpleFunctionDescriptorImpl;
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.BindingContextUtils; import org.jetbrains.jet.lang.resolve.BindingContextUtils;
import org.jetbrains.jet.lang.resolve.DescriptorUtils; import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolveData; import org.jetbrains.jet.lang.resolve.OverrideResolver;
import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolver; import org.jetbrains.jet.lang.resolve.java.*;
import org.jetbrains.jet.lang.resolve.java.TypeVariableResolver;
import org.jetbrains.jet.lang.resolve.java.TypeVariableResolvers;
import org.jetbrains.jet.lang.resolve.java.kotlinSignature.AlternativeMethodSignatureData; import org.jetbrains.jet.lang.resolve.java.kotlinSignature.AlternativeMethodSignatureData;
import org.jetbrains.jet.lang.resolve.java.kt.DescriptorKindUtils; import org.jetbrains.jet.lang.resolve.java.kt.DescriptorKindUtils;
import org.jetbrains.jet.lang.resolve.java.wrapper.PsiMethodWrapper; import org.jetbrains.jet.lang.resolve.java.wrapper.PsiMethodWrapper;
import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.TypeUtils;
import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
import org.jetbrains.jet.lang.types.lang.JetStandardLibrary;
import java.util.List; import java.util.*;
public class FunctionResolver { public class FunctionResolver {
private final JavaDescriptorResolver javaDescriptorResolver; private final JavaDescriptorResolver javaDescriptorResolver;
@@ -135,4 +135,117 @@ public class FunctionResolver {
} }
return functionDescriptorImpl; return functionDescriptorImpl;
} }
public void resolveNamedGroupFunctions(
@NotNull ClassOrNamespaceDescriptor owner, PsiClass psiClass,
NamedMembers namedMembers, Name methodName, JavaDescriptorResolveData.ResolverScopeData scopeData
) {
if (namedMembers.getFunctionDescriptors() != null) {
return;
}
final Set<FunctionDescriptor> functions = new HashSet<FunctionDescriptor>();
Set<SimpleFunctionDescriptor> functionsFromCurrent = Sets.newHashSet();
for (PsiMethodWrapper method : namedMembers.getMethods()) {
SimpleFunctionDescriptor function = resolveMethodToFunctionDescriptor(psiClass, method, scopeData);
if (function != null) {
functionsFromCurrent.add(function);
}
}
if (owner instanceof ClassDescriptor) {
ClassDescriptor classDescriptor = (ClassDescriptor) owner;
Set<SimpleFunctionDescriptor> functionsFromSupertypes = getFunctionsFromSupertypes(scopeData, methodName);
OverrideResolver.generateOverridesInFunctionGroup(methodName, functionsFromSupertypes, functionsFromCurrent, classDescriptor,
new OverrideResolver.DescriptorSink() {
@Override
public void addToScope(@NotNull CallableMemberDescriptor fakeOverride) {
functions.add((FunctionDescriptor) fakeOverride);
}
@Override
public void conflict(
@NotNull CallableMemberDescriptor fromSuper,
@NotNull CallableMemberDescriptor fromCurrent
) {
// nop
}
});
}
OverrideResolver.resolveUnknownVisibilities(functions, javaDescriptorResolver.getTrace());
functions.addAll(functionsFromCurrent);
if (DescriptorUtils.isEnumClassObject(owner)) {
for (FunctionDescriptor functionDescriptor : Lists.newArrayList(functions)) {
if (isEnumSpecialMethod(functionDescriptor)) {
functions.remove(functionDescriptor);
}
}
}
namedMembers.setFunctionDescriptors(functions);
}
public Set<FunctionDescriptor> resolveFunctionGroup(Name methodName, JavaDescriptorResolveData.ResolverScopeData scopeData) {
JavaDescriptorResolver.getResolverScopeData(scopeData);
Map<Name, NamedMembers> namedMembersMap = scopeData.getNamedMembersMap();
NamedMembers namedMembers = namedMembersMap.get(methodName);
if (namedMembers != null) {
resolveNamedGroupFunctions(scopeData.getClassOrNamespaceDescriptor(), scopeData.getPsiClass(), namedMembers,
methodName, scopeData);
return namedMembers.getFunctionDescriptors();
}
else {
return Collections.emptySet();
}
}
public static Set<SimpleFunctionDescriptor> getFunctionsFromSupertypes(
JavaDescriptorResolveData.ResolverScopeData scopeData,
Name methodName
) {
Set<SimpleFunctionDescriptor> r = Sets.newLinkedHashSet();
for (JetType supertype : JavaDescriptorResolver.getSupertypes(scopeData)) {
for (FunctionDescriptor function : supertype.getMemberScope().getFunctions(methodName)) {
r.add((SimpleFunctionDescriptor) function);
}
}
return r;
}
public List<FunctionDescriptor> resolveMethods(@NotNull JavaDescriptorResolveData.ResolverScopeData scopeData) {
JavaDescriptorResolver.getResolverScopeData(scopeData);
List<FunctionDescriptor> functions = new ArrayList<FunctionDescriptor>();
for (Map.Entry<Name, NamedMembers> entry : scopeData.getNamedMembersMap().entrySet()) {
Name methodName = entry.getKey();
NamedMembers namedMembers = entry.getValue();
resolveNamedGroupFunctions(scopeData.getClassOrNamespaceDescriptor(), scopeData.getPsiClass(),
namedMembers, methodName, scopeData);
functions.addAll(namedMembers.getFunctionDescriptors());
}
return functions;
}
public static boolean isEnumSpecialMethod(@NotNull FunctionDescriptor functionDescriptor) {
List<ValueParameterDescriptor> methodTypeParameters = functionDescriptor.getValueParameters();
String methodName = functionDescriptor.getName().getName();
JetType nullableString = TypeUtils.makeNullable(JetStandardLibrary.getInstance().getStringType());
if (methodName.equals("valueOf") && methodTypeParameters.size() == 1
&& JetTypeChecker.INSTANCE.isSubtypeOf(methodTypeParameters.get(0).getType(), nullableString)) {
return true;
}
return (methodName.equals("values") && methodTypeParameters.isEmpty());
}
} }