private static JetDelegatorToSuperCall findSuperCall(
      BindingContext bindingContext, JetElement classOrObject) {
    if (!(classOrObject instanceof JetClassOrObject)) {
      return null;
    }

    if (classOrObject instanceof JetClass && ((JetClass) classOrObject).isTrait()) {
      return null;
    }
    for (JetDelegationSpecifier specifier :
        ((JetClassOrObject) classOrObject).getDelegationSpecifiers()) {
      if (specifier instanceof JetDelegatorToSuperCall) {
        JetType superType = bindingContext.get(TYPE, specifier.getTypeReference());
        assert superType != null;
        ClassDescriptor superClassDescriptor =
            (ClassDescriptor) superType.getConstructor().getDeclarationDescriptor();
        assert superClassDescriptor != null;
        if (!isInterface(superClassDescriptor)) {
          return (JetDelegatorToSuperCall) specifier;
        }
      }
    }

    return null;
  }
  public static void reportCyclicInheritanceHierarchyError(
      @NotNull BindingTrace trace,
      @NotNull ClassDescriptor classDescriptor,
      @NotNull ClassDescriptor superclass) {
    PsiElement psiElement =
        BindingContextUtils.classDescriptorToDeclaration(
            trace.getBindingContext(), classDescriptor);

    PsiElement elementToMark = null;
    if (psiElement instanceof JetClassOrObject) {
      JetClassOrObject classOrObject = (JetClassOrObject) psiElement;
      for (JetDelegationSpecifier delegationSpecifier : classOrObject.getDelegationSpecifiers()) {
        JetTypeReference typeReference = delegationSpecifier.getTypeReference();
        if (typeReference == null) continue;
        JetType supertype = trace.get(TYPE, typeReference);
        if (supertype != null && supertype.getConstructor() == superclass.getTypeConstructor()) {
          elementToMark = typeReference;
        }
      }
    }
    if (elementToMark == null && psiElement instanceof PsiNameIdentifierOwner) {
      PsiNameIdentifierOwner namedElement = (PsiNameIdentifierOwner) psiElement;
      PsiElement nameIdentifier = namedElement.getNameIdentifier();
      if (nameIdentifier != null) {
        elementToMark = nameIdentifier;
      }
    }
    if (elementToMark != null) {
      trace.report(CYCLIC_INHERITANCE_HIERARCHY.on(elementToMark));
    }
  }
示例#3
0
  private void checkTypesInClassHeader(@NotNull JetClassOrObject classOrObject) {
    for (JetDelegationSpecifier delegationSpecifier : classOrObject.getDelegationSpecifiers()) {
      checkBoundsForTypeInClassHeader(delegationSpecifier.getTypeReference());
    }

    if (!(classOrObject instanceof JetClass)) return;
    JetClass jetClass = (JetClass) classOrObject;

    for (JetTypeParameter jetTypeParameter : jetClass.getTypeParameters()) {
      checkBoundsForTypeInClassHeader(jetTypeParameter.getExtendsBound());
      checkFinalUpperBounds(jetTypeParameter.getExtendsBound());
    }

    for (JetTypeConstraint constraint : jetClass.getTypeConstraints()) {
      checkBoundsForTypeInClassHeader(constraint.getBoundTypeReference());
      checkFinalUpperBounds(constraint.getBoundTypeReference());
    }
  }
示例#4
0
  private void checkEnumEntry(
      @NotNull JetEnumEntry enumEntry, @NotNull ClassDescriptor classDescriptor) {
    DeclarationDescriptor declaration = classDescriptor.getContainingDeclaration();
    assert DescriptorUtils.isEnumClass(declaration)
        : "Enum entry should be declared in enum class: " + classDescriptor;
    ClassDescriptor enumClass = (ClassDescriptor) declaration;

    if (enumEntryUsesDeprecatedSuperConstructor(enumEntry)) {
      trace.report(
          Errors.ENUM_ENTRY_USES_DEPRECATED_SUPER_CONSTRUCTOR.on(enumEntry, classDescriptor));
    }
    String neededDelimiter = enumEntryExpectedDelimiter(enumEntry);
    if (!neededDelimiter.isEmpty()) {
      trace.report(
          Errors.ENUM_ENTRY_USES_DEPRECATED_OR_NO_DELIMITER.on(
              enumEntry, classDescriptor, neededDelimiter));
    }
    if (enumEntryAfterEnumMember(enumEntry)) {
      trace.report(Errors.ENUM_ENTRY_AFTER_ENUM_MEMBER.on(enumEntry, classDescriptor));
    }

    List<JetDelegationSpecifier> delegationSpecifiers = enumEntry.getDelegationSpecifiers();
    ConstructorDescriptor constructor = enumClass.getUnsubstitutedPrimaryConstructor();
    if ((constructor == null || !constructor.getValueParameters().isEmpty())
        && delegationSpecifiers.isEmpty()) {
      trace.report(ENUM_ENTRY_SHOULD_BE_INITIALIZED.on(enumEntry, enumClass));
    }

    for (JetDelegationSpecifier delegationSpecifier : delegationSpecifiers) {
      JetTypeReference typeReference = delegationSpecifier.getTypeReference();
      if (typeReference != null) {
        JetType type = trace.getBindingContext().get(TYPE, typeReference);
        if (type != null) {
          JetType enumType = enumClass.getDefaultType();
          if (!type.getConstructor().equals(enumType.getConstructor())) {
            trace.report(ENUM_ENTRY_ILLEGAL_TYPE.on(typeReference, enumClass));
          }
        }
      }
    }
  }