//===--- Scope.h - Scope Abstraction ----------------------------*- C++ -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
// This file defines the Sema interface which implement hooks invoked by the 
// parser to build the AST.
//
//===----------------------------------------------------------------------===//

#ifndef SWIFT_SEMA_SCOPE_H
#define SWIFT_SEMA_SCOPE_H

#include "swift/AST/Identifier.h"
#include "swift/Basic/TreeScopedHashTable.h"
#include "llvm/ADT/SmallVector.h"

namespace swift {
  class ValueDecl;
  class Parser;
  class Scope;
  class SavedScope;

/// ScopeInfo - A single instance of this class is maintained by the Parser to
/// track the current scope.
class ScopeInfo {
  friend class Scope;
public:
  using ValueScopeEntry = std::pair<unsigned, ValueDecl *>;

  using ScopedHTTy = TreeScopedHashTable<DeclName, ValueScopeEntry>;
  using ScopedHTScopeTy = ScopedHTTy::ScopeTy;
  using ScopedHTDetachedScopeTy = ScopedHTTy::DetachedScopeTy;

private:
  ScopedHTTy HT;

  Scope *CurScope = nullptr;
  unsigned ResolvableDepth = 0;

public:
  ValueDecl *lookupValueName(DeclName Name);

  Scope *getCurrentScope() const { return CurScope; }

  /// addToScope - Register the specified decl as being in the current lexical
  /// scope.
  void addToScope(ValueDecl *D, Parser &TheParser,
                  bool diagnoseRedefinitions = true);

  bool isInactiveConfigBlock() const;
  
  SavedScope saveCurrentScope();

  LLVM_ATTRIBUTE_DEPRECATED(void dump() const LLVM_ATTRIBUTE_USED,
                            "Only for use in the debugger");
};

enum class ScopeKind {
  Extension,
  FunctionBody,
  Generics,
  EnumBody,
  StructBody,
  ClassBody,
  ProtocolBody,
  InheritanceClause,

  Brace,
  TopLevel,
  ForeachVars,
  CaseVars,
  CatchVars,
  WhileVars,
  IfVars,

  ClosureParams,
};

/// An opaque object that owns the scope frame.  The scope frame can be
/// re-entered later.
class SavedScope {
  friend class Scope;

  ScopeInfo::ScopedHTDetachedScopeTy HTDetachedScope;
  unsigned Depth;
  ScopeKind Kind;
  bool IsInactiveConfigBlock;

  SavedScope() = delete;
  SavedScope(const SavedScope &) = delete;
  void operator=(const SavedScope &) = delete;

public:
  SavedScope(SavedScope &&Other) = default;
  SavedScope &operator=(SavedScope &&) = default;
  ~SavedScope() = default;

  SavedScope(ScopeInfo::ScopedHTDetachedScopeTy &&HTDetachedScope,
             unsigned Depth, ScopeKind Kind, bool isInactiveConfigBlock)
    : HTDetachedScope(std::move(HTDetachedScope)), Depth(Depth), Kind(Kind),
      IsInactiveConfigBlock(isInactiveConfigBlock) {}
};

/// Scope - This class represents lexical scopes.  These objects are created
/// and destroyed as the parser is running, and name lookup happens relative
/// to them.
///
class Scope {
  friend class ScopeInfo;

  Scope(const Scope&) = delete;
  void operator=(const Scope&) = delete;

  ScopeInfo &SI;
  ScopeInfo::ScopedHTScopeTy HTScope;

  Scope *PrevScope;
  unsigned PrevResolvableDepth;
  unsigned Depth;
  ScopeKind Kind;
  bool IsInactiveConfigBlock;

  /// Save this scope so that it can be re-entered later.  Transfers the
  /// ownership of the scope frame to returned object.
  SavedScope saveScope() {
    return SavedScope(HTScope.detach(), Depth, Kind, IsInactiveConfigBlock);
  }

  unsigned getDepth() const {
    return Depth;
  }

  bool isResolvable() const;

public:
  /// Create a lexical scope of the specified kind.
  Scope(Parser *P, ScopeKind SC, bool isInactiveConfigBlock = false);

  /// Re-enter the specified scope, transferring the ownership of the
  /// scope frame to the new object.
  Scope(Parser *P, SavedScope &&SS);

  ScopeKind getKind() const { return Kind; }

  ~Scope() {
    // Active config blocks delegate to the enclosing scope, so there's nothing
    // to pop off.
    assert(SI.CurScope == this && "Scope mismatch");
    SI.CurScope = PrevScope;
    SI.ResolvableDepth = PrevResolvableDepth;
  }
};

inline ValueDecl *ScopeInfo::lookupValueName(DeclName Name) {
  // FIXME: this check can go away when SIL parser parses everything in
  // a toplevel scope.
  if (!CurScope)
    return nullptr;

  assert(CurScope && "no scope");
  // If we found nothing, or we found a decl at the top-level, return nothing.
  // We ignore results at the top-level because we may have overloading that
  // will be resolved properly by name binding.
  std::pair<unsigned, ValueDecl *> Res = HT.lookup(CurScope->HTScope, Name);
  if (Res.first < ResolvableDepth)
    return 0;
  return Res.second;
}

inline bool ScopeInfo::isInactiveConfigBlock() const {
  if (!CurScope)
    return false;
  return CurScope->IsInactiveConfigBlock;
}

inline SavedScope ScopeInfo::saveCurrentScope() {
  return CurScope->saveScope();
}

} // end namespace swift

#endif
