// Copyright (c) 2020, 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/compiler/frontend/kernel_binary_flowgraph.h"

#include "vm/compiler/backend/il_test_helper.h"
#include "vm/object.h"
#include "vm/unit_test.h"

namespace dart {

ISOLATE_UNIT_TEST_CASE(StreamingFlowGraphBuilder_ConstFoldStringConcats) {
  // According to the Dart spec:
  // "Adjacent strings are implicitly concatenated to form a single string
  // literal."
  const char* kScript = R"(
    test() {
      var s = 'aaaa'
          'bbbb'
          'cccc';
      return s;
    }
  )";

  const auto& root_library = Library::Handle(LoadTestScript(kScript));
  const auto& function = Function::Handle(GetFunction(root_library, "test"));

  Invoke(root_library, "test");

  TestPipeline pipeline(function, CompilerPass::kJIT);
  FlowGraph* flow_graph = pipeline.RunPasses({
      CompilerPass::kComputeSSA,
  });

  auto entry = flow_graph->graph_entry()->normal_entry();
  EXPECT(entry != nullptr);

  ReturnInstr* ret = nullptr;

  ILMatcher cursor(flow_graph, entry);
  // clang-format off
  RELEASE_ASSERT(cursor.TryMatch({
    kMatchAndMoveFunctionEntry,
    kMatchAndMoveCheckStackOverflow,
    kMoveDebugStepChecks,
    {kMatchReturn, &ret},
  }));
  // clang-format on

  EXPECT(ret->value()->BindsToConstant());
  EXPECT(ret->value()->BoundConstant().IsString());
  const String& ret_str = String::Cast(ret->value()->BoundConstant());
  EXPECT(ret_str.Equals("aaaabbbbcccc"));
}

ISOLATE_UNIT_TEST_CASE(StreamingFlowGraphBuilder_FlattenNestedStringInterp) {
  // We should collapse nested StringInterpolates:
  const char* kScript = R"(
    test(String s) {
      return '$s' '${'d' 'e'}';
    }
    main() => test('u');
  )";

  const auto& root_library = Library::Handle(LoadTestScript(kScript));
  const auto& function = Function::Handle(GetFunction(root_library, "test"));

  Invoke(root_library, "main");

  TestPipeline pipeline(function, CompilerPass::kJIT);
  FlowGraph* flow_graph = pipeline.RunPasses({
      CompilerPass::kComputeSSA,
  });

  auto entry = flow_graph->graph_entry()->normal_entry();
  EXPECT(entry != nullptr);

  StoreIndexedInstr* store1 = nullptr;
  StoreIndexedInstr* store2 = nullptr;

  ILMatcher cursor(flow_graph, entry);
  // clang-format off
  RELEASE_ASSERT(cursor.TryMatch({
    kMatchAndMoveFunctionEntry,
    kMatchAndMoveCheckStackOverflow,
    kMoveDebugStepChecks,
    kMatchAndMoveCreateArray,
    {kMatchAndMoveStoreIndexed, &store1},
    {kMatchAndMoveStoreIndexed, &store2},
    kMatchAndMoveStringInterpolate,
    kMoveDebugStepChecks,
    kMatchReturn,
  }));
  // clang-format on

  // StoreIndexed(tmp_array, 0, s)
  EXPECT(store1->index()->BindsToConstant());
  EXPECT(store1->index()->BoundConstant().IsInteger());
  EXPECT(Integer::Cast(store1->index()->BoundConstant()).AsInt64Value() == 0);

  EXPECT(!store1->value()->BindsToConstant());

  // StoreIndexed(tmp_array, 1, "de")
  EXPECT(store2->index()->BindsToConstant());
  EXPECT(store2->index()->BoundConstant().IsInteger());
  EXPECT(Integer::Cast(store2->index()->BoundConstant()).AsInt64Value() == 1);

  EXPECT(store2->value()->BindsToConstant());
  EXPECT(store2->value()->BoundConstant().IsString());
  EXPECT(String::Cast(store2->value()->BoundConstant()).Equals("de"));
}

ISOLATE_UNIT_TEST_CASE(StreamingFlowGraphBuilder_DropEmptyStringInterp) {
  // We should drop empty strings from StringInterpolates:
  const char* kScript = R"(
    test(s) {
      return '' 'a' '$s' '' 'b' '';
    }
    main() => test('u');
  )";

  const auto& root_library = Library::Handle(LoadTestScript(kScript));
  const auto& function = Function::Handle(GetFunction(root_library, "test"));

  Invoke(root_library, "main");

  TestPipeline pipeline(function, CompilerPass::kJIT);
  FlowGraph* flow_graph = pipeline.RunPasses({
      CompilerPass::kComputeSSA,
  });

  auto entry = flow_graph->graph_entry()->normal_entry();
  EXPECT(entry != nullptr);

  StoreIndexedInstr* store1 = nullptr;
  StoreIndexedInstr* store2 = nullptr;
  StoreIndexedInstr* store3 = nullptr;

  ILMatcher cursor(flow_graph, entry);
  // clang-format off
  RELEASE_ASSERT(cursor.TryMatch({
    kMatchAndMoveFunctionEntry,
    kMatchAndMoveCheckStackOverflow,
    kMoveDebugStepChecks,
    kMatchAndMoveCreateArray,
    {kMatchAndMoveStoreIndexed, &store1},
    {kMatchAndMoveStoreIndexed, &store2},
    {kMatchAndMoveStoreIndexed, &store3},
    kMatchAndMoveStringInterpolate,
    kMoveDebugStepChecks,
    kMatchReturn,
  }));
  // clang-format on

  // StoreIndexed(tmp_array, 0, "ab")
  EXPECT(store1->index()->BindsToConstant());
  EXPECT(store1->index()->BoundConstant().IsInteger());
  EXPECT(Integer::Cast(store1->index()->BoundConstant()).AsInt64Value() == 0);

  EXPECT(store1->value()->BindsToConstant());
  EXPECT(store1->value()->BoundConstant().IsString());
  EXPECT(String::Cast(store1->value()->BoundConstant()).Equals("a"));

  // StoreIndexed(tmp_array, 1, s)
  EXPECT(store2->index()->BindsToConstant());
  EXPECT(store2->index()->BoundConstant().IsInteger());
  EXPECT(Integer::Cast(store2->index()->BoundConstant()).AsInt64Value() == 1);

  EXPECT(!store2->value()->BindsToConstant());

  // StoreIndexed(tmp_array, 2, "b")
  EXPECT(store3->index()->BindsToConstant());
  EXPECT(store3->index()->BoundConstant().IsInteger());
  EXPECT(Integer::Cast(store3->index()->BoundConstant()).AsInt64Value() == 2);

  EXPECT(store3->value()->BindsToConstant());
  EXPECT(store3->value()->BoundConstant().IsString());
  EXPECT(String::Cast(store3->value()->BoundConstant()).Equals("b"));
}

ISOLATE_UNIT_TEST_CASE(StreamingFlowGraphBuilder_ConcatStringLits) {
  // We should drop empty strings from StringInterpolates:
  const char* kScript = R"(
    test(s) {
      return '' 'a' '' 'b' '$s' '' 'c' '' 'd' '';
    }
    main() => test('u');
  )";

  const auto& root_library = Library::Handle(LoadTestScript(kScript));
  const auto& function = Function::Handle(GetFunction(root_library, "test"));

  Invoke(root_library, "main");

  TestPipeline pipeline(function, CompilerPass::kJIT);
  FlowGraph* flow_graph = pipeline.RunPasses({
      CompilerPass::kComputeSSA,
  });

  auto entry = flow_graph->graph_entry()->normal_entry();
  EXPECT(entry != nullptr);

  StoreIndexedInstr* store1 = nullptr;
  StoreIndexedInstr* store2 = nullptr;
  StoreIndexedInstr* store3 = nullptr;

  ILMatcher cursor(flow_graph, entry);
  // clang-format off
  RELEASE_ASSERT(cursor.TryMatch({
    kMatchAndMoveFunctionEntry,
    kMatchAndMoveCheckStackOverflow,
    kMoveDebugStepChecks,
    kMatchAndMoveCreateArray,
    {kMatchAndMoveStoreIndexed, &store1},
    {kMatchAndMoveStoreIndexed, &store2},
    {kMatchAndMoveStoreIndexed, &store3},
    kMatchAndMoveStringInterpolate,
    kMoveDebugStepChecks,
    kMatchReturn,
  }));
  // clang-format on

  // StoreIndexed(tmp_array, 0, "ab")
  EXPECT(store1->index()->BindsToConstant());
  EXPECT(store1->index()->BoundConstant().IsInteger());
  EXPECT(Integer::Cast(store1->index()->BoundConstant()).AsInt64Value() == 0);

  EXPECT(store1->value()->BindsToConstant());
  EXPECT(store1->value()->BoundConstant().IsString());
  EXPECT(String::Cast(store1->value()->BoundConstant()).Equals("ab"));

  // StoreIndexed(tmp_array, 1, s)
  EXPECT(store2->index()->BindsToConstant());
  EXPECT(store2->index()->BoundConstant().IsInteger());
  EXPECT(Integer::Cast(store2->index()->BoundConstant()).AsInt64Value() == 1);

  EXPECT(!store2->value()->BindsToConstant());

  // StoreIndexed(tmp_array, 2, "cd")
  EXPECT(store3->index()->BindsToConstant());
  EXPECT(store3->index()->BoundConstant().IsInteger());
  EXPECT(Integer::Cast(store3->index()->BoundConstant()).AsInt64Value() == 2);

  EXPECT(store3->value()->BindsToConstant());
  EXPECT(store3->value()->BoundConstant().IsString());
  EXPECT(String::Cast(store3->value()->BoundConstant()).Equals("cd"));
}

}  // namespace dart
