// 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 "platform/assert.h"
#include "vm/cha.h"
#include "vm/class_finalizer.h"
#include "vm/globals.h"
#include "vm/symbols.h"
#include "vm/unit_test.h"

namespace dart {


TEST_CASE(ClassHierarchyAnalysis) {
  const char* kScriptChars =
      "class A {"
      "  foo() { }"
      "  bar() { }"
      "}\n"
      "class B extends A {"
      "}\n"
      "class C extends B {"
      "  foo() { }"
      "}\n"
      "class D extends A {"
      "  foo() { }"
      "  bar() { }"
      "}\n";

  TestCase::LoadTestScript(kScriptChars, NULL);
  EXPECT(ClassFinalizer::ProcessPendingClasses());
  const String& name = String::Handle(String::New(TestCase::url()));
  const Library& lib = Library::Handle(Library::LookupLibrary(thread, name));
  EXPECT(!lib.IsNull());

  const Class& class_a =
      Class::Handle(lib.LookupClass(String::Handle(Symbols::New(thread, "A"))));
  EXPECT(!class_a.IsNull());

  const Class& class_b =
      Class::Handle(lib.LookupClass(String::Handle(Symbols::New(thread, "B"))));
  EXPECT(!class_b.IsNull());

  const Class& class_c =
      Class::Handle(lib.LookupClass(String::Handle(Symbols::New(thread, "C"))));
  EXPECT(!class_c.IsNull());

  const Class& class_d =
      Class::Handle(lib.LookupClass(String::Handle(Symbols::New(thread, "D"))));
  EXPECT(!class_d.IsNull());

  const String& function_foo_name = String::Handle(String::New("foo"));
  const String& function_bar_name = String::Handle(String::New("bar"));

  const Function& class_a_foo =
      Function::Handle(class_a.LookupDynamicFunction(function_foo_name));
  EXPECT(!class_a_foo.IsNull());

  const Function& class_a_bar =
      Function::Handle(class_a.LookupDynamicFunction(function_bar_name));
  EXPECT(!class_a_bar.IsNull());

  const Function& class_c_foo =
      Function::Handle(class_c.LookupDynamicFunction(function_foo_name));
  EXPECT(!class_c_foo.IsNull());

  const Function& class_d_foo =
      Function::Handle(class_d.LookupDynamicFunction(function_foo_name));
  EXPECT(!class_d_foo.IsNull());

  const Function& class_d_bar =
      Function::Handle(class_d.LookupDynamicFunction(function_bar_name));
  EXPECT(!class_d_bar.IsNull());

  CHA cha(Thread::Current());

  EXPECT(cha.HasSubclasses(kInstanceCid));
  EXPECT(!cha.HasSubclasses(kSmiCid));
  EXPECT(!cha.HasSubclasses(kNullCid));

  EXPECT(CHA::HasSubclasses(class_a));
  EXPECT(CHA::HasSubclasses(class_b));
  EXPECT(!CHA::HasSubclasses(class_c));
  cha.AddToGuardedClasses(class_c, /*subclass_count=*/0);
  EXPECT(!CHA::HasSubclasses(class_d));
  cha.AddToGuardedClasses(class_d, /*subclass_count=*/0);

  EXPECT(!cha.IsGuardedClass(class_a.id()));
  EXPECT(!cha.IsGuardedClass(class_b.id()));
  EXPECT(cha.IsGuardedClass(class_c.id()));
  EXPECT(cha.IsGuardedClass(class_d.id()));

  const Class& closure_class =
      Class::Handle(Isolate::Current()->object_store()->closure_class());
  EXPECT(!cha.HasSubclasses(closure_class.id()));
}

}  // namespace dart
