r317344 - Move Extract.cpp that wasn't moved in r317343
Alex Lorenz via cfe-commits
cfe-commits at lists.llvm.org
Fri Nov 3 11:21:06 PDT 2017
Author: arphaman
Date: Fri Nov 3 11:21:06 2017
New Revision: 317344
URL: http://llvm.org/viewvc/llvm-project?rev=317344&view=rev
Log:
Move Extract.cpp that wasn't moved in r317343
Added:
cfe/trunk/lib/Tooling/Refactoring/Extract/Extract.cpp
Removed:
cfe/trunk/lib/Tooling/Refactoring/Extract.cpp
Removed: cfe/trunk/lib/Tooling/Refactoring/Extract.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Tooling/Refactoring/Extract.cpp?rev=317343&view=auto
==============================================================================
--- cfe/trunk/lib/Tooling/Refactoring/Extract.cpp (original)
+++ cfe/trunk/lib/Tooling/Refactoring/Extract.cpp (removed)
@@ -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
Added: cfe/trunk/lib/Tooling/Refactoring/Extract/Extract.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Tooling/Refactoring/Extract/Extract.cpp?rev=317344&view=auto
==============================================================================
--- cfe/trunk/lib/Tooling/Refactoring/Extract/Extract.cpp (added)
+++ cfe/trunk/lib/Tooling/Refactoring/Extract/Extract.cpp Fri Nov 3 11:21:06 2017
@@ -0,0 +1,199 @@
+//===--- 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
More information about the cfe-commits
mailing list