12 #include "clang/AST/ASTContext.h" 13 #include "clang/AST/RecursiveASTVisitor.h" 14 #include "clang/AST/Stmt.h" 15 #include "clang/Basic/LangOptions.h" 16 #include "clang/Basic/SourceLocation.h" 17 #include "clang/Basic/SourceManager.h" 18 #include "clang/Lex/Lexer.h" 19 #include "clang/Tooling/Core/Replacement.h" 20 #include "llvm/ADT/None.h" 21 #include "llvm/ADT/Optional.h" 22 #include "llvm/ADT/StringRef.h" 23 #include "llvm/ADT/iterator_range.h" 24 #include "llvm/Support/Casting.h" 25 #include "llvm/Support/Error.h" 37 class RawStringLiteral :
public Tweak {
39 const char *id() const override final;
41 bool prepare(const Selection &Inputs) override;
42 Expected<Effect> apply(const Selection &Inputs) override;
43 std::
string title()
const override {
return "Convert to raw string"; }
44 Intent intent()
const override {
return Refactor; }
47 const clang::StringLiteral *Str =
nullptr;
52 static bool isNormalString(
const StringLiteral &Str, SourceLocation Cursor,
57 SourceLocation LastTokenBeforeCursor;
58 for (
auto I = Str.tokloc_begin(),
E = Str.tokloc_end(); I !=
E; ++I) {
61 if (SM.isBeforeInTranslationUnit(*I, Cursor) || *I == Cursor)
62 LastTokenBeforeCursor = *I;
65 const char* Data = SM.getCharacterData(LastTokenBeforeCursor);
66 return Data && *Data ==
'"';
69 static bool needsRaw(llvm::StringRef Content) {
70 return Content.find_first_of(
"\"\n\t") != StringRef::npos;
73 static bool canBeRaw(llvm::StringRef Content) {
74 for (
char C : Content)
75 if (!llvm::isPrint(C) && C !=
'\n' && C !=
'\t')
77 return !Content.contains(
")\"");
80 bool RawStringLiteral::prepare(
const Selection &Inputs) {
81 const SelectionTree::Node *N = Inputs.ASTSelection.commonAncestor();
84 Str = dyn_cast_or_null<StringLiteral>(N->ASTNode.get<Stmt>());
86 isNormalString(*Str, Inputs.Cursor, Inputs.AST->getSourceManager()) &&
87 needsRaw(Str->getBytes()) && canBeRaw(Str->getBytes());
90 Expected<Tweak::Effect> RawStringLiteral::apply(
const Selection &Inputs) {
91 auto &SM = Inputs.AST->getSourceManager();
92 auto Reps = tooling::Replacements(
93 tooling::Replacement(SM, Str, (
"R\"(" + Str->getBytes() +
")\"").str(),
94 Inputs.AST->getLangOpts()));
95 return Effect::mainFileEdit(SM, std::move(Reps));
#define REGISTER_TWEAK(Subclass)
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
std::vector< const char * > Expected