Beispiel #1
0
  @NotNull
  private static Collection<CallableMemberDescriptor> extractMembersOverridableInBothWays(
      @NotNull CallableMemberDescriptor overrider,
      @NotNull Queue<CallableMemberDescriptor> extractFrom,
      @NotNull DescriptorSink sink) {
    Collection<CallableMemberDescriptor> overridable = new ArrayList<CallableMemberDescriptor>();
    overridable.add(overrider);
    for (Iterator<CallableMemberDescriptor> iterator = extractFrom.iterator();
        iterator.hasNext(); ) {
      CallableMemberDescriptor candidate = iterator.next();
      if (overrider == candidate) {
        iterator.remove();
        continue;
      }

      OverrideCompatibilityInfo.Result result1 =
          DEFAULT.isOverridableBy(candidate, overrider).getResult();
      OverrideCompatibilityInfo.Result result2 =
          DEFAULT.isOverridableBy(overrider, candidate).getResult();
      if (result1 == OVERRIDABLE && result2 == OVERRIDABLE) {
        overridable.add(candidate);
        iterator.remove();
      } else if (result1 == CONFLICT || result2 == CONFLICT) {
        sink.conflict(overrider, candidate);
        iterator.remove();
      }
    }
    return overridable;
  }
Beispiel #2
0
  @Nullable
  public static OverrideCompatibilityInfo.Result getBothWaysOverridability(
      CallableDescriptor overriderDescriptor, CallableDescriptor candidateDescriptor) {
    OverrideCompatibilityInfo.Result result1 =
        DEFAULT.isOverridableBy(candidateDescriptor, overriderDescriptor, null).getResult();
    OverrideCompatibilityInfo.Result result2 =
        DEFAULT.isOverridableBy(overriderDescriptor, candidateDescriptor, null).getResult();

    return result1 == OVERRIDABLE && result2 == OVERRIDABLE
        ? OVERRIDABLE
        : ((result1 == CONFLICT || result2 == CONFLICT) ? CONFLICT : INCOMPATIBLE);
  }
Beispiel #3
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;
  }
Beispiel #4
0
  public static boolean isMoreSpecific(
      @NotNull CallableDescriptor a, @NotNull CallableDescriptor b) {
    KotlinType aReturnType = a.getReturnType();
    KotlinType bReturnType = b.getReturnType();

    assert aReturnType != null : "Return type of " + a + " is null";
    assert bReturnType != null : "Return type of " + b + " is null";

    if (!isVisibilityMoreSpecific(a, b)) return false;

    if (a instanceof SimpleFunctionDescriptor) {
      assert b instanceof SimpleFunctionDescriptor : "b is " + b.getClass();

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

      PropertyDescriptor pa = (PropertyDescriptor) a;
      PropertyDescriptor pb = (PropertyDescriptor) b;

      if (!isAccessorMoreSpecific(pa.getSetter(), pb.getSetter())) return false;

      if (pa.isVar() && pb.isVar()) {
        return DEFAULT
            .createTypeChecker(a.getTypeParameters(), b.getTypeParameters())
            .equalTypes(aReturnType, bReturnType);
      } else {
        // both vals or var vs val: val can't be more specific then var
        return !(!pa.isVar() && pb.isVar())
            && isReturnTypeMoreSpecific(a, aReturnType, b, bReturnType);
      }
    }
    throw new IllegalArgumentException("Unexpected callable: " + a.getClass());
  }
Beispiel #5
0
 private static boolean isReturnTypeMoreSpecific(
     @NotNull CallableDescriptor a,
     @NotNull KotlinType aReturnType,
     @NotNull CallableDescriptor b,
     @NotNull KotlinType bReturnType) {
   KotlinTypeChecker typeChecker =
       DEFAULT.createTypeChecker(a.getTypeParameters(), b.getTypeParameters());
   return typeChecker.isSubtypeOf(aReturnType, bReturnType);
 }
Beispiel #6
0
  @NotNull
  public static <D extends CallableMemberDescriptor> Collection<D> resolveOverrides(
      @NotNull Name name,
      @NotNull Collection<D> membersFromSupertypes,
      @NotNull Collection<D> membersFromCurrent,
      @NotNull ClassDescriptor classDescriptor,
      @NotNull final ErrorReporter errorReporter) {
    final Set<D> result = new HashSet<D>();

    OverridingUtil.generateOverridesInFunctionGroup(
        name,
        membersFromSupertypes,
        membersFromCurrent,
        classDescriptor,
        new OverridingUtil.DescriptorSink() {
          @Override
          @SuppressWarnings("unchecked")
          public void addToScope(@NotNull CallableMemberDescriptor fakeOverride) {
            OverridingUtil.resolveUnknownVisibilityForMember(
                fakeOverride,
                new Function1<CallableMemberDescriptor, Unit>() {
                  @Override
                  public Unit invoke(@NotNull CallableMemberDescriptor descriptor) {
                    errorReporter.reportCannotInferVisibility(descriptor);
                    return Unit.INSTANCE$;
                  }
                });
            result.add((D) fakeOverride);
          }

          @Override
          public void conflict(
              @NotNull CallableMemberDescriptor fromSuper,
              @NotNull CallableMemberDescriptor fromCurrent) {
            // nop
          }
        });

    return result;
  }
Beispiel #7
0
  private static Collection<CallableMemberDescriptor> extractAndBindOverridesForMember(
      @NotNull CallableMemberDescriptor fromCurrent,
      @NotNull Collection<? extends CallableMemberDescriptor> descriptorsFromSuper,
      @NotNull ClassDescriptor current,
      @NotNull OverridingStrategy strategy) {
    Collection<CallableMemberDescriptor> bound =
        new ArrayList<CallableMemberDescriptor>(descriptorsFromSuper.size());
    Collection<CallableMemberDescriptor> overridden = SmartSet.create();
    for (CallableMemberDescriptor fromSupertype : descriptorsFromSuper) {
      OverrideCompatibilityInfo.Result result =
          DEFAULT.isOverridableBy(fromSupertype, fromCurrent, current).getResult();

      boolean isVisibleForOverride = isVisibleForOverride(fromCurrent, fromSupertype);

      switch (result) {
        case OVERRIDABLE:
          if (isVisibleForOverride) {
            overridden.add(fromSupertype);
          }
          bound.add(fromSupertype);
          break;
        case CONFLICT:
          if (isVisibleForOverride) {
            strategy.overrideConflict(fromSupertype, fromCurrent);
          }
          bound.add(fromSupertype);
          break;
        case INCOMPATIBLE:
          break;
      }
    }

    strategy.setOverriddenDescriptors(fromCurrent, overridden);

    return bound;
  }