Refactor override resolution in JDR

Unify the code between JavaFunctionResolver and JavaPropertyResolver
This commit is contained in:
Alexander Udalov
2013-08-05 17:42:52 +04:00
parent 520f812030
commit 70c7fbc6d1
3 changed files with 69 additions and 96 deletions
@@ -23,17 +23,15 @@ import com.intellij.psi.impl.compiled.ClsClassImpl;
import com.intellij.psi.util.PsiFormatUtil;
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.ConstructorDescriptor;
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.resolve.BindingTrace;
import org.jetbrains.jet.lang.resolve.OverrideResolver;
import org.jetbrains.jet.lang.resolve.java.structure.JavaClass;
import org.jetbrains.jet.lang.resolve.java.structure.JavaField;
import org.jetbrains.jet.lang.resolve.java.structure.JavaMember;
import org.jetbrains.jet.lang.resolve.java.structure.JavaMethod;
import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.types.JetType;
import java.util.*;
@@ -73,11 +71,34 @@ public final class DescriptorResolverUtils {
}
@NotNull
public static Collection<JetType> getSupertypes(@NotNull ClassOrNamespaceDescriptor classOrNamespaceDescriptor) {
if (classOrNamespaceDescriptor instanceof ClassDescriptor) {
return ((ClassDescriptor) classOrNamespaceDescriptor).getTypeConstructor().getSupertypes();
}
return Collections.emptyList();
public static <D extends CallableMemberDescriptor> Collection<D> resolveOverrides(
@NotNull Name name,
@NotNull Collection<D> membersFromSupertypes,
@NotNull Collection<D> membersFromCurrent,
@NotNull ClassDescriptor classDescriptor,
@NotNull BindingTrace trace
) {
final Set<D> result = new HashSet<D>();
OverrideResolver.generateOverridesInFunctionGroup(
name, membersFromSupertypes, membersFromCurrent, classDescriptor,
new OverrideResolver.DescriptorSink() {
@Override
@SuppressWarnings("unchecked")
public void addToScope(@NotNull CallableMemberDescriptor fakeOverride) {
result.add((D) fakeOverride);
}
@Override
public void conflict(@NotNull CallableMemberDescriptor fromSuper, @NotNull CallableMemberDescriptor fromCurrent) {
// nop
}
}
);
OverrideResolver.resolveUnknownVisibilities(result, trace);
return result;
}
@Nullable
@@ -26,7 +26,10 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.descriptors.impl.NamespaceDescriptorParent;
import org.jetbrains.jet.lang.descriptors.impl.SimpleFunctionDescriptorImpl;
import org.jetbrains.jet.lang.resolve.*;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.BindingContextUtils;
import org.jetbrains.jet.lang.resolve.BindingTrace;
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.java.DescriptorResolverUtils;
import org.jetbrains.jet.lang.resolve.java.JavaBindingContext;
import org.jetbrains.jet.lang.resolve.java.TypeUsage;
@@ -43,13 +46,11 @@ import org.jetbrains.jet.lang.types.*;
import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
import javax.inject.Inject;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.*;
import static org.jetbrains.jet.lang.resolve.DescriptorUtils.*;
import static org.jetbrains.jet.lang.resolve.OverridingUtil.*;
import static org.jetbrains.jet.lang.resolve.java.DescriptorResolverUtils.resolveOverrides;
import static org.jetbrains.jet.lang.resolve.java.sam.SingleAbstractMethodUtils.*;
public final class JavaFunctionResolver {
@@ -236,11 +237,6 @@ public final class JavaFunctionResolver {
public Set<FunctionDescriptor> resolveFunctionGroupForClass(@NotNull NamedMembers members, @NotNull ClassOrNamespaceDescriptor owner) {
Name methodName = members.getName();
Set<SimpleFunctionDescriptor> functionsFromSupertypes = null;
if (owner instanceof ClassDescriptor) {
functionsFromSupertypes = getFunctionsFromSupertypes(methodName, owner);
}
Set<SimpleFunctionDescriptor> functionsFromCurrent = Sets.newHashSet();
for (JavaMethod method : members.getMethods()) {
SimpleFunctionDescriptor function = resolveMethodToFunctionDescriptor(method, owner, true);
@@ -254,31 +250,15 @@ public final class JavaFunctionResolver {
ContainerUtil.addIfNotNull(functionsFromCurrent, resolveSamConstructor((NamespaceDescriptor) owner, members));
}
final Set<FunctionDescriptor> fakeOverrides = new HashSet<FunctionDescriptor>();
Set<FunctionDescriptor> functions = new HashSet<FunctionDescriptor>();
if (owner instanceof ClassDescriptor) {
ClassDescriptor classDescriptor = (ClassDescriptor) owner;
OverrideResolver.generateOverridesInFunctionGroup(methodName, functionsFromSupertypes, functionsFromCurrent, classDescriptor,
new OverrideResolver.DescriptorSink() {
@Override
public void addToScope(@NotNull CallableMemberDescriptor fakeOverride) {
fakeOverrides.add((FunctionDescriptor) fakeOverride);
}
Collection<SimpleFunctionDescriptor> functionsFromSupertypes = getFunctionsFromSupertypes(methodName, classDescriptor);
@Override
public void conflict(
@NotNull CallableMemberDescriptor fromSuper,
@NotNull CallableMemberDescriptor fromCurrent
) {
// nop
}
});
functions.addAll(resolveOverrides(methodName, functionsFromSupertypes, functionsFromCurrent, classDescriptor, trace));
}
OverrideResolver.resolveUnknownVisibilities(fakeOverrides, trace);
Set<FunctionDescriptor> functions = Sets.newHashSet(fakeOverrides);
if (isEnumClassObject(owner)) {
for (FunctionDescriptor functionDescriptor : functionsFromCurrent) {
if (!(isEnumValueOfMethod(functionDescriptor) || isEnumValuesMethod(functionDescriptor))) {
@@ -378,16 +358,14 @@ public final class JavaFunctionResolver {
}
@NotNull
private static Set<SimpleFunctionDescriptor> getFunctionsFromSupertypes(
@NotNull Name methodName, @NotNull ClassOrNamespaceDescriptor classOrNamespaceDescriptor
) {
Set<SimpleFunctionDescriptor> r = Sets.newLinkedHashSet();
for (JetType supertype : DescriptorResolverUtils.getSupertypes(classOrNamespaceDescriptor)) {
for (FunctionDescriptor function : supertype.getMemberScope().getFunctions(methodName)) {
r.add((SimpleFunctionDescriptor) function);
private static Set<SimpleFunctionDescriptor> getFunctionsFromSupertypes(@NotNull Name name, @NotNull ClassDescriptor descriptor) {
Set<SimpleFunctionDescriptor> result = Sets.newLinkedHashSet();
for (JetType supertype : descriptor.getTypeConstructor().getSupertypes()) {
for (FunctionDescriptor function : supertype.getMemberScope().getFunctions(name)) {
result.add((SimpleFunctionDescriptor) function);
}
}
return r;
return result;
}
private static boolean containsErrorType(@NotNull List<FunctionDescriptor> superFunctions, @NotNull FunctionDescriptor function) {
@@ -25,7 +25,10 @@ import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.descriptors.impl.ClassDescriptorImpl;
import org.jetbrains.jet.lang.descriptors.impl.PropertyDescriptorForObjectImpl;
import org.jetbrains.jet.lang.descriptors.impl.PropertyDescriptorImpl;
import org.jetbrains.jet.lang.resolve.*;
import org.jetbrains.jet.lang.resolve.AnnotationUtils;
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.constants.CompileTimeConstant;
import org.jetbrains.jet.lang.resolve.java.DescriptorResolverUtils;
import org.jetbrains.jet.lang.resolve.java.JavaBindingContext;
@@ -38,10 +41,9 @@ import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.TypeUtils;
import javax.inject.Inject;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.*;
import static org.jetbrains.jet.lang.resolve.java.DescriptorResolverUtils.resolveOverrides;
public final class JavaPropertyResolver {
private JavaTypeTransformer typeTransformer;
@@ -67,7 +69,7 @@ public final class JavaPropertyResolver {
}
@NotNull
public Set<VariableDescriptor> resolveFieldGroup(@NotNull NamedMembers members, @NotNull ClassOrNamespaceDescriptor ownerDescriptor) {
public Set<VariableDescriptor> resolveFieldGroup(@NotNull NamedMembers members, @NotNull ClassOrNamespaceDescriptor owner) {
Name propertyName = members.getName();
List<JavaField> fields = members.getFields();
@@ -76,52 +78,25 @@ public final class JavaPropertyResolver {
assert fields.size() <= 1;
if (fields.size() == 1) {
JavaField field = fields.iterator().next();
if (DescriptorResolverUtils.isCorrectOwnerForEnumMember(ownerDescriptor, field)) {
propertiesFromCurrent.add(resolveProperty(ownerDescriptor, propertyName, field));
if (DescriptorResolverUtils.isCorrectOwnerForEnumMember(owner, field)) {
propertiesFromCurrent.add(resolveProperty(owner, propertyName, field));
}
}
Set<PropertyDescriptor> propertiesFromSupertypes = getPropertiesFromSupertypes(propertyName, ownerDescriptor);
Set<PropertyDescriptor> properties = Sets.newHashSet();
if (owner instanceof ClassDescriptor) {
ClassDescriptor classDescriptor = (ClassDescriptor) owner;
generateOverrides(ownerDescriptor, propertyName, propertiesFromCurrent, propertiesFromSupertypes, properties);
OverrideResolver.resolveUnknownVisibilities(properties, trace);
Collection<PropertyDescriptor> propertiesFromSupertypes = getPropertiesFromSupertypes(propertyName, classDescriptor);
properties.addAll(resolveOverrides(propertyName, propertiesFromSupertypes, propertiesFromCurrent, classDescriptor, trace));
}
properties.addAll(propertiesFromCurrent);
return Sets.<VariableDescriptor>newHashSet(properties);
}
private static void generateOverrides(
@NotNull ClassOrNamespaceDescriptor owner,
@NotNull Name propertyName,
@NotNull Set<PropertyDescriptor> propertiesFromCurrent,
@NotNull Set<PropertyDescriptor> propertiesFromSupertypes,
@NotNull final Set<PropertyDescriptor> properties
) {
if (!(owner instanceof ClassDescriptor)) {
return;
}
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
}
});
}
@NotNull
private PropertyDescriptor resolveProperty(@NotNull ClassOrNamespaceDescriptor owner, @NotNull Name name, @NotNull JavaField field) {
boolean isVar = !field.isFinal();
@@ -230,16 +205,15 @@ public final class JavaPropertyResolver {
}
@NotNull
private static Set<PropertyDescriptor> getPropertiesFromSupertypes(
@NotNull Name propertyName, @NotNull ClassOrNamespaceDescriptor ownerDescriptor
) {
Set<PropertyDescriptor> r = new HashSet<PropertyDescriptor>();
for (JetType supertype : DescriptorResolverUtils.getSupertypes(ownerDescriptor)) {
for (VariableDescriptor property : supertype.getMemberScope().getProperties(propertyName)) {
r.add((PropertyDescriptor) property);
private static Set<PropertyDescriptor> getPropertiesFromSupertypes(@NotNull Name name, @NotNull ClassDescriptor descriptor) {
Set<PropertyDescriptor> result = new HashSet<PropertyDescriptor>();
for (JetType supertype : descriptor.getTypeConstructor().getSupertypes()) {
for (VariableDescriptor property : supertype.getMemberScope().getProperties(name)) {
result.add((PropertyDescriptor) property);
}
}
return r;
return result;
}
private static boolean isStaticFinalField(@NotNull JavaField field) {