package jetbrains.mps.kotlin.scopes.signed;

/*Generated by MPS */

import org.jetbrains.mps.openapi.model.SNode;
import jetbrains.mps.internal.collections.runtime.Sequence;
import jetbrains.mps.kotlin.behavior.IVisible__BehaviorDescriptor;
import jetbrains.mps.lang.smodel.generator.smodelAdapter.SNodeOperations;
import org.jetbrains.mps.openapi.language.SConcept;
import jetbrains.mps.kotlin.behavior.VisibilityModifier__BehaviorDescriptor;
import jetbrains.mps.kotlin.scopes.VisibilityAccess;
import org.jetbrains.mps.openapi.language.SInterfaceConcept;
import jetbrains.mps.smodel.adapter.structure.MetaAdapterFactory;

public class TopLevelVisibility {
  public static <T extends SNode> Iterable<T> visibleTo(Iterable<T> declarations, final SNode contextNode) {
    return Sequence.fromIterable(declarations).where((it) -> visibleTo(it, contextNode));
  }
  /**
   * Checks if the declaration is visible to the context node in a top level context.
   * 
   * Same as declaration,getVisibility().isApplicable(...) but properly handles cases where the declaration is not
   * instance of IVisible (avoid issues with null being the result and negation).
   */
  public static boolean visibleTo(SNode declaration, SNode contextNode) {
    return visibleTo(declaration, IVisible__BehaviorDescriptor.getVisibility_id2WVyZr44ojH.invoke(SNodeOperations.as(declaration, CONCEPTS.IVisible$LZ)), contextNode);
  }

  public static boolean visibleTo(SNode declaration, SConcept modifier, SNode contextNode) {
    return modifier == null || (boolean) VisibilityModifier__BehaviorDescriptor.isApplicable_id6jE_6duQ0AR.invoke(SNodeOperations.asSConcept(modifier), contextNode, declaration, VisibilityAccess.TOP_LEVEL);
  }

  private static final class CONCEPTS {
    /*package*/ static final SInterfaceConcept IVisible$LZ = MetaAdapterFactory.getInterfaceConcept(0x6b3888c1980244d8L, 0x8baff8e6c33ed689L, 0x631027d1c4c4e03fL, "jetbrains.mps.kotlin.structure.IVisible");
  }
}
