diff options
author | Alex Lorenz <arphaman@gmail.com> | 2017-11-03 18:21:06 +0000 |
---|---|---|
committer | Alex Lorenz <arphaman@gmail.com> | 2017-11-03 18:21:06 +0000 |
commit | 3aae328318209ac11d652c93806bdce7ffd3f41f (patch) | |
tree | f027dba2e5142ccdee25712a525b34f6c4d4304f /clang/lib/Tooling/Refactoring/Extract.cpp | |
parent | ebbbb8126678c027e1f6bfa9c34f3470a2f81b89 (diff) | |
download | bcm5719-llvm-3aae328318209ac11d652c93806bdce7ffd3f41f.tar.gz bcm5719-llvm-3aae328318209ac11d652c93806bdce7ffd3f41f.zip |
Move Extract.cpp that wasn't moved in r317343
llvm-svn: 317344
Diffstat (limited to 'clang/lib/Tooling/Refactoring/Extract.cpp')
-rw-r--r-- | clang/lib/Tooling/Refactoring/Extract.cpp | 199 |
1 files changed, 0 insertions, 199 deletions
diff --git a/clang/lib/Tooling/Refactoring/Extract.cpp b/clang/lib/Tooling/Refactoring/Extract.cpp deleted file mode 100644 index b0847a74004..00000000000 --- a/clang/lib/Tooling/Refactoring/Extract.cpp +++ /dev/null @@ -1,199 +0,0 @@ -//===--- Extract.cpp - Clang refactoring library --------------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -/// -/// \file -/// \brief Implements the "extract" refactoring that can pull code into -/// new functions, methods or declare new variables. -/// -//===----------------------------------------------------------------------===// - -#include "clang/Tooling/Refactoring/Extract/Extract.h" -#include "SourceExtraction.h" -#include "clang/AST/ASTContext.h" -#include "clang/AST/DeclCXX.h" -#include "clang/AST/Expr.h" -#include "clang/AST/ExprObjC.h" -#include "clang/Rewrite/Core/Rewriter.h" - -namespace clang { -namespace tooling { - -namespace { - -/// Returns true if \c E is a simple literal or a reference expression that -/// should not be extracted. -bool isSimpleExpression(const Expr *E) { - if (!E) - return false; - switch (E->IgnoreParenCasts()->getStmtClass()) { - case Stmt::DeclRefExprClass: - case Stmt::PredefinedExprClass: - case Stmt::IntegerLiteralClass: - case Stmt::FloatingLiteralClass: - case Stmt::ImaginaryLiteralClass: - case Stmt::CharacterLiteralClass: - case Stmt::StringLiteralClass: - return true; - default: - return false; - } -} - -SourceLocation computeFunctionExtractionLocation(const Decl *D) { - if (isa<CXXMethodDecl>(D)) { - // Code from method that is defined in class body should be extracted to a - // function defined just before the class. - while (const auto *RD = dyn_cast<CXXRecordDecl>(D->getLexicalDeclContext())) - D = RD; - } - return D->getLocStart(); -} - -} // end anonymous namespace - -const RefactoringDescriptor &ExtractFunction::describe() { - static const RefactoringDescriptor Descriptor = { - "extract-function", - "Extract Function", - "(WIP action; use with caution!) Extracts code into a new function", - }; - return Descriptor; -} - -Expected<ExtractFunction> -ExtractFunction::initiate(RefactoringRuleContext &Context, - CodeRangeASTSelection Code, - Optional<std::string> DeclName) { - // We would like to extract code out of functions/methods/blocks. - // Prohibit extraction from things like global variable / field - // initializers and other top-level expressions. - if (!Code.isInFunctionLikeBodyOfCode()) - return Context.createDiagnosticError( - diag::err_refactor_code_outside_of_function); - - if (Code.size() == 1) { - // Avoid extraction of simple literals and references. - if (isSimpleExpression(dyn_cast<Expr>(Code[0]))) - return Context.createDiagnosticError( - diag::err_refactor_extract_simple_expression); - - // Property setters can't be extracted. - if (const auto *PRE = dyn_cast<ObjCPropertyRefExpr>(Code[0])) { - if (!PRE->isMessagingGetter()) - return Context.createDiagnosticError( - diag::err_refactor_extract_prohibited_expression); - } - } - - return ExtractFunction(std::move(Code), DeclName); -} - -// FIXME: Support C++ method extraction. -// FIXME: Support Objective-C method extraction. -Expected<AtomicChanges> -ExtractFunction::createSourceReplacements(RefactoringRuleContext &Context) { - const Decl *ParentDecl = Code.getFunctionLikeNearestParent(); - assert(ParentDecl && "missing parent"); - - // Compute the source range of the code that should be extracted. - SourceRange ExtractedRange(Code[0]->getLocStart(), - Code[Code.size() - 1]->getLocEnd()); - // FIXME (Alex L): Add code that accounts for macro locations. - - ASTContext &AST = Context.getASTContext(); - SourceManager &SM = AST.getSourceManager(); - const LangOptions &LangOpts = AST.getLangOpts(); - Rewriter ExtractedCodeRewriter(SM, LangOpts); - - // FIXME: Capture used variables. - - // Compute the return type. - QualType ReturnType = AST.VoidTy; - // FIXME (Alex L): Account for the return statement in extracted code. - // FIXME (Alex L): Check for lexical expression instead. - bool IsExpr = Code.size() == 1 && isa<Expr>(Code[0]); - if (IsExpr) { - // FIXME (Alex L): Get a more user-friendly type if needed. - ReturnType = cast<Expr>(Code[0])->getType(); - } - - // FIXME: Rewrite the extracted code performing any required adjustments. - - // FIXME: Capture any field if necessary (method -> function extraction). - - // FIXME: Sort captured variables by name. - - // FIXME: Capture 'this' / 'self' if necessary. - - // FIXME: Compute the actual parameter types. - - // Compute the location of the extracted declaration. - SourceLocation ExtractedDeclLocation = - computeFunctionExtractionLocation(ParentDecl); - // FIXME: Adjust the location to account for any preceding comments. - - // FIXME: Adjust with PP awareness like in Sema to get correct 'bool' - // treatment. - PrintingPolicy PP = AST.getPrintingPolicy(); - // FIXME: PP.UseStdFunctionForLambda = true; - PP.SuppressStrongLifetime = true; - PP.SuppressLifetimeQualifiers = true; - PP.SuppressUnwrittenScope = true; - - ExtractionSemicolonPolicy Semicolons = ExtractionSemicolonPolicy::compute( - Code[Code.size() - 1], ExtractedRange, SM, LangOpts); - AtomicChange Change(SM, ExtractedDeclLocation); - // Create the replacement for the extracted declaration. - { - std::string ExtractedCode; - llvm::raw_string_ostream OS(ExtractedCode); - // FIXME: Use 'inline' in header. - OS << "static "; - ReturnType.print(OS, PP, DeclName); - OS << '('; - // FIXME: Arguments. - OS << ')'; - - // Function body. - OS << " {\n"; - if (IsExpr && !ReturnType->isVoidType()) - OS << "return "; - OS << ExtractedCodeRewriter.getRewrittenText(ExtractedRange); - if (Semicolons.isNeededInExtractedFunction()) - OS << ';'; - OS << "\n}\n\n"; - auto Err = Change.insert(SM, ExtractedDeclLocation, OS.str()); - if (Err) - return std::move(Err); - } - - // Create the replacement for the call to the extracted declaration. - { - std::string ReplacedCode; - llvm::raw_string_ostream OS(ReplacedCode); - - OS << DeclName << '('; - // FIXME: Forward arguments. - OS << ')'; - if (Semicolons.isNeededInOriginalFunction()) - OS << ';'; - - auto Err = Change.replace( - SM, CharSourceRange::getTokenRange(ExtractedRange), OS.str()); - if (Err) - return std::move(Err); - } - - // FIXME: Add support for assocciated symbol location to AtomicChange to mark - // the ranges of the name of the extracted declaration. - return AtomicChanges{std::move(Change)}; -} - -} // end namespace tooling -} // end namespace clang |