//===-- Variable.cpp ------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "lldb/Symbol/Variable.h"

#include "lldb/Core/Debugger.h"
#include "lldb/Core/Module.h"
#include "lldb/Symbol/Block.h"
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/CompilerDecl.h"
#include "lldb/Symbol/CompilerDeclContext.h"
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/SymbolContext.h"
#include "lldb/Symbol/SymbolFile.h"
#include "lldb/Symbol/Type.h"
#include "lldb/Symbol/TypeSystem.h"
#include "lldb/Symbol/VariableList.h"
#include "lldb/Target/ABI.h"
#include "lldb/Target/Language.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/StackFrame.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
#include "lldb/Utility/LLDBLog.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/RegularExpression.h"
#include "lldb/Utility/Stream.h"
#include "lldb/ValueObject/ValueObject.h"
#include "lldb/ValueObject/ValueObjectVariable.h"

#include "llvm/ADT/Twine.h"

using namespace lldb;
using namespace lldb_private;

Variable::Variable(lldb::user_id_t uid, const char *name, const char *mangled,
                   const lldb::SymbolFileTypeSP &symfile_type_sp,
                   ValueType scope, SymbolContextScope *context,
                   const RangeList &scope_range, Declaration *decl_ptr,
                   const DWARFExpressionList &location_list, bool external,
                   bool artificial, bool location_is_constant_data,
                   bool static_member, std::optional<uint64_t> tag_offset)
    : UserID(uid), m_name(name), m_mangled(ConstString(mangled)),
      m_symfile_type_sp(symfile_type_sp), m_scope(scope),
      m_owner_scope(context), m_scope_range(scope_range),
      m_declaration(decl_ptr), m_location_list(location_list),
      m_external(external), m_artificial(artificial),
      m_loc_is_const_data(location_is_constant_data),
      m_static_member(static_member), m_tag_offset(tag_offset) {
#ifndef NDEBUG
  if (TestingProperties::GetGlobalTestingProperties()
          .GetInjectVarLocListError())
    m_location_list.Clear();
#endif
}

Variable::~Variable() = default;

lldb::LanguageType Variable::GetLanguage() const {
  lldb::LanguageType lang = m_mangled.GuessLanguage();
  if (lang != lldb::eLanguageTypeUnknown)
    return lang;

  if (auto *func = m_owner_scope->CalculateSymbolContextFunction()) {
    if ((lang = func->GetLanguage()) != lldb::eLanguageTypeUnknown)
      return lang;
  } else if (auto *comp_unit =
                 m_owner_scope->CalculateSymbolContextCompileUnit()) {
    if ((lang = comp_unit->GetLanguage()) != lldb::eLanguageTypeUnknown)
      return lang;
  }

  return lldb::eLanguageTypeUnknown;
}

ConstString Variable::GetName() const {
  ConstString name = m_mangled.GetName();
  if (name)
    return name;
  return m_name;
}

ConstString Variable::GetUnqualifiedName() const { return m_name; }

bool Variable::NameMatches(ConstString name) const {
  if (m_name == name)
    return true;
  SymbolContext variable_sc;
  m_owner_scope->CalculateSymbolContext(&variable_sc);

  return m_mangled.NameMatches(name);
}
bool Variable::NameMatches(const RegularExpression &regex) const {
  if (regex.Execute(m_name.AsCString(nullptr)))
    return true;
  if (m_mangled)
    return m_mangled.NameMatches(regex);
  return false;
}

Type *Variable::GetType() {
  if (m_symfile_type_sp)
    return m_symfile_type_sp->GetType();
  return nullptr;
}

void Variable::Dump(Stream *s, bool show_context) const {
  s->Printf("%p: ", static_cast<const void *>(this));
  s->Indent();
  *s << "Variable" << (const UserID &)*this;

  if (m_name)
    *s << ", name = \"" << m_name << "\"";

  if (m_symfile_type_sp) {
    Type *type = m_symfile_type_sp->GetType();
    if (type) {
      s->Format(", type = {{{0:x-16}} {1} (", type->GetID(), type);
      type->DumpTypeName(s);
      s->PutChar(')');
    }
  }

  if (m_scope != eValueTypeInvalid) {
    s->PutCString(", scope = ");
    switch (m_scope) {
    case eValueTypeVariableGlobal:
      s->PutCString(m_external ? "global" : "static");
      break;
    case eValueTypeVariableArgument:
      s->PutCString("parameter");
      break;
    case eValueTypeVariableLocal:
      s->PutCString("local");
      break;
    case eValueTypeVariableThreadLocal:
      s->PutCString("thread local");
      break;
    default:
      s->AsRawOstream() << "??? (" << m_scope << ')';
    }
  }

  if (show_context && m_owner_scope != nullptr) {
    s->PutCString(", context = ( ");
    m_owner_scope->DumpSymbolContext(s);
    s->PutCString(" )");
  }

  bool show_fullpaths = false;
  m_declaration.Dump(s, show_fullpaths);

  if (m_location_list.IsValid()) {
    s->PutCString(", location = ");
    ABISP abi;
    if (m_owner_scope) {
      ModuleSP module_sp(m_owner_scope->CalculateSymbolContextModule());
      if (module_sp)
        abi = ABI::FindPlugin(ProcessSP(), module_sp->GetArchitecture());
    }
    m_location_list.GetDescription(s, lldb::eDescriptionLevelBrief, abi.get());
  }

  if (m_external)
    s->PutCString(", external");

  if (m_artificial)
    s->PutCString(", artificial");

  s->EOL();
}

bool Variable::DumpDeclaration(Stream *s, bool show_fullpaths,
                               bool show_module) {
  bool dumped_declaration_info = false;
  if (m_owner_scope) {
    SymbolContext sc;
    m_owner_scope->CalculateSymbolContext(&sc);
    sc.block = nullptr;
    sc.line_entry.Clear();
    bool show_inlined_frames = false;
    const bool show_function_arguments = true;
    const bool show_function_name = true;

    dumped_declaration_info = sc.DumpStopContext(
        s, nullptr, Address(), show_fullpaths, show_module, show_inlined_frames,
        show_function_arguments, show_function_name);

    if (sc.function)
      s->PutChar(':');
  }
  if (m_declaration.DumpStopContext(s, false))
    dumped_declaration_info = true;
  return dumped_declaration_info;
}

CompilerDeclContext Variable::GetDeclContext() {
  Type *type = GetType();
  if (type)
    return type->GetSymbolFile()->GetDeclContextContainingUID(GetID());
  return CompilerDeclContext();
}

CompilerDecl Variable::GetDecl() {
  Type *type = GetType();
  return type ? type->GetSymbolFile()->GetDeclForUID(GetID()) : CompilerDecl();
}

void Variable::CalculateSymbolContext(SymbolContext *sc) {
  if (m_owner_scope) {
    m_owner_scope->CalculateSymbolContext(sc);
    sc->variable = this;
  } else
    sc->Clear(false);
}

bool Variable::LocationIsValidForFrame(StackFrame *frame) {
  if (frame) {
    Function *function =
        frame->GetSymbolContext(eSymbolContextFunction).function;
    if (function) {
      TargetSP target_sp(frame->CalculateTarget());

      addr_t loclist_base_load_addr =
          function->GetAddress().GetLoadAddress(target_sp.get());
      if (loclist_base_load_addr == LLDB_INVALID_ADDRESS)
        return false;
      // It is a location list. We just need to tell if the location list
      // contains the current address when converted to a load address
      return m_location_list.ContainsAddress(
          loclist_base_load_addr,
          frame->GetFrameCodeAddressForSymbolication().GetLoadAddress(
              target_sp.get()));
    }
  }
  return false;
}

bool Variable::LocationIsValidForAddress(const Address &address) {
  // Be sure to resolve the address to section offset prior to calling this
  // function.
  if (address.IsSectionOffset()) {
    // We need to check if the address is valid for both scope range and value
    // range.
    // Empty scope range means block range.
    bool valid_in_scope_range =
        GetScopeRange().IsEmpty() || GetScopeRange().FindEntryThatContains(
                                         address.GetFileAddress()) != nullptr;
    if (!valid_in_scope_range)
      return false;
    SymbolContext sc;
    CalculateSymbolContext(&sc);
    if (sc.module_sp == address.GetModule()) {
      // Is the variable is described by a single location?
      if (m_location_list.IsAlwaysValidSingleExpr()) {
        // Yes it is, the location is valid.
        return true;
      }

      if (sc.function) {
        addr_t loclist_base_file_addr =
            sc.function->GetAddress().GetFileAddress();
        if (loclist_base_file_addr == LLDB_INVALID_ADDRESS)
          return false;
        // It is a location list. We just need to tell if the location list
        // contains the current address when converted to a load address
        return m_location_list.ContainsAddress(loclist_base_file_addr,
                                               address.GetFileAddress());
      }
    }
  }
  return false;
}

bool Variable::IsInScope(StackFrame *frame) {
  switch (m_scope) {
  case eValueTypeRegister:
  case eValueTypeRegisterSet:
    return frame != nullptr;

  case eValueTypeConstResult:
  case eValueTypeVariableGlobal:
  case eValueTypeVariableStatic:
  case eValueTypeVariableThreadLocal:
    return true;

  case eValueTypeVariableArgument:
  case eValueTypeVariableLocal:
    if (frame) {
      // We don't have a location list, we just need to see if the block that
      // this variable was defined in is currently
      Block *deepest_frame_block =
          frame->GetSymbolContext(eSymbolContextBlock).block;
      Address frame_addr = frame->GetFrameCodeAddress();
      if (deepest_frame_block)
        return IsInScope(*deepest_frame_block, frame_addr);
    }
    break;

  default:
    break;
  }
  return false;
}

bool Variable::IsInScope(const Block &block, const Address &addr) {
  SymbolContext variable_sc;
  CalculateSymbolContext(&variable_sc);

  // Check for static or global variable defined at the compile unit
  // level that wasn't defined in a block
  if (variable_sc.block == nullptr)
    return true;

  // Check if the variable is valid in the current block
  if (variable_sc.block != &block && !variable_sc.block->Contains(&block))
    return false;

  // If no scope range is specified then it means that the scope is the
  // same as the scope of the enclosing lexical block.
  if (m_scope_range.IsEmpty())
    return true;

  return m_scope_range.FindEntryThatContains(addr.GetFileAddress()) != nullptr;
}

Status Variable::GetValuesForVariableExpressionPath(
    llvm::StringRef variable_expr_path, ExecutionContextScope *scope,
    GetVariableCallback callback, void *baton, VariableList &variable_list,
    ValueObjectList &valobj_list) {
  Status error;
  if (!callback || variable_expr_path.empty()) {
    error = Status::FromErrorString("unknown error");
    return error;
  }

  switch (variable_expr_path.front()) {
  case '*':
    error = Variable::GetValuesForVariableExpressionPath(
        variable_expr_path.drop_front(), scope, callback, baton, variable_list,
        valobj_list);
    if (error.Fail()) {
      error = Status::FromErrorString("unknown error");
      return error;
    }
    for (uint32_t i = 0; i < valobj_list.GetSize();) {
      Status tmp_error;
      ValueObjectSP valobj_sp(
          valobj_list.GetValueObjectAtIndex(i)->Dereference(tmp_error));
      if (tmp_error.Fail()) {
        variable_list.RemoveVariableAtIndex(i);
        valobj_list.RemoveValueObjectAtIndex(i);
      } else {
        valobj_list.SetValueObjectAtIndex(i, valobj_sp);
        ++i;
      }
    }
    return error;
  case '&': {
    error = Variable::GetValuesForVariableExpressionPath(
        variable_expr_path.drop_front(), scope, callback, baton, variable_list,
        valobj_list);
    if (error.Success()) {
      for (uint32_t i = 0; i < valobj_list.GetSize();) {
        Status tmp_error;
        ValueObjectSP valobj_sp(
            valobj_list.GetValueObjectAtIndex(i)->AddressOf(tmp_error));
        if (tmp_error.Fail()) {
          variable_list.RemoveVariableAtIndex(i);
          valobj_list.RemoveValueObjectAtIndex(i);
        } else {
          valobj_list.SetValueObjectAtIndex(i, valobj_sp);
          ++i;
        }
      }
    } else {
      error = Status::FromErrorString("unknown error");
    }
    return error;
  } break;

  default: {
    static RegularExpression g_regex(
        llvm::StringRef("^([A-Za-z_:][A-Za-z_0-9:]*)(.*)"));
    llvm::SmallVector<llvm::StringRef, 2> matches;
    variable_list.Clear();
    if (!g_regex.Execute(variable_expr_path, &matches)) {
      error = Status::FromErrorStringWithFormatv(
          "unable to extract a variable name from '{0}'", variable_expr_path);
      return error;
    }
    std::string variable_name = matches[1].str();
    if (!callback(baton, variable_name.c_str(), variable_list)) {
      error = Status::FromErrorString("unknown error");
      return error;
    }
    uint32_t i = 0;
    while (i < variable_list.GetSize()) {
      VariableSP var_sp(variable_list.GetVariableAtIndex(i));
      ValueObjectSP valobj_sp;
      if (!var_sp) {
        variable_list.RemoveVariableAtIndex(i);
        continue;
      }
      ValueObjectSP variable_valobj_sp(
          ValueObjectVariable::Create(scope, var_sp));
      if (!variable_valobj_sp) {
        variable_list.RemoveVariableAtIndex(i);
        continue;
      }

      llvm::StringRef variable_sub_expr_path =
          variable_expr_path.drop_front(variable_name.size());
      if (!variable_sub_expr_path.empty()) {
        valobj_sp = variable_valobj_sp->GetValueForExpressionPath(
            variable_sub_expr_path);
        if (!valobj_sp) {
          error = Status::FromErrorStringWithFormatv(
              "invalid expression path '{0}' for variable '{1}'",
              variable_sub_expr_path, var_sp->GetName().GetCString());
          variable_list.RemoveVariableAtIndex(i);
          continue;
        }
      } else {
        // Just the name of a variable with no extras
        valobj_sp = variable_valobj_sp;
      }

      valobj_list.Append(valobj_sp);
      ++i;
    }

    if (variable_list.GetSize() > 0) {
      error.Clear();
      return error;
    }
  } break;
  }
  error = Status::FromErrorString("unknown error");
  return error;
}

bool Variable::DumpLocations(Stream *s, const Address &address) {
  SymbolContext sc;
  CalculateSymbolContext(&sc);
  ABISP abi;
  if (m_owner_scope) {
    ModuleSP module_sp(m_owner_scope->CalculateSymbolContextModule());
    if (module_sp)
      abi = ABI::FindPlugin(ProcessSP(), module_sp->GetArchitecture());
  }

  const addr_t file_addr = address.GetFileAddress();
  if (sc.function) {
    addr_t loclist_base_file_addr = sc.function->GetAddress().GetFileAddress();
    if (loclist_base_file_addr == LLDB_INVALID_ADDRESS)
      return false;
    return m_location_list.DumpLocations(s, eDescriptionLevelBrief,
                                         loclist_base_file_addr, file_addr,
                                         abi.get());
  }
  return false;
}

static void PrivateAutoComplete(
    StackFrame *frame, llvm::StringRef partial_path,
    const llvm::Twine
        &prefix_path, // Anything that has been resolved already will be in here
    const CompilerType &compiler_type, CompletionRequest &request);

/// Get the CompilerType of the current instance (this/self) for direct ivar
/// completion. Returns an invalid CompilerType if the frame is not for an
/// instance method.
static CompilerType GetInstanceType(StackFrame &frame,
                                    VariableList &variable_list) {
  SymbolContext sc =
      frame.GetSymbolContext(eSymbolContextFunction | eSymbolContextBlock);
  llvm::StringRef instance_name = sc.GetInstanceName();
  if (instance_name.empty())
    return {};
  VariableSP var_sp = variable_list.FindVariable(ConstString(instance_name));
  if (!var_sp)
    return {};
  Type *var_type = var_sp->GetType();
  if (!var_type)
    return {};
  CompilerType compiler_type = var_type->GetForwardCompilerType();
  if (compiler_type.IsPointerType())
    compiler_type = compiler_type.GetPointeeType();
  return compiler_type.GetCanonicalType();
}

static void PrivateAutoCompleteMembers(
    StackFrame *frame, const std::string &partial_member_name,
    llvm::StringRef partial_path,
    const llvm::Twine
        &prefix_path, // Anything that has been resolved already will be in here
    const CompilerType &compiler_type, CompletionRequest &request) {

  // We are in a type parsing child members
  const uint32_t num_bases = compiler_type.GetNumDirectBaseClasses();

  if (num_bases > 0) {
    for (uint32_t i = 0; i < num_bases; ++i) {
      CompilerType base_class_type =
          compiler_type.GetDirectBaseClassAtIndex(i, nullptr);

      PrivateAutoCompleteMembers(frame, partial_member_name, partial_path,
                                 prefix_path,
                                 base_class_type.GetCanonicalType(), request);
    }
  }

  const uint32_t num_vbases = compiler_type.GetNumVirtualBaseClasses();

  if (num_vbases > 0) {
    for (uint32_t i = 0; i < num_vbases; ++i) {
      CompilerType vbase_class_type =
          compiler_type.GetVirtualBaseClassAtIndex(i, nullptr);

      PrivateAutoCompleteMembers(frame, partial_member_name, partial_path,
                                 prefix_path,
                                 vbase_class_type.GetCanonicalType(), request);
    }
  }

  // We are in a type parsing child members
  const uint32_t num_fields = compiler_type.GetNumFields();

  if (num_fields > 0) {
    for (uint32_t i = 0; i < num_fields; ++i) {
      std::string member_name;

      CompilerType member_compiler_type = compiler_type.GetFieldAtIndex(
          i, member_name, nullptr, nullptr, nullptr);

      if (partial_member_name.empty()) {
        request.AddCompletion((prefix_path + member_name).str());
      } else if (llvm::StringRef(member_name)
                     .starts_with(partial_member_name)) {
        if (member_name == partial_member_name) {
          PrivateAutoComplete(
              frame, partial_path,
              prefix_path + member_name, // Anything that has been resolved
                                         // already will be in here
              member_compiler_type.GetCanonicalType(), request);
        } else if (partial_path.empty()) {
          request.AddCompletion((prefix_path + member_name).str());
        }
      }
    }
  }
}

static void PrivateAutoComplete(
    StackFrame *frame, llvm::StringRef partial_path,
    const llvm::Twine
        &prefix_path, // Anything that has been resolved already will be in here
    const CompilerType &compiler_type, CompletionRequest &request) {
  //    printf ("\nPrivateAutoComplete()\n\tprefix_path = '%s'\n\tpartial_path =
  //    '%s'\n", prefix_path.c_str(), partial_path.c_str());
  std::string remaining_partial_path;

  const lldb::TypeClass type_class = compiler_type.GetTypeClass();
  if (partial_path.empty()) {
    if (compiler_type.IsValid()) {
      switch (type_class) {
      default:
      case eTypeClassArray:
      case eTypeClassBlockPointer:
      case eTypeClassBuiltin:
      case eTypeClassComplexFloat:
      case eTypeClassComplexInteger:
      case eTypeClassEnumeration:
      case eTypeClassFunction:
      case eTypeClassMemberPointer:
      case eTypeClassReference:
      case eTypeClassTypedef:
      case eTypeClassVector: {
        request.AddCompletion(prefix_path.str());
      } break;

      case eTypeClassClass:
      case eTypeClassStruct:
      case eTypeClassUnion:
        if (prefix_path.str().back() != '.')
          request.AddCompletion((prefix_path + ".").str());
        break;

      case eTypeClassObjCObject:
      case eTypeClassObjCInterface:
        break;
      case eTypeClassObjCObjectPointer:
      case eTypeClassPointer: {
        bool omit_empty_base_classes = true;
        if (llvm::expectedToOptional(
                compiler_type.GetNumChildren(omit_empty_base_classes, nullptr))
                .value_or(0))
          request.AddCompletion((prefix_path + "->").str());
        else {
          request.AddCompletion(prefix_path.str());
        }
      } break;
      }
    } else {
      if (frame) {
        const bool get_file_globals = true;
        const bool include_synthetic_vars = true;

        VariableList *variable_list = frame->GetVariableList(
            get_file_globals, include_synthetic_vars, nullptr);

        if (variable_list) {
          for (const VariableSP &var_sp : *variable_list)
            request.AddCompletion(var_sp->GetName());

          // Offer members of this/self so that direct ivar access can be
          // completed (eg "frame variable member" for "this->member").
          CompilerType instance_type = GetInstanceType(*frame, *variable_list);
          if (instance_type.IsValid())
            PrivateAutoCompleteMembers(frame, "", "", "", instance_type,
                                       request);
        }
      }
    }
  } else {
    const char ch = partial_path[0];
    switch (ch) {
    case '*':
      if (prefix_path.str().empty()) {
        PrivateAutoComplete(frame, partial_path.substr(1), "*", compiler_type,
                            request);
      }
      break;

    case '&':
      if (prefix_path.isTriviallyEmpty()) {
        PrivateAutoComplete(frame, partial_path.substr(1), std::string("&"),
                            compiler_type, request);
      }
      break;

    case '-':
      if (partial_path.size() > 1 && partial_path[1] == '>' &&
          !prefix_path.str().empty()) {
        switch (type_class) {
        case lldb::eTypeClassPointer: {
          CompilerType pointee_type(compiler_type.GetPointeeType());
          if (partial_path.size() > 2 && partial_path[2]) {
            // If there is more after the "->", then search deeper
            PrivateAutoComplete(frame, partial_path.substr(2),
                                prefix_path + "->",
                                pointee_type.GetCanonicalType(), request);
          } else {
            // Nothing after the "->", so list all members
            PrivateAutoCompleteMembers(
                frame, std::string(), std::string(), prefix_path + "->",
                pointee_type.GetCanonicalType(), request);
          }
        } break;
        default:
          break;
        }
      }
      break;

    case '.':
      if (compiler_type.IsValid()) {
        switch (type_class) {
        case lldb::eTypeClassUnion:
        case lldb::eTypeClassStruct:
        case lldb::eTypeClassClass:
          if (partial_path.size() > 1 && partial_path[1]) {
            // If there is more after the ".", then search deeper
            PrivateAutoComplete(frame, partial_path.substr(1),
                                prefix_path + ".", compiler_type, request);

          } else {
            // Nothing after the ".", so list all members
            PrivateAutoCompleteMembers(frame, std::string(), partial_path,
                                       prefix_path + ".", compiler_type,
                                       request);
          }
          break;
        default:
          break;
        }
      }
      break;
    default:
      if (isalpha(ch) || ch == '_' || ch == '$') {
        const size_t partial_path_len = partial_path.size();
        size_t pos = 1;
        while (pos < partial_path_len) {
          const char curr_ch = partial_path[pos];
          if (isalnum(curr_ch) || curr_ch == '_' || curr_ch == '$') {
            ++pos;
            continue;
          }
          break;
        }

        std::string token(std::string(partial_path), 0, pos);
        remaining_partial_path = std::string(partial_path.substr(pos));

        if (compiler_type.IsValid()) {
          PrivateAutoCompleteMembers(frame, token, remaining_partial_path,
                                     prefix_path, compiler_type, request);
        } else if (frame) {
          // We haven't found our variable yet
          const bool get_file_globals = true;
          const bool include_synthetic_vars = true;

          VariableList *variable_list = frame->GetVariableList(
              get_file_globals, include_synthetic_vars, nullptr);

          if (!variable_list)
            break;

          for (VariableSP var_sp : *variable_list) {

            if (!var_sp)
              continue;

            llvm::StringRef variable_name = var_sp->GetName().GetStringRef();
            if (variable_name.starts_with(token)) {
              if (variable_name == token) {
                Type *variable_type = var_sp->GetType();
                if (variable_type) {
                  CompilerType variable_compiler_type(
                      variable_type->GetForwardCompilerType());
                  PrivateAutoComplete(
                      frame, remaining_partial_path,
                      prefix_path + token, // Anything that has been resolved
                                           // already will be in here
                      variable_compiler_type.GetCanonicalType(), request);
                } else {
                  request.AddCompletion((prefix_path + variable_name).str());
                }
              } else if (remaining_partial_path.empty()) {
                request.AddCompletion((prefix_path + variable_name).str());
              }
            }
          }

          // Try also completing the token as a member of this/self (direct ivar
          // access).
          CompilerType instance_type = GetInstanceType(*frame, *variable_list);
          if (instance_type.IsValid())
            PrivateAutoCompleteMembers(frame, token, remaining_partial_path,
                                       prefix_path, instance_type, request);
        }
      }
      break;
    }
  }
}

void Variable::AutoComplete(const ExecutionContext &exe_ctx,
                            CompletionRequest &request) {
  CompilerType compiler_type;

  PrivateAutoComplete(exe_ctx.GetFramePtr(), request.GetCursorArgumentPrefix(),
                      "", compiler_type, request);
}
