//===- unittests/Analysis/CloneDetectionTest.cpp - Clone detection tests --===//
//
// 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 "clang/AST/RecursiveASTVisitor.h"
#include "clang/Analysis/CloneDetection.h"
#include "clang/Tooling/Tooling.h"
#include "gtest/gtest.h"

namespace clang {
namespace analysis {
namespace {

class CloneDetectionVisitor
    : public RecursiveASTVisitor<CloneDetectionVisitor> {

  CloneDetector &Detector;

public:
  explicit CloneDetectionVisitor(CloneDetector &D) : Detector(D) {}

  bool VisitFunctionDecl(FunctionDecl *D) {
    Detector.analyzeCodeBody(D);
    return true;
  }
};

/// Example constraint for testing purposes.
/// Filters out all statements that are in a function which name starts with
/// "bar".
class NoBarFunctionConstraint {
public:
  void constrain(std::vector<CloneDetector::CloneGroup> &CloneGroups) {
    CloneConstraint::splitCloneGroups(
        CloneGroups, [](const StmtSequence &A, const StmtSequence &B) {
          // Check if one of the sequences is in a function which name starts
          // with "bar".
          for (const StmtSequence &Arg : {A, B}) {
            if (const auto *D =
                    dyn_cast<const FunctionDecl>(Arg.getContainingDecl())) {
              if (D->getName().startswith("bar"))
                return false;
            }
          }
          return true;
        });
  }
};

TEST(CloneDetector, FilterFunctionsByName) {
  auto ASTUnit =
      clang::tooling::buildASTFromCode("void foo1(int &a1) { a1++; }\n"
                                       "void foo2(int &a2) { a2++; }\n"
                                       "void bar1(int &a3) { a3++; }\n"
                                       "void bar2(int &a4) { a4++; }\n");
  auto TU = ASTUnit->getASTContext().getTranslationUnitDecl();

  CloneDetector Detector;
  // Push all the function bodies into the detector.
  CloneDetectionVisitor Visitor(Detector);
  Visitor.TraverseTranslationUnitDecl(TU);

  // Find clones with the usual settings, but but we want to filter out
  // all statements from functions which names start with "bar".
  std::vector<CloneDetector::CloneGroup> CloneGroups;
  Detector.findClones(CloneGroups, NoBarFunctionConstraint(),
                      RecursiveCloneTypeIIHashConstraint(),
                      MinComplexityConstraint(2), MinGroupSizeConstraint(2),
                      RecursiveCloneTypeIIVerifyConstraint(),
                      OnlyLargestCloneConstraint());

  ASSERT_EQ(CloneGroups.size(), 1u);
  ASSERT_EQ(CloneGroups.front().size(), 2u);

  for (auto &Clone : CloneGroups.front()) {
    const auto ND = dyn_cast<const FunctionDecl>(Clone.getContainingDecl());
    ASSERT_TRUE(ND != nullptr);
    // Check that no function name starting with "bar" is in the results...
    ASSERT_TRUE(ND->getNameAsString().find("bar") != 0);
  }

  // Retry above's example without the filter...
  CloneGroups.clear();

  Detector.findClones(CloneGroups, RecursiveCloneTypeIIHashConstraint(),
                      MinComplexityConstraint(2), MinGroupSizeConstraint(2),
                      RecursiveCloneTypeIIVerifyConstraint(),
                      OnlyLargestCloneConstraint());
  ASSERT_EQ(CloneGroups.size(), 1u);
  ASSERT_EQ(CloneGroups.front().size(), 4u);

  // Count how many functions with the bar prefix we have in the results.
  int FoundFunctionsWithBarPrefix = 0;
  for (auto &Clone : CloneGroups.front()) {
    const auto ND = dyn_cast<const FunctionDecl>(Clone.getContainingDecl());
    ASSERT_TRUE(ND != nullptr);
    // This time check that we picked up the bar functions from above
    if (ND->getNameAsString().find("bar") == 0) {
      FoundFunctionsWithBarPrefix++;
    }
  }
  // We should have found the two functions bar1 and bar2.
  ASSERT_EQ(FoundFunctionsWithBarPrefix, 2);
}
} // namespace
} // namespace analysis
} // namespace clang
