10#include "clang/AST/ASTContext.h"
11#include "clang/AST/Stmt.h"
12#include "clang/Basic/LangOptions.h"
13#include "clang/Basic/SourceLocation.h"
14#include "clang/Basic/SourceManager.h"
15#include "clang/Tooling/Core/Replacement.h"
16#include "llvm/ADT/StringRef.h"
17#include "llvm/Support/Casting.h"
18#include "llvm/Support/Error.h"
30class RawStringLiteral :
public Tweak {
32 const char *id() const final;
34 bool prepare(const Selection &Inputs) override;
35 Expected<Effect> apply(const Selection &Inputs) override;
36 std::
string title()
const override {
return "Convert to raw string"; }
37 llvm::StringLiteral kind()
const override {
42 const clang::StringLiteral *Str =
nullptr;
47static bool isFeatureAvailable(
const ASTContext &Context) {
50 return Context.getLangOpts().CPlusPlus11;
53static bool isNormalString(
const StringLiteral &Str, SourceLocation Cursor,
56 if (!Str.isOrdinary())
58 SourceLocation LastTokenBeforeCursor;
59 for (
auto I = Str.tokloc_begin(),
E = Str.tokloc_end(); I !=
E; ++I) {
62 if (SM.isBeforeInTranslationUnit(*I, Cursor) || *I == Cursor)
63 LastTokenBeforeCursor = *I;
66 const char* Data = SM.getCharacterData(LastTokenBeforeCursor);
67 return Data && *Data ==
'"';
70static bool needsRaw(llvm::StringRef Content) {
71 return Content.find_first_of(
"\"\n\t") != StringRef::npos;
74static bool canBeRaw(llvm::StringRef Content) {
75 for (
char C : Content)
76 if (!llvm::isPrint(
C) &&
C !=
'\n' &&
C !=
'\t')
78 return !Content.contains(
")\"");
81bool RawStringLiteral::prepare(
const Selection &Inputs) {
82 if (!isFeatureAvailable(Inputs.AST->getASTContext())) {
85 const SelectionTree::Node *N = Inputs.ASTSelection.commonAncestor();
88 Str = dyn_cast_or_null<StringLiteral>(N->ASTNode.get<Stmt>());
90 isNormalString(*Str, Inputs.Cursor, Inputs.AST->getSourceManager()) &&
91 needsRaw(Str->getBytes()) && canBeRaw(Str->getBytes());
94Expected<Tweak::Effect> RawStringLiteral::apply(
const Selection &Inputs) {
95 auto &SM = Inputs.AST->getSourceManager();
96 auto Reps = tooling::Replacements(
97 tooling::Replacement(SM, Str, (
"R\"(" + Str->getBytes() +
")\"").str(),
98 Inputs.AST->getLangOpts()));
99 return Effect::mainFileEdit(SM, std::move(Reps));
std::vector< const char * > Expected
#define REGISTER_TWEAK(Subclass)
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
static const llvm::StringLiteral REFACTOR_KIND