Refactor DescriptorUtils

Remove dependency on org.jetbrains.jet.lang.psi, move utilities closer to their
usages, add NotNull annotations, fix formatting, etc.
This commit is contained in:
Alexander Udalov
2013-08-21 22:15:15 +04:00
parent 8400d2b8cf
commit d0a9464504
12 changed files with 136 additions and 165 deletions
@@ -24,12 +24,12 @@ import org.jetbrains.jet.lang.descriptors.annotations.Annotated;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.diagnostics.Errors;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall;
import org.jetbrains.jet.lang.resolve.calls.util.CallMaker;
import org.jetbrains.jet.lang.resolve.calls.CallResolver;
import org.jetbrains.jet.lang.resolve.calls.results.OverloadResolutionResults;
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedValueArgument;
import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo;
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall;
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedValueArgument;
import org.jetbrains.jet.lang.resolve.calls.results.OverloadResolutionResults;
import org.jetbrains.jet.lang.resolve.calls.util.CallMaker;
import org.jetbrains.jet.lang.resolve.constants.*;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue;
@@ -341,13 +341,10 @@ public class AnnotationResolver {
}
private static boolean isEnumProperty(@NotNull PropertyDescriptor descriptor) {
if (DescriptorUtils.isKindOf(descriptor.getType(), ClassKind.ENUM_CLASS)) {
DeclarationDescriptor enumClassObject = descriptor.getContainingDeclaration();
if (DescriptorUtils.isKindOf(enumClassObject, ClassKind.CLASS_OBJECT)) {
return DescriptorUtils.isKindOf(enumClassObject.getContainingDeclaration(), ClassKind.ENUM_CLASS);
}
}
return false;
ClassifierDescriptor classifier = descriptor.getType().getConstructor().getDeclarationDescriptor();
return classifier != null &&
DescriptorUtils.isEnumClass(classifier) &&
DescriptorUtils.isEnumClassObject(descriptor.getContainingDeclaration());
}
@NotNull
@@ -1083,14 +1083,14 @@ public class DescriptorResolver {
}
@Nullable
private JetType transformAnonymousTypeIfNeeded(
private static JetType transformAnonymousTypeIfNeeded(
@NotNull DeclarationDescriptorWithVisibility descriptor,
@NotNull JetNamedDeclaration declaration,
@NotNull JetType type,
@NotNull BindingTrace trace
) {
ClassifierDescriptor classifierDescriptor = type.getConstructor().getDeclarationDescriptor();
if (!DescriptorUtils.isAnonymous(classifierDescriptor)) {
if (classifierDescriptor == null || !DescriptorUtils.isAnonymous(classifierDescriptor)) {
return type;
}
@@ -24,17 +24,12 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.descriptors.impl.AnonymousFunctionDescriptor;
import org.jetbrains.jet.lang.psi.JetElement;
import org.jetbrains.jet.lang.psi.JetFunction;
import org.jetbrains.jet.lang.psi.JetParameter;
import org.jetbrains.jet.lang.psi.JetProperty;
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant;
import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.lang.resolve.name.FqNameUnsafe;
import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.resolve.scopes.FilteringScope;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue;
import org.jetbrains.jet.lang.types.*;
import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
@@ -45,6 +40,8 @@ import java.util.*;
import static org.jetbrains.jet.lang.descriptors.ReceiverParameterDescriptor.NO_RECEIVER_PARAMETER;
public class DescriptorUtils {
private DescriptorUtils() {
}
@NotNull
public static <D extends CallableDescriptor> D substituteBounds(@NotNull D functionDescriptor) {
@@ -59,7 +56,8 @@ public class DescriptorUtils {
return substitutedFunction;
}
public static Modality convertModality(Modality modality, boolean makeNonAbstract) {
@NotNull
public static Modality convertModality(@NotNull Modality modality, boolean makeNonAbstract) {
if (makeNonAbstract && modality == Modality.ABSTRACT) return Modality.OPEN;
return modality;
}
@@ -126,7 +124,7 @@ public class DescriptorUtils {
return FqName.ROOT.toUnsafe();
}
}
throw new IllegalStateException("descriptor is not module descriptor and has null containingDeclaration: " + containingDeclaration);
throw new IllegalStateException("descriptor is not module descriptor and has null containingDeclaration: " + descriptor);
}
if (containingDeclaration instanceof ClassDescriptor && ((ClassDescriptor) containingDeclaration).getKind() == ClassKind.CLASS_OBJECT) {
@@ -143,8 +141,8 @@ public class DescriptorUtils {
}
public static boolean isInSameModule(@NotNull DeclarationDescriptor first, @NotNull DeclarationDescriptor second) {
ModuleDescriptor parentModule = DescriptorUtils.getParentOfType(first, ModuleDescriptorImpl.class, false);
ModuleDescriptor fromModule = DescriptorUtils.getParentOfType(second, ModuleDescriptorImpl.class, false);
ModuleDescriptor parentModule = getParentOfType(first, ModuleDescriptorImpl.class, false);
ModuleDescriptor fromModule = getParentOfType(second, ModuleDescriptorImpl.class, false);
assert parentModule != null && fromModule != null;
return parentModule.equals(fromModule);
}
@@ -153,7 +151,7 @@ public class DescriptorUtils {
public static DeclarationDescriptor findTopLevelParent(@NotNull DeclarationDescriptor declarationDescriptor) {
DeclarationDescriptor descriptor = declarationDescriptor;
if (declarationDescriptor instanceof PropertyAccessorDescriptor) {
descriptor = ((PropertyAccessorDescriptor)descriptor).getCorrespondingProperty();
descriptor = ((PropertyAccessorDescriptor) descriptor).getCorrespondingProperty();
}
while (!(descriptor == null || isTopLevelDeclaration(descriptor))) {
descriptor = descriptor.getContainingDeclaration();
@@ -162,12 +160,19 @@ public class DescriptorUtils {
}
@Nullable
public static <D extends DeclarationDescriptor> D getParentOfType(@Nullable DeclarationDescriptor descriptor, @NotNull Class<D> aClass) {
public static <D extends DeclarationDescriptor> D getParentOfType(
@Nullable DeclarationDescriptor descriptor,
@NotNull Class<D> aClass
) {
return getParentOfType(descriptor, aClass, true);
}
@Nullable
public static <D extends DeclarationDescriptor> D getParentOfType(@Nullable DeclarationDescriptor descriptor, @NotNull Class<D> aClass, boolean strict) {
public static <D extends DeclarationDescriptor> D getParentOfType(
@Nullable DeclarationDescriptor descriptor,
@NotNull Class<D> aClass,
boolean strict
) {
if (descriptor == null) return null;
if (strict) {
descriptor = descriptor.getContainingDeclaration();
@@ -182,7 +187,11 @@ public class DescriptorUtils {
return null;
}
public static boolean isAncestor(@Nullable DeclarationDescriptor ancestor, @NotNull DeclarationDescriptor declarationDescriptor, boolean strict) {
public static boolean isAncestor(
@Nullable DeclarationDescriptor ancestor,
@NotNull DeclarationDescriptor declarationDescriptor,
boolean strict
) {
if (ancestor == null) return false;
DeclarationDescriptor descriptor = strict ? declarationDescriptor.getContainingDeclaration() : declarationDescriptor;
while (descriptor != null) {
@@ -192,23 +201,6 @@ public class DescriptorUtils {
return false;
}
@NotNull
public static JetType getFunctionExpectedReturnType(@NotNull FunctionDescriptor descriptor, @NotNull JetElement function) {
JetType expectedType;
if (function instanceof JetFunction) {
if (((JetFunction) function).getReturnTypeRef() != null || ((JetFunction) function).hasBlockBody()) {
expectedType = descriptor.getReturnType();
}
else {
expectedType = TypeUtils.NO_EXPECTED_TYPE;
}
}
else {
expectedType = descriptor.getReturnType();
}
return expectedType != null ? expectedType : TypeUtils.NO_EXPECTED_TYPE;
}
public static boolean isSubclass(@NotNull ClassDescriptor subClass, @NotNull ClassDescriptor superClass) {
return isSubtypeOfClass(subClass.getDefaultType(), superClass.getOriginal());
}
@@ -226,7 +218,7 @@ public class DescriptorUtils {
return false;
}
public static void addSuperTypes(JetType type, Set<JetType> set) {
public static void addSuperTypes(@NotNull JetType type, @NotNull Set<JetType> set) {
set.add(type);
for (JetType jetType : type.getConstructor().getSupertypes()) {
@@ -238,19 +230,6 @@ public class DescriptorUtils {
return namespaceDescriptor.getContainingDeclaration() instanceof ModuleDescriptor;
}
@NotNull
public static List<DeclarationDescriptor> getPathWithoutRootNsAndModule(@NotNull DeclarationDescriptor descriptor) {
List<DeclarationDescriptor> path = Lists.newArrayList();
DeclarationDescriptor current = descriptor;
while (true) {
if (current instanceof NamespaceDescriptor && isRootNamespace((NamespaceDescriptor) current)) {
return Lists.reverse(path);
}
path.add(current);
current = current.getContainingDeclaration();
}
}
public static boolean isFunctionLiteral(@NotNull FunctionDescriptor descriptor) {
return descriptor instanceof AnonymousFunctionDescriptor;
}
@@ -259,7 +238,7 @@ public class DescriptorUtils {
return isKindOf(descriptor, ClassKind.CLASS_OBJECT);
}
public static boolean isAnonymous(@Nullable ClassifierDescriptor descriptor) {
public static boolean isAnonymous(@NotNull ClassifierDescriptor descriptor) {
return isKindOf(descriptor, ClassKind.OBJECT) && descriptor.getName().isSpecial();
}
@@ -275,20 +254,16 @@ public class DescriptorUtils {
return isKindOf(descriptor, ClassKind.ANNOTATION_CLASS);
}
public static boolean isTrait(@NotNull DeclarationDescriptor descriptor) {
return isKindOf(descriptor, ClassKind.TRAIT);
}
public static boolean isClass(@NotNull DeclarationDescriptor descriptor) {
return isKindOf(descriptor, ClassKind.CLASS);
}
public static boolean isKindOf(@NotNull JetType jetType, @NotNull ClassKind classKind) {
ClassifierDescriptor descriptor = jetType.getConstructor().getDeclarationDescriptor();
return isKindOf(descriptor, classKind);
}
public static boolean isKindOf(@Nullable DeclarationDescriptor descriptor, @NotNull ClassKind classKind) {
if (descriptor instanceof ClassDescriptor) {
return ((ClassDescriptor) descriptor).getKind() == classKind;
}
return false;
return descriptor instanceof ClassDescriptor && ((ClassDescriptor) descriptor).getKind() == classKind;
}
@NotNull
@@ -311,11 +286,10 @@ public class DescriptorUtils {
@NotNull
public static ClassDescriptor getClassDescriptorForTypeConstructor(@NotNull TypeConstructor typeConstructor) {
DeclarationDescriptor superClassDescriptor =
typeConstructor.getDeclarationDescriptor();
assert superClassDescriptor instanceof ClassDescriptor
: "Superclass descriptor of a type should be of type ClassDescriptor";
return (ClassDescriptor)superClassDescriptor;
ClassifierDescriptor descriptor = typeConstructor.getDeclarationDescriptor();
assert descriptor instanceof ClassDescriptor
: "Classifier descriptor of a type should be of type ClassDescriptor: " + typeConstructor;
return (ClassDescriptor) descriptor;
}
public static boolean isAny(@NotNull DeclarationDescriptor superClassDescriptor) {
@@ -338,24 +312,6 @@ public class DescriptorUtils {
return false;
}
public static boolean isIteratorWithoutRemoveImpl(@NotNull ClassDescriptor classDescriptor) {
ClassDescriptor iteratorOfT = KotlinBuiltIns.getInstance().getIterator();
JetType iteratorOfAny = TypeUtils.substituteParameters(iteratorOfT, Collections.singletonList(KotlinBuiltIns.getInstance().getAnyType()));
boolean isIterator = JetTypeChecker.INSTANCE.isSubtypeOf(classDescriptor.getDefaultType(), iteratorOfAny);
boolean hasRemove = hasMethod(classDescriptor, Name.identifier("remove"));
return isIterator && !hasRemove;
}
private static boolean hasMethod(ClassDescriptor classDescriptor, Name name) {
Collection<FunctionDescriptor> removeFunctions = classDescriptor.getDefaultType().getMemberScope().getFunctions(name);
for (FunctionDescriptor function : removeFunctions) {
if (function.getValueParameters().isEmpty() && function.getTypeParameters().isEmpty()) {
return true;
}
}
return false;
}
@NotNull
public static Name getClassObjectName(@NotNull Name className) {
return Name.special("<class-object-for-" + className.asString() + ">");
@@ -438,35 +394,10 @@ public class DescriptorUtils {
return receiverParameterDescriptor.getType();
}
@NotNull
public static ReceiverValue safeGetValue(@Nullable ReceiverParameterDescriptor receiverParameterDescriptor) {
if (receiverParameterDescriptor == null) {
return ReceiverValue.NO_RECEIVER;
}
return receiverParameterDescriptor.getValue();
}
public static boolean isExternallyAccessible(PropertyDescriptor propertyDescriptor) {
return propertyDescriptor.getVisibility() != Visibilities.PRIVATE || isClassObject(propertyDescriptor.getContainingDeclaration())
|| isTopLevelDeclaration(propertyDescriptor);
}
@NotNull
public static JetType getVarargParameterType(@NotNull JetType elementType) {
return getVarargParameterType(elementType, Variance.INVARIANT);
}
@NotNull
public static JetType getVarargParameterType(@NotNull JetType elementType, @NotNull Variance projectionKind) {
KotlinBuiltIns builtIns = KotlinBuiltIns.getInstance();
JetType primitiveArrayType = builtIns.getPrimitiveArrayJetTypeByPrimitiveJetType(elementType);
if (primitiveArrayType != null) {
return primitiveArrayType;
}
else {
return builtIns.getArrayType(projectionKind, elementType);
}
JetType primitiveArrayType = KotlinBuiltIns.getInstance().getPrimitiveArrayJetTypeByPrimitiveJetType(elementType);
return primitiveArrayType != null ? primitiveArrayType : KotlinBuiltIns.getInstance().getArrayType(Variance.INVARIANT, elementType);
}
@NotNull
@@ -536,24 +467,6 @@ public class DescriptorUtils {
return allSuperclasses;
}
@NotNull
public static PropertyDescriptor getPropertyDescriptor(@NotNull JetProperty property, @NotNull BindingContext bindingContext) {
VariableDescriptor descriptor = bindingContext.get(BindingContext.VARIABLE, property);
if (!(descriptor instanceof PropertyDescriptor)) {
throw new UnsupportedOperationException("expect a property to have a property descriptor");
}
return (PropertyDescriptor) descriptor;
}
@NotNull
public static PropertyDescriptor getPropertyDescriptor(@NotNull JetParameter constructorParameter, @NotNull BindingContext bindingContext) {
assert constructorParameter.getValOrVarNode() != null;
PropertyDescriptor descriptor = bindingContext.get(BindingContext.PRIMARY_CONSTRUCTOR_PARAMETER, constructorParameter);
assert descriptor != null;
return descriptor;
}
/**
* @return true iff {@code descriptor}'s first non-class container is a namespace
*/
@@ -384,8 +384,8 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
}
}
if (result != null) {
if (DescriptorUtils.isKindOf(thisType, ClassKind.TRAIT)) {
if (DescriptorUtils.isKindOf(result, ClassKind.CLASS)) {
if (DescriptorUtils.isTrait(thisType.getConstructor().getDeclarationDescriptor())) {
if (DescriptorUtils.isClass(result.getConstructor().getDeclarationDescriptor())) {
context.trace.report(SUPERCLASS_NOT_ACCESSIBLE_FROM_TRAIT.on(expression));
}
}
@@ -542,7 +542,7 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor {
resultType = ErrorUtils.createErrorType(RETURN_NOT_ALLOWED_MESSAGE);
}
if (containingFunctionDescriptor != null) {
expectedType = DescriptorUtils.getFunctionExpectedReturnType(containingFunctionDescriptor, (JetElement) containingFunction);
expectedType = getFunctionExpectedReturnType(containingFunctionDescriptor, (JetElement) containingFunction);
}
}
else {
@@ -554,7 +554,7 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor {
else if (labelTargetElement != null) {
SimpleFunctionDescriptor functionDescriptor = context.trace.get(FUNCTION, labelTargetElement);
if (functionDescriptor != null) {
expectedType = DescriptorUtils.getFunctionExpectedReturnType(functionDescriptor, labelTargetElement);
expectedType = getFunctionExpectedReturnType(functionDescriptor, labelTargetElement);
if (functionDescriptor != containingFunctionDescriptor) {
// Qualified, non-local
context.trace.report(RETURN_NOT_ALLOWED.on(expression));
@@ -593,4 +593,21 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor {
context.labelResolver.resolveLabel(expression, context);
return DataFlowUtils.checkType(KotlinBuiltIns.getInstance().getNothingType(), expression, context, context.dataFlowInfo);
}
@NotNull
private static JetType getFunctionExpectedReturnType(@NotNull FunctionDescriptor descriptor, @NotNull JetElement function) {
JetType expectedType;
if (function instanceof JetFunction) {
if (((JetFunction) function).getReturnTypeRef() != null || ((JetFunction) function).hasBlockBody()) {
expectedType = descriptor.getReturnType();
}
else {
expectedType = TypeUtils.NO_EXPECTED_TYPE;
}
}
else {
expectedType = descriptor.getReturnType();
}
return expectedType != null ? expectedType : TypeUtils.NO_EXPECTED_TYPE;
}
}