// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "src/developer/debug/zxdb/expr/expr_node.h"

#include <map>
#include <type_traits>

#include <gtest/gtest.h>

#include "src/developer/debug/shared/platform_message_loop.h"
#include "src/developer/debug/zxdb/common/err.h"
#include "src/developer/debug/zxdb/common/test_with_loop.h"
#include "src/developer/debug/zxdb/expr/eval_context.h"
#include "src/developer/debug/zxdb/expr/eval_context_impl.h"
#include "src/developer/debug/zxdb/expr/eval_test_support.h"
#include "src/developer/debug/zxdb/expr/expr_value.h"
#include "src/developer/debug/zxdb/expr/mock_eval_context.h"
#include "src/developer/debug/zxdb/expr/mock_expr_node.h"
#include "src/developer/debug/zxdb/expr/pretty_type.h"
#include "src/developer/debug/zxdb/symbols/base_type.h"
#include "src/developer/debug/zxdb/symbols/code_block.h"
#include "src/developer/debug/zxdb/symbols/collection.h"
#include "src/developer/debug/zxdb/symbols/data_member.h"
#include "src/developer/debug/zxdb/symbols/mock_symbol_data_provider.h"
#include "src/developer/debug/zxdb/symbols/modified_type.h"
#include "src/developer/debug/zxdb/symbols/symbol_test_parent_setter.h"
#include "src/developer/debug/zxdb/symbols/type_test_support.h"

namespace zxdb {

namespace {

class ExprNodeTest : public TestWithLoop {};

// A PrettyType with a getter that returns a constant value.
class MockGetterPrettyType : public PrettyType {
 public:
  static const char kGetterName[];
  static const char kMemberName[];
  static const int kGetterValue;
  static const int kMemberValue;

  MockGetterPrettyType() : PrettyType({{kGetterName, "5"}}) {}

  void Format(FormatNode* node, const FormatOptions& options,
              const fxl::RefPtr<EvalContext>& context, fit::deferred_callback cb) override {}

  EvalFunction GetMember(const std::string& member_name) const override {
    if (member_name == kMemberName) {
      return [](const fxl::RefPtr<EvalContext>&, const ExprValue& object_value, EvalCallback cb) {
        cb(ExprValue(kMemberValue));
      };
    }

    return EvalFunction();
  }
};
const char MockGetterPrettyType::kGetterName[] = "get5";
const char MockGetterPrettyType::kMemberName[] = "member";
const int MockGetterPrettyType::kGetterValue = 5;
const int MockGetterPrettyType::kMemberValue = 42;

// A PrettyType with a dereference function that returns a constant value.
class MockDerefPrettyType : public PrettyType {
 public:
  MockDerefPrettyType(ExprValue val) : PrettyType(), val_(std::move(val)) {}

  void Format(FormatNode* node, const FormatOptions& options,
              const fxl::RefPtr<EvalContext>& context, fit::deferred_callback cb) override {}
  EvalFunction GetDereferencer() const override {
    return [val = val_](const fxl::RefPtr<EvalContext>&, ExprValue, EvalCallback cb) { cb(val); };
  }

 private:
  ExprValue val_;
};

}  // namespace

TEST_F(ExprNodeTest, EvalIdentifier) {
  auto context = fxl::MakeRefCounted<MockEvalContext>();
  ExprValue foo_expected(12);
  context->AddVariable("foo", foo_expected);

  // This identifier should be found synchronously and returned.
  auto good_identifier = fxl::MakeRefCounted<IdentifierExprNode>("foo");
  bool called = false;
  ExprValue out_value;
  good_identifier->Eval(context, [&called, &out_value](ErrOrValue value) {
    called = true;
    EXPECT_FALSE(value.has_error());
    out_value = value.take_value();
  });

  // This should succeed synchronously.
  EXPECT_TRUE(called);
  EXPECT_EQ(foo_expected, out_value);

  // This identifier should be not found.
  auto bad_identifier = fxl::MakeRefCounted<IdentifierExprNode>("bar");
  called = false;
  bad_identifier->Eval(context, [&called](ErrOrValue value) {
    called = true;
    EXPECT_TRUE(value.has_error());
  });

  // It should fail synchronously.
  EXPECT_TRUE(called);
}

// This test mocks at the SymbolDataProvider level because most of the dereference logic is in the
// EvalContextImpl.
TEST_F(ExprNodeTest, DereferenceReferencePointer) {
  auto data_provider = fxl::MakeRefCounted<MockSymbolDataProvider>();
  auto context = fxl::MakeRefCounted<EvalContextImpl>(fxl::WeakPtr<const ProcessSymbols>(),
                                                      data_provider, ExprLanguage::kC);

  // Dereferencing should remove the const on the pointer but not the pointee.
  auto base_type = fxl::MakeRefCounted<BaseType>(BaseType::kBaseTypeUnsigned, 4, "uint32_t");
  auto const_base_type = fxl::MakeRefCounted<ModifiedType>(DwarfTag::kConstType, base_type);
  auto ptr_type = fxl::MakeRefCounted<ModifiedType>(DwarfTag::kPointerType, const_base_type);
  auto const_ptr_type = fxl::MakeRefCounted<ModifiedType>(DwarfTag::kConstType, ptr_type);

  // The value being pointed to.
  constexpr uint32_t kValue = 0x12345678;
  constexpr uint64_t kAddress = 0x1020;
  data_provider->AddMemory(kAddress, {0x78, 0x56, 0x34, 0x12});

  // The pointer.
  ExprValue ptr_value(const_ptr_type, {0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00});

  // Execute the dereference.
  auto deref_node =
      fxl::MakeRefCounted<DereferenceExprNode>(fxl::MakeRefCounted<MockExprNode>(true, ptr_value));
  bool called = false;
  ExprValue out_value;
  deref_node->Eval(context, [&called, &out_value](ErrOrValue value) {
    called = true;
    EXPECT_TRUE(value.ok());
    out_value = value.take_value();
  });
  loop().RunUntilNoTasks();
  EXPECT_TRUE(called);

  // The type should be the const base type.
  EXPECT_EQ(const_base_type.get(), out_value.type());

  ASSERT_EQ(4u, out_value.data().size());
  EXPECT_EQ(kValue, out_value.GetAs<uint32_t>());

  // Now go backwards and get the address of the value.
  auto addr_node =
      fxl::MakeRefCounted<AddressOfExprNode>(fxl::MakeRefCounted<MockExprNode>(true, out_value));

  called = false;
  out_value = ExprValue();
  addr_node->Eval(context, [&called, &out_value](ErrOrValue value) {
    called = true;
    EXPECT_TRUE(value.ok());
    out_value = value.take_value();
  });

  // Taking the address should always complete synchronously.
  EXPECT_TRUE(called);

  // The value should be the address.
  ASSERT_EQ(8u, out_value.data().size());
  EXPECT_EQ(kAddress, out_value.GetAs<uint64_t>());

  // The type should be a pointer modifier on the old type. The pointer modifier will be a
  // dynamically created one so won't match the original we made above, but the underlying "const
  // int" should still match.
  const ModifiedType* out_mod_type = out_value.type()->AsModifiedType();
  ASSERT_TRUE(out_mod_type);
  EXPECT_EQ(DwarfTag::kPointerType, out_mod_type->tag());
  EXPECT_EQ(const_base_type.get(), out_mod_type->modified().Get()->AsModifiedType());
  EXPECT_EQ("const uint32_t*", out_mod_type->GetFullName());
}

TEST_F(ExprNodeTest, DereferenceErrors) {
  auto data_provider = fxl::MakeRefCounted<MockSymbolDataProvider>();
  auto context = fxl::MakeRefCounted<EvalContextImpl>(fxl::WeakPtr<const ProcessSymbols>(),
                                                      data_provider, ExprLanguage::kC);

  auto base_type = MakeInt32Type();
  auto ptr_type = fxl::MakeRefCounted<ModifiedType>(DwarfTag::kPointerType, base_type);

  // Try to dereference an invalid address.
  ExprValue bad_ptr_value(ptr_type, {0, 0, 0, 0, 0, 0, 0, 0});
  auto bad_deref_node = fxl::MakeRefCounted<DereferenceExprNode>(
      fxl::MakeRefCounted<MockExprNode>(true, bad_ptr_value));
  bool called = false;
  bad_deref_node->Eval(context, [&called](ErrOrValue value) {
    called = true;
    EXPECT_TRUE(value.has_error());
    EXPECT_EQ("Invalid pointer 0x0", value.err().msg());
  });
  loop().RunUntilNoTasks();
  EXPECT_TRUE(called);

  // Try to take the address of the invalid expression above. The error should be forwarded.
  auto addr_bad_deref_node = fxl::MakeRefCounted<AddressOfExprNode>(std::move(bad_deref_node));
  called = false;
  addr_bad_deref_node->Eval(context, [&called](ErrOrValue value) {
    called = true;
    EXPECT_TRUE(value.has_error());
    EXPECT_EQ("Invalid pointer 0x0", value.err().msg());
  });
  loop().RunUntilNoTasks();
  EXPECT_TRUE(called);

  // Dereference an undefined value.
  auto undef_node = fxl::MakeRefCounted<MockExprNode>(true, Err("Undefined"));
  auto undef_deref_node = fxl::MakeRefCounted<DereferenceExprNode>(std::move(undef_node));
  called = false;
  undef_deref_node->Eval(context, [&called](ErrOrValue value) {
    called = true;
    EXPECT_TRUE(value.has_error());
    EXPECT_EQ("Undefined", value.err().msg());
  });
  loop().RunUntilNoTasks();
  EXPECT_TRUE(called);
}

// This also tests ExprNode::EvalFollowReferences() by making the index a reference type.
TEST_F(ExprNodeTest, ArrayAccess) {
  // The base address of the array (of type uint32_t*).
  auto uint32_type = fxl::MakeRefCounted<BaseType>(BaseType::kBaseTypeUnsigned, 4, "uint32_t");
  auto uint32_ptr_type = fxl::MakeRefCounted<ModifiedType>(DwarfTag::kPointerType, uint32_type);
  constexpr uint64_t kAddress = 0x12345678;
  ExprValue pointer_value(uint32_ptr_type, {0x78, 0x56, 0x34, 0x12, 0x00, 0x00, 0x00, 0x00});
  auto pointer_node = fxl::MakeRefCounted<MockExprNode>(false, pointer_value);

  // The index value (= 5) lives in memory as a 32-bit little-endian value.
  constexpr uint64_t kRefAddress = 0x5000;
  constexpr uint8_t kIndex = 5;
  auto context = fxl::MakeRefCounted<MockEvalContext>();
  context->data_provider()->AddMemory(kRefAddress, {kIndex, 0, 0, 0});

  // The index expression is a reference to the index we saved above, and the
  // reference data is the address.
  auto uint32_ref_type = fxl::MakeRefCounted<ModifiedType>(DwarfTag::kReferenceType, uint32_type);
  auto index = fxl::MakeRefCounted<MockExprNode>(
      false, ExprValue(uint32_ref_type, {0, 0x50, 0, 0, 0, 0, 0, 0}));

  // The node to evaluate the access. Note the pointer are index nodes are moved here so the source
  // reference is gone. This allows us to test that they stay in scope during an async call below.
  auto access = fxl::MakeRefCounted<ArrayAccessExprNode>(std::move(pointer_node), std::move(index));

  // We expect it to read @ kAddress[kIndex]. Insert a value there.
  constexpr uint64_t kExpectedAddr = kAddress + 4 * kIndex;
  constexpr uint32_t kExpectedValue = 0x11223344;
  context->data_provider()->AddMemory(kExpectedAddr, {0x44, 0x33, 0x22, 0x11});

  // Execute.
  bool called = false;
  ExprValue out_value;
  access->Eval(context, [&called, &out_value](ErrOrValue value) {
    called = true;
    EXPECT_FALSE(value.has_error()) << value.err().msg();
    out_value = value.take_value();
  });

  // The two parts of the expression were set as async above, so it should not have been called yet.
  EXPECT_FALSE(called);

  // Clear out references to the stuff being executed. It should not crash, the relevant data should
  // remain alive.
  context.reset();
  access.reset();

  // Should succeed asynchronously.
  loop().RunUntilNoTasks();
  EXPECT_TRUE(called);

  // Should have found our data at the right place.
  EXPECT_EQ(uint32_type.get(), out_value.type());
  EXPECT_EQ(kExpectedValue, out_value.GetAs<uint32_t>());
  EXPECT_EQ(kExpectedAddr, out_value.source().address());
}

// This is more of an integration smoke test for "." and "->". The details are tested in
// resolve_collection_unittest.cc.
TEST_F(ExprNodeTest, MemberAccess) {
  auto context = fxl::MakeRefCounted<MockEvalContext>();

  // Define a class.
  auto int32_type = MakeInt32Type();
  auto sc =
      MakeCollectionType(DwarfTag::kStructureType, "Foo", {{"a", int32_type}, {"b", int32_type}});

  // Set up a call to do "." synchronously.
  auto struct_node =
      fxl::MakeRefCounted<MockExprNode>(true, ExprValue(sc, {0x78, 0x56, 0x34, 0x12}));
  auto access_node = fxl::MakeRefCounted<MemberAccessExprNode>(
      struct_node, ExprToken(ExprTokenType::kDot, ".", 0), ParsedIdentifier("a"));

  // Do the call.
  bool called = false;
  ExprValue out_value;
  access_node->Eval(context, [&called, &out_value](ErrOrValue value) {
    called = true;
    EXPECT_FALSE(value.has_error());
    out_value = value.take_value();
  });

  // Should have run synchronously.
  EXPECT_TRUE(called);
  EXPECT_EQ(0x12345678, out_value.GetAs<int32_t>());

  // Test indirection: "foo->a".
  auto foo_ptr_type = fxl::MakeRefCounted<ModifiedType>(DwarfTag::kPointerType, sc);
  // Add memory in two chunks since the mock data provider can only respond with the addresses it's
  // given.
  constexpr uint64_t kAddress = 0x1000;
  context->data_provider()->AddMemory(kAddress, {0x44, 0x33, 0x22, 0x11});
  context->data_provider()->AddMemory(kAddress + 4, {0x88, 0x77, 0x66, 0x55});

  // Make this one evaluate the left-hand-size asynchronously. This value references kAddress
  // (little-endian).
  auto struct_ptr_node = fxl::MakeRefCounted<MockExprNode>(
      false, ExprValue(foo_ptr_type, {0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}));
  auto access_ptr_node = fxl::MakeRefCounted<MemberAccessExprNode>(
      struct_ptr_node, ExprToken(ExprTokenType::kArrow, "->", 0), ParsedIdentifier("b"));

  // Do the call.
  called = false;
  out_value = ExprValue();
  access_ptr_node->Eval(context, [&called, &out_value](ErrOrValue value) {
    called = true;
    EXPECT_TRUE(value.ok());
    out_value = value.take_value();
  });

  // Should have run asynchronously.
  EXPECT_FALSE(called);
  loop().RunUntilNoTasks();
  EXPECT_TRUE(called);
  EXPECT_EQ(sizeof(int32_t), out_value.data().size());
  EXPECT_EQ(0x55667788, out_value.GetAs<int32_t>());
}

// Tests that Rust references are autodereferenced by the . operator.
TEST_F(ExprNodeTest, RustMemberAccess) {
  auto context = fxl::MakeRefCounted<MockEvalContext>();
  auto unit = fxl::MakeRefCounted<CompileUnit>(fxl::WeakPtr<ModuleSymbols>(), DwarfLang::kRust,
                                               "module.so");

  // Define a class.
  auto int32_type = MakeInt32Type();
  auto sc =
      MakeCollectionType(DwarfTag::kStructureType, "Foo", {{"a", int32_type}, {"b", int32_type}});
  SymbolTestParentSetter sc_parent(sc, unit);

  // Define a reference type.
  auto foo_ptr_type = fxl::MakeRefCounted<ModifiedType>(DwarfTag::kPointerType, sc);
  SymbolTestParentSetter foo_ptr_type_parent(foo_ptr_type, unit);
  foo_ptr_type->set_assigned_name("&Foo");
  // Add memory in two chunks since the mock data provider can only respond with the addresses it's
  // given.
  constexpr uint64_t kAddress = 0x1000;
  context->data_provider()->AddMemory(kAddress, {0x44, 0x33, 0x22, 0x11});
  context->data_provider()->AddMemory(kAddress + 4, {0x88, 0x77, 0x66, 0x55});

  // Make this one evaluate the left-hand-size asynchronously. This value references kAddress
  // (little-endian).
  auto struct_ptr_node = fxl::MakeRefCounted<MockExprNode>(
      false, ExprValue(foo_ptr_type, {0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}));
  auto access_ptr_node = fxl::MakeRefCounted<MemberAccessExprNode>(
      struct_ptr_node, ExprToken(ExprTokenType::kDot, ".", 0), ParsedIdentifier("b"));

  // Do the call.
  auto called = false;
  auto out_value = ExprValue();
  access_ptr_node->Eval(context, [&called, &out_value](ErrOrValue value) {
    called = true;
    EXPECT_TRUE(value.ok());
    out_value = value.take_value();
  });

  // Should have run asynchronously.
  EXPECT_FALSE(called);
  loop().RunUntilNoTasks();
  EXPECT_TRUE(called);

  EXPECT_EQ(sizeof(int32_t), out_value.data().size());
  EXPECT_EQ(0x55667788, out_value.GetAs<int32_t>());
}

// Tests dereferencing via "*" and "->" with a type that has a pretty type.
TEST_F(ExprNodeTest, PrettyDereference) {
  auto context = fxl::MakeRefCounted<MockEvalContext>();

  // Make a struct to return, it has one 32-bit value.
  auto int32_type = MakeInt32Type();
  auto struct_type =
      MakeCollectionType(DwarfTag::kStructureType, "StructType", {{"a", int32_type}});
  constexpr uint8_t kAValue = 42;
  ExprValue struct_value(struct_type, {kAValue, 0, 0, 0});  // ReturnType.a = kAValue.

  // Register the PrettyType that provides a getter. It always returns struct_value.
  const char kTypeName[] = "MyType";
  IdentifierGlob glob;
  ASSERT_FALSE(glob.Init(kTypeName).has_error());
  context->pretty_type_manager().Add(ExprLanguage::kC, glob,
                                     std::make_unique<MockDerefPrettyType>(struct_value));

  // Value of MyType to pass to the evaluator. The contents of this don't matter, only the type
  // name will be matched.
  auto my_type = MakeCollectionType(DwarfTag::kStructureType, kTypeName, {});
  ExprValue my_value(my_type, {});
  auto my_node = fxl::MakeRefCounted<MockExprNode>(true, my_value);

  // Dereferencing MyType should yield the pretty type result |struct_type| above.
  auto deref_node = fxl::MakeRefCounted<DereferenceExprNode>(my_node);
  bool called = false;
  deref_node->Eval(context, [&called, struct_value](ErrOrValue value) {
    called = true;
    EXPECT_TRUE(value.ok()) << value.err().msg();
    // Should have returned the constant struct.
    EXPECT_EQ(struct_value, value.value());
  });
  EXPECT_TRUE(called);

  // Accessing "MyType->a" should use the PrettyType to dereference to the |struct_type| and then
  // resolve the member "a" on it, giving kAValue as the result.
  auto member_node = fxl::MakeRefCounted<MemberAccessExprNode>(
      my_node, ExprToken(ExprTokenType::kArrow, "->", 0), ParsedIdentifier("a"));
  called = false;
  member_node->Eval(context, [&called, struct_value, kAValue](ErrOrValue value) {
    called = true;
    EXPECT_TRUE(value.ok()) << value.err().msg();
    // Should have returned the constant struct.
    EXPECT_EQ(kAValue, value.value().GetAs<int32_t>());
  });
  EXPECT_TRUE(called);
}

// The casting tests cover most casting-related functionality. This acts as a smoketest that it's
// hooked up, and specifically tests the tricky special-casing of casting references to references
// (which shouldn't expand the reference value).
TEST_F(ExprNodeTest, Cast) {
  DerivedClassTestSetup d;
  auto context = fxl::MakeRefCounted<MockEvalContext>();

  // Base2& base2_ref_value = base2_value;
  // static_cast<Derived&>(base2_ref_value);  // <- cast_ref_ref_node
  auto base2_ref_node = fxl::MakeRefCounted<MockExprNode>(true, d.base2_ref_value);
  auto derived_ref_type_node = fxl::MakeRefCounted<TypeExprNode>(d.derived_ref_type);
  auto cast_ref_ref_node = fxl::MakeRefCounted<CastExprNode>(
      CastType::kStatic, std::move(derived_ref_type_node), std::move(base2_ref_node));

  // Do the call.
  bool called = false;
  ExprValue out_value;
  cast_ref_ref_node->Eval(context, [&called, &out_value](ErrOrValue value) {
    called = true;
    ASSERT_FALSE(value.has_error());
    out_value = value.take_value();
  });

  // Should have run synchronously.
  EXPECT_TRUE(called);
  EXPECT_EQ(d.derived_ref_value, out_value);

  // Now cast a ref to an object. This should dereference the object and find the base class inside
  // of it.
  // static_cast<Base2>(derived_ref_value)
  auto derived_ref_node = fxl::MakeRefCounted<MockExprNode>(true, d.derived_ref_value);
  auto base2_type_node = fxl::MakeRefCounted<TypeExprNode>(d.base2_type);
  auto cast_node = fxl::MakeRefCounted<CastExprNode>(CastType::kStatic, std::move(base2_type_node),
                                                     std::move(derived_ref_node));

  // Provide the memory for the derived type for when we dereference the ref.
  context->data_provider()->AddMemory(d.kDerivedAddr, d.derived_value.data());

  called = false;
  out_value = ExprValue();
  cast_node->Eval(context, [&called, &out_value](ErrOrValue value) {
    called = true;
    EXPECT_FALSE(value.has_error()) << value.err().msg();
    out_value = value.take_value();
  });

  // Dereferencing will be an asynchronous memory request so it will not have completed yet.
  EXPECT_FALSE(called);
  loop().RunUntilNoTasks();
  EXPECT_TRUE(called);

  // Should have converted to the Base2 value.
  EXPECT_EQ(d.base2_value, out_value);
}

// Tests integration with the PrettyType's member mechanism. A PrettyType provides a getter function
// that can evaluate a value on an object that looks like a member access.
TEST_F(ExprNodeTest, PrettyTypeMember) {
  auto context = fxl::MakeRefCounted<MockEvalContext>();

  // Register the PrettyType that provides a getter.
  const char kTypeName[] = "MyType";
  IdentifierGlob glob;
  ASSERT_FALSE(glob.Init(kTypeName).has_error());
  context->pretty_type_manager().Add(ExprLanguage::kC, glob,
                                     std::make_unique<MockGetterPrettyType>());

  // Object on left side of the ".".
  auto type = fxl::MakeRefCounted<Collection>(DwarfTag::kStructureType, kTypeName);
  type->set_byte_size(1);  // Make it not zero size.
  ExprValue value(type, {});
  auto content = fxl::MakeRefCounted<MockExprNode>(true, value);

  // Evaluate "value.<kMemberName>`
  auto dot_access = fxl::MakeRefCounted<MemberAccessExprNode>(
      content, ExprToken(ExprTokenType::kDot, ".", 0),
      ParsedIdentifier(MockGetterPrettyType::kMemberName));

  // Evaluate, everything is synchronously available.
  bool called = false;
  dot_access->Eval(context, [&called](ErrOrValue value) {
    called = true;
    EXPECT_FALSE(value.has_error()) << value.err().msg();
    EXPECT_EQ(MockGetterPrettyType::kMemberValue, value.value().GetAs<int32_t>());
  });
  EXPECT_TRUE(called);

  // Now try one with a pointer.
  auto type_ptr = fxl::MakeRefCounted<ModifiedType>(DwarfTag::kPointerType, type);
  constexpr uint64_t kAddress = 0x110000;
  ExprValue pointer_value(type_ptr, {0x00, 0x00, 0x11, 0, 0, 0, 0, 0});
  auto pointer = fxl::MakeRefCounted<MockExprNode>(true, pointer_value);

  // Data pointed to by the pointer (object is one byte, doesn't matter what value).
  context->data_provider()->AddMemory(kAddress, {0x00});

  auto arrow_access = fxl::MakeRefCounted<MemberAccessExprNode>(
      pointer, ExprToken(ExprTokenType::kArrow, "->", 0),
      ParsedIdentifier(MockGetterPrettyType::kMemberName));

  // Evaluate, requires a loop because fetching the pointer data is async.
  called = false;
  arrow_access->Eval(context, [&called](ErrOrValue value) {
    called = true;
    EXPECT_FALSE(value.has_error()) << value.err().msg();
    EXPECT_EQ(MockGetterPrettyType::kMemberValue, value.value().GetAs<int>());
  });
  EXPECT_FALSE(called);
  loop().RunUntilNoTasks();
  EXPECT_TRUE(called);

  // Try an non-pointer with the "->" operator.
  auto invalid_arrow_access = fxl::MakeRefCounted<MemberAccessExprNode>(
      content, ExprToken(ExprTokenType::kArrow, "->", 0),
      ParsedIdentifier(MockGetterPrettyType::kMemberName));

  called = false;
  invalid_arrow_access->Eval(context, [&called](ErrOrValue value) {
    called = true;
    EXPECT_TRUE(value.has_error());
    EXPECT_EQ("Attempting to dereference 'MyType' which is not a pointer.", value.err().msg());
  });
  EXPECT_TRUE(called);  // This error is synchronous.

  // Combine a custom dereferencer with a custom getter. So "needs_deref->getter()" where
  // needs_deref's type provides a pretty dereference operator.
  const char kDerefTypeName[] = "NeedsDeref";
  IdentifierGlob deref_glob;
  ASSERT_FALSE(deref_glob.Init(kDerefTypeName).has_error());
  context->pretty_type_manager().Add(ExprLanguage::kC, deref_glob,
                                     std::make_unique<MockDerefPrettyType>(value));

  // This is the node that returns the NeedsDeref type. Its value is unimportant.
  auto needs_deref_type = MakeCollectionType(DwarfTag::kStructureType, kDerefTypeName, {});
  ExprValue needs_deref_value(needs_deref_type, {});
  auto needs_deref_node = fxl::MakeRefCounted<MockExprNode>(true, needs_deref_value);

  // Nodes that represent the call "needs_deref->get5()";
  auto pretty_arrow_access = fxl::MakeRefCounted<MemberAccessExprNode>(
      needs_deref_node, ExprToken(ExprTokenType::kArrow, "->", 0),
      ParsedIdentifier(MockGetterPrettyType::kMemberName));

  // This is synchronous since no pointers are actually dereferenced.
  called = false;
  pretty_arrow_access->Eval(context, [&called](ErrOrValue value) {
    called = true;
    EXPECT_FALSE(value.has_error()) << value.err().msg();
    EXPECT_EQ(MockGetterPrettyType::kMemberValue, value.value().GetAs<int>());
  });
  EXPECT_TRUE(called);
}

// Tests integration with the PrettyType's getter mechanism. A PrettyType provides a getter function
// that can evaluate a value on an object that looks like a function call.
TEST_F(ExprNodeTest, PrettyTypeGetter) {
  auto context = fxl::MakeRefCounted<MockEvalContext>();

  // Register the PrettyType that provides a getter.
  const char kTypeName[] = "MyType";
  IdentifierGlob glob;
  ASSERT_FALSE(glob.Init(kTypeName).has_error());
  context->pretty_type_manager().Add(ExprLanguage::kC, glob,
                                     std::make_unique<MockGetterPrettyType>());

  // Object on left side of the ".".
  auto type = fxl::MakeRefCounted<Collection>(DwarfTag::kStructureType, kTypeName);
  type->set_byte_size(1);  // Make it not zero size.
  ExprValue value(type, {});
  auto content = fxl::MakeRefCounted<MockExprNode>(true, value);

  // Evaluate "value.<kGetterName>`
  auto dot_access = fxl::MakeRefCounted<MemberAccessExprNode>(
      content, ExprToken(ExprTokenType::kDot, ".", 0),
      ParsedIdentifier(MockGetterPrettyType::kGetterName));
  auto dot_call = fxl::MakeRefCounted<FunctionCallExprNode>(dot_access);

  // Evaluate, everything is synchronously available.
  bool called = false;
  dot_call->Eval(context, [&called](ErrOrValue value) {
    called = true;
    EXPECT_FALSE(value.has_error()) << value.err().msg();
    EXPECT_EQ(MockGetterPrettyType::kGetterValue, value.value().GetAs<int32_t>());
  });
  EXPECT_TRUE(called);

  // Now try one with a pointer.
  auto type_ptr = fxl::MakeRefCounted<ModifiedType>(DwarfTag::kPointerType, type);
  constexpr uint64_t kAddress = 0x110000;
  ExprValue pointer_value(type_ptr, {0x00, 0x00, 0x11, 0, 0, 0, 0, 0});
  auto pointer = fxl::MakeRefCounted<MockExprNode>(true, pointer_value);

  // Data pointed to by the pointer (object is one byte, doesn't matter what value).
  context->data_provider()->AddMemory(kAddress, {0x00});

  auto arrow_access = fxl::MakeRefCounted<MemberAccessExprNode>(
      pointer, ExprToken(ExprTokenType::kArrow, "->", 0),
      ParsedIdentifier(MockGetterPrettyType::kGetterName));
  auto arrow_call = fxl::MakeRefCounted<FunctionCallExprNode>(arrow_access);

  // Evaluate, requires a loop because fetching the pointer data is async.
  called = false;
  arrow_call->Eval(context, [&called](ErrOrValue value) {
    called = true;
    EXPECT_FALSE(value.has_error()) << value.err().msg();
    EXPECT_EQ(MockGetterPrettyType::kGetterValue, value.value().GetAs<int>());
  });
  EXPECT_FALSE(called);
  loop().RunUntilNoTasks();
  EXPECT_TRUE(called);

  // Try an non-pointer with the "->" operator.
  auto invalid_arrow_access = fxl::MakeRefCounted<MemberAccessExprNode>(
      content, ExprToken(ExprTokenType::kArrow, "->", 0),
      ParsedIdentifier(MockGetterPrettyType::kGetterName));
  auto invalid_arrow_call = fxl::MakeRefCounted<FunctionCallExprNode>(invalid_arrow_access);

  called = false;
  invalid_arrow_call->Eval(context, [&called](ErrOrValue value) {
    called = true;
    EXPECT_TRUE(value.has_error());
    EXPECT_EQ("Attempting to dereference 'MyType' which is not a pointer.", value.err().msg());
  });
  EXPECT_TRUE(called);  // This error is synchronous.

  // Combine a custom dereferencer with a custom getter. So "needs_deref->getter()" where
  // needs_deref's type provides a pretty dereference operator.
  const char kDerefTypeName[] = "NeedsDeref";
  IdentifierGlob deref_glob;
  ASSERT_FALSE(deref_glob.Init(kDerefTypeName).has_error());
  context->pretty_type_manager().Add(ExprLanguage::kC, deref_glob,
                                     std::make_unique<MockDerefPrettyType>(value));

  // This is the node that returns the NeedsDeref type. Its value is unimportant.
  auto needs_deref_type = MakeCollectionType(DwarfTag::kStructureType, kDerefTypeName, {});
  ExprValue needs_deref_value(needs_deref_type, {});
  auto needs_deref_node = fxl::MakeRefCounted<MockExprNode>(true, needs_deref_value);

  // Nodes that represent the call "needs_deref->get5()";
  auto pretty_arrow_access = fxl::MakeRefCounted<MemberAccessExprNode>(
      needs_deref_node, ExprToken(ExprTokenType::kArrow, "->", 0),
      ParsedIdentifier(MockGetterPrettyType::kGetterName));
  auto pretty_arrow_call = fxl::MakeRefCounted<FunctionCallExprNode>(pretty_arrow_access);

  // This is synchronous since no pointers are actually dereferenced.
  called = false;
  pretty_arrow_call->Eval(context, [&called](ErrOrValue value) {
    called = true;
    EXPECT_FALSE(value.has_error()) << value.err().msg();
    EXPECT_EQ(MockGetterPrettyType::kGetterValue, value.value().GetAs<int>());
  });
  EXPECT_TRUE(called);
}

TEST_F(ExprNodeTest, Sizeof) {
  auto context = fxl::MakeRefCounted<MockEvalContext>();

  // References on raw types should be stripped. Make a one-byte sized type and an 8-byte reference
  // to it.
  auto char_type = fxl::MakeRefCounted<BaseType>(BaseType::kBaseTypeSignedChar, 1, "char");
  auto char_ref_type = fxl::MakeRefCounted<ModifiedType>(DwarfTag::kReferenceType, char_type);
  EXPECT_EQ(8u, char_ref_type->byte_size());

  auto char_ref_type_node = fxl::MakeRefCounted<TypeExprNode>(char_ref_type);
  auto sizeof_char_ref_type = fxl::MakeRefCounted<SizeofExprNode>(char_ref_type_node);

  bool called = false;
  sizeof_char_ref_type->Eval(context, [&called](ErrOrValue v) {
    EXPECT_FALSE(v.has_error());

    // Should have retrieved the size of the char, not the reference itself.
    uint64_t sizeof_value = 0;
    EXPECT_FALSE(v.value().PromoteTo64(&sizeof_value).has_error());
    EXPECT_EQ(1u, sizeof_value);

    called = true;
  });
  EXPECT_TRUE(called);  // Make sure callback executed.

  // Test sizeof() for an asynchronously-executed boolean value.
  auto char_value_node = fxl::MakeRefCounted<MockExprNode>(false, ExprValue(true));
  auto sizeof_char = fxl::MakeRefCounted<SizeofExprNode>(char_value_node);

  called = false;
  sizeof_char->Eval(context, [&called](ErrOrValue v) {
    EXPECT_FALSE(v.has_error());

    // Should have retrieved the size of the char.
    uint64_t sizeof_value = 0;
    EXPECT_FALSE(v.value().PromoteTo64(&sizeof_value).has_error());
    EXPECT_EQ(1u, sizeof_value);

    called = true;
  });

  loop().RunUntilNoTasks();
  EXPECT_TRUE(called);  // Make sure callback executed.
}

}  // namespace zxdb
