Exemplo n.º 1
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;
 }
Exemplo n.º 2
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());
  }
  @Override
  public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
    if (!super.isAvailable(project, editor, file) || !(file instanceof JetFile)) {
      return false;
    }

    // When running single test 'isAvailable()' is invoked multiple times, so we need to clear
    // lists.
    overriddenNonOverridableMembers.clear();
    containingDeclarationsNames.clear();

    DeclarationDescriptor descriptor = ResolvePackage.resolveToDescriptor(element);
    if (!(descriptor instanceof CallableMemberDescriptor)) return false;

    for (CallableMemberDescriptor overriddenDescriptor :
        getAllDeclaredNonOverridableOverriddenDescriptors((CallableMemberDescriptor) descriptor)) {
      assert overriddenDescriptor.getKind() == DECLARATION : "Can only be applied to declarations.";
      PsiElement overriddenMember = descriptorToDeclaration(overriddenDescriptor);
      if (overriddenMember == null
          || !QuickFixUtil.canModifyElement(overriddenMember)
          || !(overriddenMember instanceof JetCallableDeclaration)) {
        return false;
      }
      String containingDeclarationName =
          overriddenDescriptor.getContainingDeclaration().getName().asString();
      overriddenNonOverridableMembers.add((JetCallableDeclaration) overriddenMember);
      containingDeclarationsNames.add(containingDeclarationName);
    }
    return overriddenNonOverridableMembers.size() > 0;
  }
Exemplo n.º 4
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;
 }
Exemplo n.º 5
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));
  }
Exemplo n.º 6
0
  @Override
  protected void generateBody() {
    List<KtObjectDeclaration> companions = new ArrayList<KtObjectDeclaration>();
    if (kind != OwnerKind.DEFAULT_IMPLS) {
      // generate nested classes first and only then generate class body. It necessary to access to
      // nested CodegenContexts
      for (KtDeclaration declaration : myClass.getDeclarations()) {
        if (shouldProcessFirst(declaration)) {
          // Generate companions after class body generation (need to record all synthetic
          // accessors)
          if (declaration instanceof KtObjectDeclaration
              && ((KtObjectDeclaration) declaration).isCompanion()) {
            companions.add((KtObjectDeclaration) declaration);
            CodegenUtilKt.populateCompanionBackingFieldNamesToOuterContextIfNeeded(
                (KtObjectDeclaration) declaration, context, state);
          } else {
            generateDeclaration(declaration);
          }
        }
      }
    }

    for (KtDeclaration declaration : myClass.getDeclarations()) {
      if (!shouldProcessFirst(declaration)) {
        generateDeclaration(declaration);
      }
    }

    generatePrimaryConstructorProperties();
    generateConstructors();
    generateDefaultImplsIfNeeded();

    for (KtObjectDeclaration companion : companions) {
      generateDeclaration(companion);
    }

    if (!DescriptorUtils.isInterface(descriptor)) {
      for (DeclarationDescriptor memberDescriptor :
          DescriptorUtils.getAllDescriptors(descriptor.getDefaultType().getMemberScope())) {
        if (memberDescriptor instanceof CallableMemberDescriptor) {
          CallableMemberDescriptor member = (CallableMemberDescriptor) memberDescriptor;
          if (!member.getKind().isReal() && ImplKt.findInterfaceImplementation(member) == null) {
            if (member instanceof FunctionDescriptor) {
              functionCodegen.generateBridges((FunctionDescriptor) member);
            } else if (member instanceof PropertyDescriptor) {
              PropertyGetterDescriptor getter = ((PropertyDescriptor) member).getGetter();
              if (getter != null) {
                functionCodegen.generateBridges(getter);
              }
              PropertySetterDescriptor setter = ((PropertyDescriptor) member).getSetter();
              if (setter != null) {
                functionCodegen.generateBridges(setter);
              }
            }
          }
        }
      }
    }
  }
Exemplo n.º 7
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;
 }
Exemplo n.º 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));
      }
    }
  }
Exemplo n.º 9
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);
    }
  }
Exemplo n.º 10
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);
     }
   }
 }
Exemplo n.º 11
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;
  }
Exemplo n.º 12
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));
   }
 }
Exemplo n.º 13
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;
 }
Exemplo n.º 14
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);
  }
Exemplo n.º 15
0
 @NotNull
 private static Collection<CallableMemberDescriptor>
     getAllDeclaredNonOverridableOverriddenDescriptors(
         @NotNull CallableMemberDescriptor callableMemberDescriptor) {
   Set<CallableMemberDescriptor> result = Sets.newHashSet();
   Collection<CallableMemberDescriptor> nonOverridableOverriddenDescriptors =
       retainNonOverridableMembers(callableMemberDescriptor.getOverriddenDescriptors());
   for (CallableMemberDescriptor overriddenDescriptor : nonOverridableOverriddenDescriptors) {
     CallableMemberDescriptor.Kind kind = overriddenDescriptor.getKind();
     if (kind == DECLARATION) {
       result.add(overriddenDescriptor);
     } else if (kind == FAKE_OVERRIDE || kind == DELEGATION) {
       result.addAll(getAllDeclaredNonOverridableOverriddenDescriptors(overriddenDescriptor));
     } else if (kind == SYNTHESIZED) {
       // do nothing, final synthesized members can't be made open
     } else {
       throw new UnsupportedOperationException("Unexpected callable kind " + kind);
     }
   }
   return result;
 }
Exemplo n.º 16
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);
    }
  }
Exemplo n.º 17
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();
 }
Exemplo n.º 18
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);
  }
Exemplo n.º 19
0
 public static boolean isOverride(@NotNull CallableMemberDescriptor descriptor) {
   return !descriptor.getOverriddenDescriptors().isEmpty();
 }