// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#include "vm/scopes.h"
#include "platform/assert.h"
#include "vm/unit_test.h"

namespace dart {

ISOLATE_UNIT_TEST_CASE(LocalScope) {
  // Allocate a couple of local variables first.
  const Type& dynamic_type = Type::ZoneHandle(Type::DynamicType());
  const String& a = String::ZoneHandle(Symbols::New(thread, "a"));
  LocalVariable* var_a = new LocalVariable(
      TokenPosition::kNoSource, TokenPosition::kNoSource, a, dynamic_type);
  LocalVariable* inner_var_a = new LocalVariable(
      TokenPosition::kNoSource, TokenPosition::kNoSource, a, dynamic_type);
  const String& b = String::ZoneHandle(Symbols::New(thread, "b"));
  LocalVariable* var_b = new LocalVariable(
      TokenPosition::kNoSource, TokenPosition::kNoSource, b, dynamic_type);
  const String& c = String::ZoneHandle(Symbols::New(thread, "c"));
  LocalVariable* var_c = new LocalVariable(
      TokenPosition::kNoSource, TokenPosition::kNoSource, c, dynamic_type);

  LocalScope* outer_scope = new LocalScope(nullptr, 0, 0);
  LocalScope* inner_scope1 = new LocalScope(outer_scope, 0, 0);
  LocalScope* inner_scope2 = new LocalScope(outer_scope, 0, 0);

  EXPECT(outer_scope->parent() == nullptr);
  EXPECT_EQ(outer_scope, inner_scope1->parent());
  EXPECT_EQ(outer_scope, inner_scope2->parent());
  EXPECT_EQ(inner_scope2, outer_scope->child());
  EXPECT_EQ(inner_scope1, inner_scope2->sibling());
  EXPECT(inner_scope1->child() == nullptr);
  EXPECT(inner_scope2->child() == nullptr);

  // Populate the local scopes as follows:
  // {  // outer_scope
  //   var a;
  //   {  // inner_scope1
  //     var b;
  //   }
  //   L: {  // inner_scope2
  //     var c;
  //   }
  // }
  EXPECT(outer_scope->AddVariable(var_a));
  EXPECT(inner_scope1->AddVariable(var_b));
  EXPECT(inner_scope2->AddVariable(var_c));
  EXPECT(!outer_scope->AddVariable(var_a));

  // Check the simple layout above.
  EXPECT_EQ(var_a, outer_scope->LocalLookupVariable(
                       a, LocalVariable::kNoKernelOffset));
  EXPECT_EQ(var_a, inner_scope1->LookupVariable(
                       a, LocalVariable::kNoKernelOffset, true));
  EXPECT(outer_scope->LocalLookupVariable(b, LocalVariable::kNoKernelOffset) ==
         nullptr);
  EXPECT(inner_scope1->LocalLookupVariable(c, LocalVariable::kNoKernelOffset) ==
         nullptr);

  // Modify the local scopes to contain shadowing:
  // {  // outer_scope
  //   var a;
  //   {  // inner_scope1
  //     var b;
  //     var a;  // inner_var_a
  //   }
  //   {  // inner_scope2
  //     var c;
  //     L: ...
  //   }
  // }
  EXPECT(inner_scope1->AddVariable(inner_var_a));
  EXPECT_EQ(inner_var_a, inner_scope1->LookupVariable(
                             a, LocalVariable::kNoKernelOffset, true));
  EXPECT(inner_scope1->LookupVariable(a, LocalVariable::kNoKernelOffset,
                                      true) != var_a);

  // Modify the local scopes with access of an outer scope variable:
  // {  // outer_scope
  //   var a;
  //   {  // inner_scope1
  //     var b;
  //     var a;  // inner_var_a
  //   }
  //   {  // inner_scope2
  //     var c = a;
  //     L: ...
  //   }
  // }
  EXPECT(inner_scope2->LocalLookupVariable(a, LocalVariable::kNoKernelOffset) ==
         nullptr);
  EXPECT(inner_scope2->AddVariable(var_a));
  EXPECT_EQ(var_a, inner_scope2->LocalLookupVariable(
                       a, LocalVariable::kNoKernelOffset));

  EXPECT_EQ(1, outer_scope->num_variables());
  EXPECT_EQ(2, inner_scope1->num_variables());
  EXPECT_EQ(2, inner_scope2->num_variables());

  // Cannot depend on the order, but we should find the variables.
  EXPECT(outer_scope->VariableAt(0) == var_a);
  EXPECT((inner_scope1->VariableAt(0) == inner_var_a) ||
         (inner_scope1->VariableAt(1) == inner_var_a));
  EXPECT((inner_scope1->VariableAt(0) == var_b) ||
         (inner_scope1->VariableAt(1) == var_b));
  EXPECT((inner_scope2->VariableAt(0) == var_a) ||
         (inner_scope2->VariableAt(1) == var_a) ||
         (inner_scope2->VariableAt(2) == var_a));
  EXPECT((inner_scope2->VariableAt(0) == var_c) ||
         (inner_scope2->VariableAt(1) == var_c) ||
         (inner_scope2->VariableAt(2) == var_c));
}

}  // namespace dart
