//===--- SourceExtraction.cpp - Clang refactoring library -----------------===//
//
// 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/Tooling/Refactoring/Extract/SourceExtraction.h"
#include "clang/AST/Stmt.h"
#include "clang/AST/StmtCXX.h"
#include "clang/AST/StmtObjC.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Lex/Lexer.h"

using namespace clang;

namespace {

/// Returns true if the token at the given location is a semicolon.
bool isSemicolonAtLocation(SourceLocation TokenLoc, const SourceManager &SM,
                           const LangOptions &LangOpts) {
  return Lexer::getSourceText(
             CharSourceRange::getTokenRange(TokenLoc, TokenLoc), SM,
             LangOpts) == ";";
}

/// Returns true if there should be a semicolon after the given statement.
bool isSemicolonRequiredAfter(const Stmt *S) {
  if (isa<CompoundStmt>(S))
    return false;
  if (const auto *If = dyn_cast<IfStmt>(S))
    return isSemicolonRequiredAfter(If->getElse() ? If->getElse()
                                                  : If->getThen());
  if (const auto *While = dyn_cast<WhileStmt>(S))
    return isSemicolonRequiredAfter(While->getBody());
  if (const auto *For = dyn_cast<ForStmt>(S))
    return isSemicolonRequiredAfter(For->getBody());
  if (const auto *CXXFor = dyn_cast<CXXForRangeStmt>(S))
    return isSemicolonRequiredAfter(CXXFor->getBody());
  if (const auto *ObjCFor = dyn_cast<ObjCForCollectionStmt>(S))
    return isSemicolonRequiredAfter(ObjCFor->getBody());
  if(const auto *Switch = dyn_cast<SwitchStmt>(S))
    return isSemicolonRequiredAfter(Switch->getBody());
  if(const auto *Case = dyn_cast<SwitchCase>(S))
    return isSemicolonRequiredAfter(Case->getSubStmt());
  switch (S->getStmtClass()) {
  case Stmt::DeclStmtClass:
  case Stmt::CXXTryStmtClass:
  case Stmt::ObjCAtSynchronizedStmtClass:
  case Stmt::ObjCAutoreleasePoolStmtClass:
  case Stmt::ObjCAtTryStmtClass:
    return false;
  default:
    return true;
  }
}

/// Returns true if the two source locations are on the same line.
bool areOnSameLine(SourceLocation Loc1, SourceLocation Loc2,
                   const SourceManager &SM) {
  return !Loc1.isMacroID() && !Loc2.isMacroID() &&
         SM.getSpellingLineNumber(Loc1) == SM.getSpellingLineNumber(Loc2);
}

} // end anonymous namespace

namespace clang {
namespace tooling {

ExtractionSemicolonPolicy
ExtractionSemicolonPolicy::compute(const Stmt *S, SourceRange &ExtractedRange,
                                   const SourceManager &SM,
                                   const LangOptions &LangOpts) {
  auto neededInExtractedFunction = []() {
    return ExtractionSemicolonPolicy(true, false);
  };
  auto neededInOriginalFunction = []() {
    return ExtractionSemicolonPolicy(false, true);
  };

  /// The extracted expression should be terminated with a ';'. The call to
  /// the extracted function will replace this expression, so it won't need
  /// a terminating ';'.
  if (isa<Expr>(S))
    return neededInExtractedFunction();

  /// Some statements don't need to be terminated with ';'. The call to the
  /// extracted function will be a standalone statement, so it should be
  /// terminated with a ';'.
  bool NeedsSemi = isSemicolonRequiredAfter(S);
  if (!NeedsSemi)
    return neededInOriginalFunction();

  /// Some statements might end at ';'. The extraction will move that ';', so
  /// the call to the extracted function should be terminated with a ';'.
  SourceLocation End = ExtractedRange.getEnd();
  if (isSemicolonAtLocation(End, SM, LangOpts))
    return neededInOriginalFunction();

  /// Other statements should generally have a trailing ';'. We can try to find
  /// it and move it together it with the extracted code.
  Optional<Token> NextToken = Lexer::findNextToken(End, SM, LangOpts);
  if (NextToken && NextToken->is(tok::semi) &&
      areOnSameLine(NextToken->getLocation(), End, SM)) {
    ExtractedRange.setEnd(NextToken->getLocation());
    return neededInOriginalFunction();
  }

  /// Otherwise insert semicolons in both places.
  return ExtractionSemicolonPolicy(true, true);
}

} // end namespace tooling
} // end namespace clang
