// Copyright 2015 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef V8_DEBUG_DEBUG_SCOPES_H_
#define V8_DEBUG_DEBUG_SCOPES_H_

#include "src/debug/debug-frames.h"
#include "src/frames.h"

namespace v8 {
namespace internal {

// Iterate over the actual scopes visible from a stack frame or from a closure.
// The iteration proceeds from the innermost visible nested scope outwards.
// All scopes are backed by an actual context except the local scope,
// which is inserted "artificially" in the context chain.
class ScopeIterator {
 public:
  enum ScopeType {
    ScopeTypeGlobal = 0,
    ScopeTypeLocal,
    ScopeTypeWith,
    ScopeTypeClosure,
    ScopeTypeCatch,
    ScopeTypeBlock,
    ScopeTypeScript,
    ScopeTypeModule
  };

  static const int kScopeDetailsTypeIndex = 0;
  static const int kScopeDetailsObjectIndex = 1;
  static const int kScopeDetailsNameIndex = 2;
  static const int kScopeDetailsStartPositionIndex = 3;
  static const int kScopeDetailsEndPositionIndex = 4;
  static const int kScopeDetailsFunctionIndex = 5;
  static const int kScopeDetailsSize = 6;

  enum Option { DEFAULT, IGNORE_NESTED_SCOPES, COLLECT_NON_LOCALS };

  ScopeIterator(Isolate* isolate, FrameInspector* frame_inspector,
                Option options = DEFAULT);

  ScopeIterator(Isolate* isolate, Handle<JSFunction> function);

  MUST_USE_RESULT MaybeHandle<JSObject> MaterializeScopeDetails();

  // More scopes?
  bool Done() {
    DCHECK(!failed_);
    return context_.is_null();
  }

  bool Failed() { return failed_; }

  // Move to the next scope.
  void Next();

  // Return the type of the current scope.
  ScopeType Type();

  // Return the JavaScript object with the content of the current scope.
  MaybeHandle<JSObject> ScopeObject();

  bool HasContext();

  // Set variable value and return true on success.
  bool SetVariableValue(Handle<String> variable_name, Handle<Object> new_value);

  Handle<ScopeInfo> CurrentScopeInfo();

  // Return the context for this scope. For the local context there might not
  // be an actual context.
  Handle<Context> CurrentContext();

  // Populate the set with collected non-local variable names.
  Handle<StringSet> GetNonLocals();

#ifdef DEBUG
  // Debug print of the content of the current scope.
  void DebugPrint();
#endif

 private:
  struct ExtendedScopeInfo {
    ExtendedScopeInfo(Handle<ScopeInfo> info, int start, int end)
        : scope_info(info), start_position(start), end_position(end) {}
    Handle<ScopeInfo> scope_info;
    int start_position;
    int end_position;
  };

  Isolate* isolate_;
  FrameInspector* const frame_inspector_;
  Handle<Context> context_;
  List<ExtendedScopeInfo> nested_scope_chain_;
  Handle<StringSet> non_locals_;
  bool seen_script_scope_;
  bool failed_;

  inline JavaScriptFrame* GetFrame() {
    return frame_inspector_->GetArgumentsFrame();
  }

  inline Handle<JSFunction> GetFunction() {
    return Handle<JSFunction>::cast(frame_inspector_->GetFunction());
  }

  void RetrieveScopeChain(Scope* scope);

  void CollectNonLocals(Scope* scope);

  void UnwrapEvaluationContext();

  MUST_USE_RESULT MaybeHandle<JSObject> MaterializeScriptScope();
  MUST_USE_RESULT MaybeHandle<JSObject> MaterializeLocalScope();
  MUST_USE_RESULT MaybeHandle<JSObject> MaterializeModuleScope();
  Handle<JSObject> MaterializeClosure();
  Handle<JSObject> MaterializeCatchScope();
  Handle<JSObject> MaterializeBlockScope();
  Handle<JSObject> WithContextExtension();

  bool SetLocalVariableValue(Handle<String> variable_name,
                             Handle<Object> new_value);
  bool SetBlockVariableValue(Handle<String> variable_name,
                             Handle<Object> new_value);
  bool SetClosureVariableValue(Handle<String> variable_name,
                               Handle<Object> new_value);
  bool SetScriptVariableValue(Handle<String> variable_name,
                              Handle<Object> new_value);
  bool SetCatchVariableValue(Handle<String> variable_name,
                             Handle<Object> new_value);
  bool SetContextLocalValue(Handle<ScopeInfo> scope_info,
                            Handle<Context> context,
                            Handle<String> variable_name,
                            Handle<Object> new_value);

  void CopyContextLocalsToScopeObject(Handle<ScopeInfo> scope_info,
                                      Handle<Context> context,
                                      Handle<JSObject> scope_object);
  bool CopyContextExtensionToScopeObject(Handle<JSObject> extension,
                                         Handle<JSObject> scope_object,
                                         KeyCollectionType type);

  // Get the chain of nested scopes within this scope for the source statement
  // position. The scopes will be added to the list from the outermost scope to
  // the innermost scope. Only nested block, catch or with scopes are tracked
  // and will be returned, but no inner function scopes.
  void GetNestedScopeChain(Isolate* isolate, Scope* scope,
                           int statement_position);

  DISALLOW_IMPLICIT_CONSTRUCTORS(ScopeIterator);
};

}  // namespace internal
}  // namespace v8

#endif  // V8_DEBUG_DEBUG_SCOPES_H_
