package jetbrains.mps.kotlin.scopes;

/*Generated by MPS */

import org.jetbrains.mps.openapi.model.SNode;
import jetbrains.mps.kotlin.signatures.MemberSignature;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Nullable;
import java.util.Map;
import jetbrains.mps.kotlin.api.members.SignatureAttributeKey;

/**
 * Filter for signatures that scopes in kotlin language output. All methods should be tested on the
 * 
 */
public interface SignatureFilter {
  /**
   * Returns whether the given receiver can be accepted for the resulting signature.
   * 
   * If the receiver is the implicit one from the context (eg. class of an instance function), null should be passed to
   * this method. Non-null values denote receivers that are not the natural one for the node location (eg. extension member)
   * 
   * @param type type to test against, or null if the contextual receiver is to be used
   */
  default boolean acceptReceiver(SNode type) {
    // Default: no other receiver than those in context
    return (type == null);
  }

  /**
   * Returns whether signature kind should be accepted. If true, individually created signature
   * should be passed to the other accept method for advanced validation.
   */
  boolean acceptKind(Class<? extends MemberSignature> signatureKind);

  /**
   * Returns whether the given signature should be accepted. Node associated is
   * provided but filtering should occur on signature to take various node implementation
   * into account.
   * 
   * For instance, filtering on node's concept could prevent external signatures to overload
   * resolution, and have some signature not hidden correctly after processing.
   * 
   * @param signature signature whose class is assumed to conform to acceptKind method
   */
  boolean acceptSignature(MemberSignature signature, SNode source);

  /**
   * Returns true if the attributes given to a signature are deemed valid.
   */
  @ApiStatus.Experimental
  default boolean acceptAttributes(@Nullable Map<SignatureAttributeKey<?>, Object> attributes) {
    // Attribute filtering is rare, most of the time there is not filter on this
    return true;
  }

}
