31bool isSimpleExpression(
const Expr *
E) {
34 switch (
E->IgnoreParenCasts()->getStmtClass()) {
35 case Stmt::DeclRefExprClass:
36 case Stmt::PredefinedExprClass:
37 case Stmt::IntegerLiteralClass:
38 case Stmt::FloatingLiteralClass:
39 case Stmt::ImaginaryLiteralClass:
40 case Stmt::CharacterLiteralClass:
41 case Stmt::StringLiteralClass:
48SourceLocation computeFunctionExtractionLocation(
const Decl *
D) {
49 if (isa<CXXMethodDecl>(
D)) {
52 while (
const auto *RD = dyn_cast<CXXRecordDecl>(
D->getLexicalDeclContext()))
55 return D->getBeginLoc();
64 "(WIP action; use with caution!) Extracts code into a new function",
72 std::optional<std::string> DeclName) {
77 return Context.createDiagnosticError(
78 diag::err_refactor_code_outside_of_function);
80 if (Code.
size() == 1) {
82 if (isSimpleExpression(dyn_cast<Expr>(Code[0])))
83 return Context.createDiagnosticError(
84 diag::err_refactor_extract_simple_expression);
87 if (
const auto *PRE = dyn_cast<ObjCPropertyRefExpr>(Code[0])) {
88 if (!PRE->isMessagingGetter())
89 return Context.createDiagnosticError(
90 diag::err_refactor_extract_prohibited_expression);
102 assert(ParentDecl &&
"missing parent");
106 Code[Code.
size() - 1]->getEndLoc());
120 bool IsExpr = Code.
size() == 1 && isa<Expr>(Code[0]);
123 ReturnType = cast<Expr>(Code[0])->getType();
138 computeFunctionExtractionLocation(ParentDecl);
150 Code[Code.
size() - 1], ExtractedRange,
SM, LangOpts);
151 AtomicChange Change(
SM, ExtractedDeclLocation);
154 std::string ExtractedCode;
155 llvm::raw_string_ostream OS(ExtractedCode);
158 ReturnType.
print(OS, PP, DeclName);
167 OS << ExtractedCodeRewriter.getRewrittenText(ExtractedRange);
168 if (Semicolons.isNeededInExtractedFunction())
171 auto Err = Change.insert(
SM, ExtractedDeclLocation, OS.str());
173 return std::move(Err);
178 std::string ReplacedCode;
179 llvm::raw_string_ostream OS(ReplacedCode);
181 OS << DeclName <<
'(';
184 if (Semicolons.isNeededInOriginalFunction())
187 auto Err = Change.replace(
190 return std::move(Err);
Defines the clang::ASTContext interface.
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
SourceManager & getSourceManager()
const LangOptions & getLangOpts() const
const clang::PrintingPolicy & getPrintingPolicy() const
static CharSourceRange getTokenRange(SourceRange R)
Decl - This represents one declaration (or definition), e.g.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
A (possibly-)qualified type.
void print(raw_ostream &OS, const PrintingPolicy &Policy, const Twine &PlaceHolder=Twine(), unsigned Indentation=0) const
Rewriter - This is the main interface to the rewrite buffers.
Encodes a location in the source.
This class handles loading and caching of source files into memory.
A trivial tuple used to represent a source range.
The refactoring rule context stores all of the inputs that might be needed by a refactoring action ru...
The JSON file list parser is used to communicate input to InstallAPI.
Describes how types, statements, expressions, and declarations should be printed.
unsigned SuppressUnwrittenScope
Suppress printing parts of scope specifiers that are never written, e.g., for anonymous namespaces.
unsigned SuppressStrongLifetime
When true, suppress printing of the __strong lifetime qualifier in ARC.
unsigned SuppressLifetimeQualifiers
When true, suppress printing of lifetime qualifier in ARC.