protected void checkFunction(
     JetNamedFunction function, SimpleFunctionDescriptor functionDescriptor) {
   reportErrorIfHasIllegalModifier(function);
   DeclarationDescriptor containingDescriptor = functionDescriptor.getContainingDeclaration();
   boolean hasAbstractModifier = function.hasModifier(JetTokens.ABSTRACT_KEYWORD);
   checkDeclaredTypeInPublicMember(function, functionDescriptor);
   if (containingDescriptor instanceof ClassDescriptor) {
     ClassDescriptor classDescriptor = (ClassDescriptor) containingDescriptor;
     boolean inTrait = classDescriptor.getKind() == ClassKind.INTERFACE;
     if (hasAbstractModifier && !classCanHaveAbstractMembers(classDescriptor)) {
       trace.report(
           ABSTRACT_FUNCTION_IN_NON_ABSTRACT_CLASS.on(
               function, functionDescriptor.getName().asString(), classDescriptor));
     }
     if (hasAbstractModifier && inTrait) {
       trace.report(ABSTRACT_MODIFIER_IN_TRAIT.on(function));
     }
     boolean hasBody = function.hasBody();
     if (hasBody && hasAbstractModifier) {
       trace.report(ABSTRACT_FUNCTION_WITH_BODY.on(function, functionDescriptor));
     }
     if (!hasBody && function.hasModifier(JetTokens.FINAL_KEYWORD) && inTrait) {
       trace.report(FINAL_FUNCTION_WITH_NO_BODY.on(function, functionDescriptor));
     }
     if (!hasBody && !hasAbstractModifier && !inTrait) {
       trace.report(NON_ABSTRACT_FUNCTION_WITH_NO_BODY.on(function, functionDescriptor));
     }
     return;
   }
   modifiersChecker.reportIllegalModalityModifiers(function);
   if (!function.hasBody() && !hasAbstractModifier) {
     trace.report(NON_MEMBER_FUNCTION_NO_BODY.on(function, functionDescriptor));
   }
 }
  private void checkPropertyAbstractness(
      @NotNull JetProperty property,
      @NotNull PropertyDescriptor propertyDescriptor,
      @NotNull ClassDescriptor classDescriptor) {
    JetPropertyAccessor getter = property.getGetter();
    JetPropertyAccessor setter = property.getSetter();
    JetModifierList modifierList = property.getModifierList();
    ASTNode abstractNode =
        modifierList != null ? modifierList.getModifierNode(JetTokens.ABSTRACT_KEYWORD) : null;

    if (abstractNode != null) { // has abstract modifier
      if (!classCanHaveAbstractMembers(classDescriptor)) {
        String name = property.getName();
        trace.report(
            ABSTRACT_PROPERTY_IN_NON_ABSTRACT_CLASS.on(
                property, name != null ? name : "", classDescriptor));
        return;
      }
      if (classDescriptor.getKind() == ClassKind.INTERFACE) {
        trace.report(ABSTRACT_MODIFIER_IN_TRAIT.on(property));
      }
    }

    if (propertyDescriptor.getModality() == Modality.ABSTRACT) {
      JetExpression initializer = property.getInitializer();
      if (initializer != null) {
        trace.report(ABSTRACT_PROPERTY_WITH_INITIALIZER.on(initializer));
      }
      JetPropertyDelegate delegate = property.getDelegate();
      if (delegate != null) {
        trace.report(ABSTRACT_DELEGATED_PROPERTY.on(delegate));
      }
      if (getter != null && getter.hasBody()) {
        trace.report(ABSTRACT_PROPERTY_WITH_GETTER.on(getter));
      }
      if (setter != null && setter.hasBody()) {
        trace.report(ABSTRACT_PROPERTY_WITH_SETTER.on(setter));
      }
    }
  }