예제 #1
0
  private static boolean isMoreSpecific(
      @NotNull CallableMemberDescriptor a, @NotNull CallableMemberDescriptor b) {
    if (a instanceof SimpleFunctionDescriptor) {
      assert b instanceof SimpleFunctionDescriptor : "b is " + b.getClass();

      KotlinType aReturnType = a.getReturnType();
      assert aReturnType != null;
      KotlinType bReturnType = b.getReturnType();
      assert bReturnType != null;

      return KotlinTypeChecker.DEFAULT.isSubtypeOf(aReturnType, bReturnType);
    }
    if (a instanceof PropertyDescriptor) {
      assert b instanceof PropertyDescriptor : "b is " + b.getClass();

      if (((PropertyDescriptor) a).isVar() || ((PropertyDescriptor) b).isVar()) {
        return ((PropertyDescriptor) a).isVar();
      }

      // both vals
      return KotlinTypeChecker.DEFAULT.isSubtypeOf(
          ((PropertyDescriptor) a).getType(), ((PropertyDescriptor) b).getType());
    }
    throw new IllegalArgumentException("Unexpected callable: " + a.getClass());
  }
예제 #2
0
 @Nullable
 public static Visibility findMaxVisibility(
     @NotNull Collection<? extends CallableMemberDescriptor> descriptors) {
   if (descriptors.isEmpty()) {
     return Visibilities.DEFAULT_VISIBILITY;
   }
   Visibility maxVisibility = null;
   for (CallableMemberDescriptor descriptor : descriptors) {
     Visibility visibility = descriptor.getVisibility();
     assert visibility != Visibilities.INHERITED
         : "Visibility should have been computed for " + descriptor;
     if (maxVisibility == null) {
       maxVisibility = visibility;
       continue;
     }
     Integer compareResult = Visibilities.compare(visibility, maxVisibility);
     if (compareResult == null) {
       maxVisibility = null;
     } else if (compareResult > 0) {
       maxVisibility = visibility;
     }
   }
   if (maxVisibility == null) {
     return null;
   }
   for (CallableMemberDescriptor descriptor : descriptors) {
     Integer compareResult = Visibilities.compare(maxVisibility, descriptor.getVisibility());
     if (compareResult == null || compareResult < 0) {
       return null;
     }
   }
   return maxVisibility;
 }
예제 #3
0
 @Nullable
 private static Visibility findMaxVisibility(
     @NotNull Collection<? extends CallableMemberDescriptor> descriptors) {
   if (descriptors.isEmpty()) {
     return Visibilities.INTERNAL;
   }
   Visibility maxVisibility = null;
   for (CallableMemberDescriptor descriptor : descriptors) {
     Visibility visibility = descriptor.getVisibility();
     assert visibility != Visibilities.INHERITED
         : "Visibility should have been computed for " + descriptor;
     if (maxVisibility == null) {
       maxVisibility = visibility;
       continue;
     }
     Integer compareResult = Visibilities.compare(visibility, maxVisibility);
     if (compareResult == null) {
       maxVisibility = null;
     } else if (compareResult > 0) {
       maxVisibility = visibility;
     }
   }
   // TODO: IDEA seems to issue an incorrect warning here
   //noinspection ConstantConditions
   if (maxVisibility == null) {
     return null;
   }
   for (CallableMemberDescriptor descriptor : descriptors) {
     Integer compareResult = Visibilities.compare(maxVisibility, descriptor.getVisibility());
     if (compareResult == null || compareResult < 0) {
       return null;
     }
   }
   return maxVisibility;
 }
예제 #4
0
  @NotNull
  private static Modality determineModality(
      @NotNull Collection<CallableMemberDescriptor> descriptors) {
    // Optimization: avoid creating hash sets in frequent cases when modality can be computed
    // trivially
    boolean hasOpen = false;
    boolean hasAbstract = false;
    for (CallableMemberDescriptor descriptor : descriptors) {
      switch (descriptor.getModality()) {
        case FINAL:
          return Modality.FINAL;
        case SEALED:
          throw new IllegalStateException("Member cannot have SEALED modality: " + descriptor);
        case OPEN:
          hasOpen = true;
          break;
        case ABSTRACT:
          hasAbstract = true;
          break;
      }
    }

    if (hasOpen && !hasAbstract) return Modality.OPEN;
    if (!hasOpen && hasAbstract) return Modality.ABSTRACT;

    Set<CallableMemberDescriptor> allOverriddenDeclarations =
        new HashSet<CallableMemberDescriptor>();
    for (CallableMemberDescriptor descriptor : descriptors) {
      allOverriddenDeclarations.addAll(getOverriddenDeclarations(descriptor));
    }
    return getMinimalModality(filterOutOverridden(allOverriddenDeclarations));
  }
예제 #5
0
 @NotNull
 private static Modality getMinimalModality(
     @NotNull Collection<CallableMemberDescriptor> descriptors) {
   Modality modality = Modality.ABSTRACT;
   for (CallableMemberDescriptor descriptor : descriptors) {
     if (descriptor.getModality().compareTo(modality) < 0) {
       modality = descriptor.getModality();
     }
   }
   return modality;
 }
예제 #6
0
 private void renderModalityForCallable(
     @NotNull CallableMemberDescriptor callable, @NotNull StringBuilder builder) {
   if (!DescriptorUtils.isTopLevelDeclaration(callable)
       || callable.getModality() != Modality.FINAL) {
     if (overridesSomething(callable)
         && overrideRenderingPolicy == OverrideRenderingPolicy.RENDER_OVERRIDE
         && callable.getModality() == Modality.OPEN) {
       return;
     }
     renderModality(callable.getModality(), builder);
   }
 }
예제 #7
0
  public static void bindOverride(
      CallableMemberDescriptor fromCurrent, CallableMemberDescriptor fromSupertype) {
    fromCurrent.addOverriddenDescriptor(fromSupertype);

    for (ValueParameterDescriptor parameterFromCurrent : fromCurrent.getValueParameters()) {
      assert parameterFromCurrent.getIndex() < fromSupertype.getValueParameters().size()
          : "An override relation between functions implies that they have the same number of value parameters";
      ValueParameterDescriptor parameterFromSupertype =
          fromSupertype.getValueParameters().get(parameterFromCurrent.getIndex());
      parameterFromCurrent.addOverriddenDescriptor(parameterFromSupertype);
    }
  }
예제 #8
0
  private void checkOpenMembers(ClassDescriptorWithResolutionScopes classDescriptor) {
    if (classCanHaveOpenMembers(classDescriptor)) return;

    for (CallableMemberDescriptor memberDescriptor : classDescriptor.getDeclaredCallableMembers()) {
      if (memberDescriptor.getKind() != CallableMemberDescriptor.Kind.DECLARATION) continue;
      JetNamedDeclaration member =
          (JetNamedDeclaration) DescriptorToSourceUtils.descriptorToDeclaration(memberDescriptor);
      if (member != null && member.hasModifier(JetTokens.OPEN_KEYWORD)) {
        trace.report(NON_FINAL_MEMBER_IN_FINAL_CLASS.on(member));
      }
    }
  }
예제 #9
0
 private static void collectOverriddenDeclarations(
     @NotNull CallableMemberDescriptor descriptor, @NotNull Set<CallableMemberDescriptor> result) {
   if (descriptor.getKind().isReal()) {
     result.add(descriptor);
   } else {
     if (descriptor.getOverriddenDescriptors().isEmpty()) {
       throw new IllegalStateException(
           "No overridden descriptors found for (fake override) " + descriptor);
     }
     for (CallableMemberDescriptor overridden : descriptor.getOverriddenDescriptors()) {
       collectOverriddenDeclarations(overridden, result);
     }
   }
 }
예제 #10
0
  private static Collection<CallableMemberDescriptor> extractAndBindOverridesForMember(
      @NotNull CallableMemberDescriptor fromCurrent,
      @NotNull Collection<? extends CallableMemberDescriptor> descriptorsFromSuper,
      @NotNull ClassDescriptor current,
      @NotNull DescriptorSink sink) {
    Collection<CallableMemberDescriptor> bound =
        new ArrayList<CallableMemberDescriptor>(descriptorsFromSuper.size());
    for (CallableMemberDescriptor fromSupertype : descriptorsFromSuper) {
      OverrideCompatibilityInfo.Result result =
          DEFAULT.isOverridableBy(fromSupertype, fromCurrent).getResult();

      boolean isVisible =
          Visibilities.isVisible(ReceiverValue.IRRELEVANT_RECEIVER, fromSupertype, current);
      switch (result) {
        case OVERRIDABLE:
          if (isVisible) {
            fromCurrent.addOverriddenDescriptor(fromSupertype);
          }
          bound.add(fromSupertype);
          break;
        case CONFLICT:
          if (isVisible) {
            sink.conflict(fromSupertype, fromCurrent);
          }
          bound.add(fromSupertype);
          break;
        case INCOMPATIBLE:
          break;
      }
    }
    return bound;
  }
예제 #11
0
 private void checkDeclaredTypeInPublicMember(
     JetNamedDeclaration member, CallableMemberDescriptor memberDescriptor) {
   boolean hasDeferredType;
   if (member instanceof JetProperty) {
     hasDeferredType =
         ((JetProperty) member).getTypeReference() == null
             && DescriptorResolver.hasBody((JetProperty) member);
   } else {
     assert member instanceof JetFunction;
     JetFunction function = (JetFunction) member;
     hasDeferredType =
         function.getTypeReference() == null && function.hasBody() && !function.hasBlockBody();
   }
   if ((memberDescriptor.getVisibility().isPublicAPI())
       && memberDescriptor.getOverriddenDescriptors().size() == 0
       && hasDeferredType) {
     trace.report(PUBLIC_MEMBER_SHOULD_SPECIFY_TYPE.on(member));
   }
 }
예제 #12
0
 @NotNull
 @SuppressWarnings("unchecked")
 public static <D extends CallableMemberDescriptor> Set<D> getAllOverriddenDeclarations(
     @NotNull D memberDescriptor) {
   Set<D> result = new HashSet<D>();
   for (CallableMemberDescriptor overriddenDeclaration :
       memberDescriptor.getOverriddenDescriptors()) {
     CallableMemberDescriptor.Kind kind = overriddenDeclaration.getKind();
     if (kind == DECLARATION) {
       result.add((D) overriddenDeclaration);
     } else if (kind == DELEGATION || kind == FAKE_OVERRIDE || kind == SYNTHESIZED) {
       // do nothing
     } else {
       throw new AssertionError("Unexpected callable kind " + kind);
     }
     result.addAll(getAllOverriddenDeclarations((D) overriddenDeclaration));
   }
   return result;
 }
예제 #13
0
  private static void createAndBindFakeOverride(
      @NotNull Collection<CallableMemberDescriptor> overridables,
      @NotNull ClassDescriptor current,
      @NotNull DescriptorSink sink) {
    Collection<CallableMemberDescriptor> visibleOverridables =
        filterVisibleFakeOverrides(current, overridables);
    boolean allInvisible = visibleOverridables.isEmpty();
    Collection<CallableMemberDescriptor> effectiveOverridden =
        allInvisible ? overridables : visibleOverridables;

    Modality modality = getMinimalModality(effectiveOverridden);
    Visibility visibility = allInvisible ? Visibilities.INVISIBLE_FAKE : Visibilities.INHERITED;
    CallableMemberDescriptor mostSpecific = selectMostSpecificMemberFromSuper(effectiveOverridden);
    CallableMemberDescriptor fakeOverride =
        mostSpecific.copy(
            current, modality, visibility, CallableMemberDescriptor.Kind.FAKE_OVERRIDE, false);
    for (CallableMemberDescriptor descriptor : effectiveOverridden) {
      fakeOverride.addOverriddenDescriptor(descriptor);
    }
    sink.addFakeOverride(fakeOverride);
  }
예제 #14
0
  public static void resolveUnknownVisibilityForMember(
      @NotNull CallableMemberDescriptor memberDescriptor,
      @Nullable Function1<CallableMemberDescriptor, Unit> cannotInferVisibility) {
    for (CallableMemberDescriptor descriptor : memberDescriptor.getOverriddenDescriptors()) {
      if (descriptor.getVisibility() == Visibilities.INHERITED) {
        resolveUnknownVisibilityForMember(descriptor, cannotInferVisibility);
      }
    }

    if (memberDescriptor.getVisibility() != Visibilities.INHERITED) {
      return;
    }

    Visibility maxVisibility = computeVisibilityToInherit(memberDescriptor);
    Visibility visibilityToInherit;
    if (maxVisibility == null) {
      if (cannotInferVisibility != null) {
        cannotInferVisibility.invoke(memberDescriptor);
      }
      visibilityToInherit = Visibilities.PUBLIC;
    } else {
      visibilityToInherit = maxVisibility;
    }

    if (memberDescriptor instanceof PropertyDescriptorImpl) {
      ((PropertyDescriptorImpl) memberDescriptor).setVisibility(visibilityToInherit);
      for (PropertyAccessorDescriptor accessor :
          ((PropertyDescriptor) memberDescriptor).getAccessors()) {
        // If we couldn't infer visibility for property, the diagnostic is already reported, no need
        // to report it again on accessors
        resolveUnknownVisibilityForMember(
            accessor, maxVisibility == null ? null : cannotInferVisibility);
      }
    } else if (memberDescriptor instanceof FunctionDescriptorImpl) {
      ((FunctionDescriptorImpl) memberDescriptor).setVisibility(visibilityToInherit);
    } else {
      assert memberDescriptor instanceof PropertyAccessorDescriptorImpl;
      ((PropertyAccessorDescriptorImpl) memberDescriptor).setVisibility(visibilityToInherit);
    }
  }
예제 #15
0
 @Nullable
 private static Visibility computeVisibilityToInherit(
     @NotNull CallableMemberDescriptor memberDescriptor) {
   Collection<? extends CallableMemberDescriptor> overriddenDescriptors =
       memberDescriptor.getOverriddenDescriptors();
   Visibility maxVisibility = findMaxVisibility(overriddenDescriptors);
   if (maxVisibility == null) {
     return null;
   }
   if (memberDescriptor.getKind() == CallableMemberDescriptor.Kind.FAKE_OVERRIDE) {
     for (CallableMemberDescriptor overridden : overriddenDescriptors) {
       // An implementation (a non-abstract overridden member) of a fake override should have the
       // maximum possible visibility
       if (overridden.getModality() != Modality.ABSTRACT
           && !overridden.getVisibility().equals(maxVisibility)) {
         return null;
       }
     }
     return maxVisibility;
   }
   return maxVisibility.normalize();
 }
예제 #16
0
  private static void createAndBindFakeOverride(
      @NotNull Collection<CallableMemberDescriptor> overridables,
      @NotNull ClassDescriptor current,
      @NotNull OverridingStrategy strategy) {
    Collection<CallableMemberDescriptor> visibleOverridables =
        filterVisibleFakeOverrides(current, overridables);
    boolean allInvisible = visibleOverridables.isEmpty();
    Collection<CallableMemberDescriptor> effectiveOverridden =
        allInvisible ? overridables : visibleOverridables;

    Modality modality = determineModality(effectiveOverridden);
    Visibility visibility = allInvisible ? Visibilities.INVISIBLE_FAKE : Visibilities.INHERITED;

    // FIXME doesn't work as expected for flexible types: should create a refined signature.
    // Current algorithm produces bad results in presence of annotated Java signatures such as:
    //      J: foo(s: String!): String -- @NotNull String foo(String s);
    //      K: foo(s: String): String?
    //  --> 'foo(s: String!): String' as an inherited signature with most specific return type.
    // This is bad because it can be overridden by 'foo(s: String?): String', which is not
    // override-equivalent with K::foo above.
    // Should be 'foo(s: String): String'.
    CallableMemberDescriptor mostSpecific =
        selectMostSpecificMember(
            effectiveOverridden,
            new Function1<CallableMemberDescriptor, CallableDescriptor>() {
              @Override
              public CallableMemberDescriptor invoke(CallableMemberDescriptor descriptor) {
                return descriptor;
              }
            });
    CallableMemberDescriptor fakeOverride =
        mostSpecific.copy(
            current, modality, visibility, CallableMemberDescriptor.Kind.FAKE_OVERRIDE, false);
    strategy.setOverriddenDescriptors(fakeOverride, effectiveOverridden);
    assert !fakeOverride.getOverriddenDescriptors().isEmpty()
        : "Overridden descriptors should be set for " + CallableMemberDescriptor.Kind.FAKE_OVERRIDE;
    strategy.addFakeOverride(fakeOverride);
  }
예제 #17
0
 private void renderOverride(
     @NotNull CallableMemberDescriptor callableMember, @NotNull StringBuilder builder) {
   if (!modifiers.contains(Modifier.OVERRIDE)) return;
   if (overridesSomething(callableMember)) {
     if (overrideRenderingPolicy != OverrideRenderingPolicy.RENDER_OPEN) {
       builder.append("override ");
       if (verbose) {
         builder
             .append("/*")
             .append(callableMember.getOverriddenDescriptors().size())
             .append("*/ ");
       }
     }
   }
 }
예제 #18
0
 private void renderWhereSuffix(
     @NotNull CallableMemberDescriptor callable, @NotNull StringBuilder builder) {
   boolean first = true;
   for (TypeParameterDescriptor typeParameter : callable.getTypeParameters()) {
     if (typeParameter.getUpperBounds().size() > 1) {
       for (JetType upperBound : typeParameter.getUpperBounds()) {
         if (first) {
           builder.append(" ");
           builder.append(renderKeyword("where"));
           builder.append(" ");
         } else {
           builder.append(", ");
         }
         builder.append(typeParameter.getName());
         builder.append(" : ");
         builder.append(escape(renderType(upperBound)));
         first = false;
       }
     }
   }
 }
예제 #19
0
 public static boolean isOverride(@NotNull CallableMemberDescriptor descriptor) {
   return !descriptor.getOverriddenDescriptors().isEmpty();
 }
예제 #20
0
 private boolean overridesSomething(CallableMemberDescriptor callable) {
   return !callable.getOverriddenDescriptors().isEmpty();
 }
예제 #21
0
 private void renderMemberKind(CallableMemberDescriptor callableMember, StringBuilder builder) {
   if (!modifiers.contains(Modifier.MEMBER_KIND)) return;
   if (verbose && callableMember.getKind() != CallableMemberDescriptor.Kind.DECLARATION) {
     builder.append("/*").append(callableMember.getKind().name().toLowerCase()).append("*/ ");
   }
 }