From 2e3642e66bfeddd3dbb9c91637059e32b444ac52 Mon Sep 17 00:00:00 2001 From: Luboš Luňák Date: Mon, 15 Oct 2012 17:34:13 +0200 Subject: convenience functions for source rewriters Change-Id: I36e2b49bc615db0b12b03ffa755fa51acc6830a0 --- compilerplugins/clang/lclstaticfix.cxx | 9 +--- compilerplugins/clang/lclstaticfix.hxx | 4 +- compilerplugins/clang/plugin.cxx | 86 ++++++++++++++++++++++++++++++++++ compilerplugins/clang/plugin.hxx | 18 +++++++ 4 files changed, 107 insertions(+), 10 deletions(-) (limited to 'compilerplugins') diff --git a/compilerplugins/clang/lclstaticfix.cxx b/compilerplugins/clang/lclstaticfix.cxx index c6b61363e134..849fea57b9e8 100644 --- a/compilerplugins/clang/lclstaticfix.cxx +++ b/compilerplugins/clang/lclstaticfix.cxx @@ -22,7 +22,7 @@ namespace loplugin { LclStaticFix::LclStaticFix( ASTContext& context, Rewriter& rewriter ) - : Plugin( context ), rewriter( rewriter ) + : RewritePlugin( context, rewriter ) { } @@ -46,12 +46,7 @@ bool LclStaticFix::VisitFunctionDecl( FunctionDecl* declaration ) return true; if( name.compare( 0, 4, "lcl_" ) != 0 ) return true; - if( rewriter.InsertText( declaration->getLocStart(), "static " )) - { // the logic is backwards, true here meant it failed, so report - report( DiagnosticsEngine::Warning, - "cannot fix lcl_ function (result of macro expansion?) [loplugin]", - declaration->getLocStart()); - } + insertText( declaration->getLocStart(), "static " ); return true; } diff --git a/compilerplugins/clang/lclstaticfix.hxx b/compilerplugins/clang/lclstaticfix.hxx index be89b4622620..fdf9d34107e7 100644 --- a/compilerplugins/clang/lclstaticfix.hxx +++ b/compilerplugins/clang/lclstaticfix.hxx @@ -18,14 +18,12 @@ namespace loplugin class LclStaticFix : public RecursiveASTVisitor< LclStaticFix > - , public Plugin + , public RewritePlugin { public: explicit LclStaticFix( ASTContext& context, Rewriter& rewriter ); void run(); bool VisitFunctionDecl( FunctionDecl* declaration ); - private: - Rewriter& rewriter; }; } // namespace diff --git a/compilerplugins/clang/plugin.cxx b/compilerplugins/clang/plugin.cxx index 115193c14137..853cf74a8526 100644 --- a/compilerplugins/clang/plugin.cxx +++ b/compilerplugins/clang/plugin.cxx @@ -52,6 +52,92 @@ bool Plugin::ignoreLocation( SourceLocation loc ) return context.getSourceManager().isInSystemHeader( context.getSourceManager().getExpansionLoc( loc )); } + +RewritePlugin::RewritePlugin( ASTContext& context, Rewriter& rewriter ) + : Plugin( context ) + , rewriter( rewriter ) + { + } + +bool RewritePlugin::insertText( SourceLocation Loc, StringRef Str, bool InsertAfter, bool indentNewLines ) + { + if( rewriter.InsertText( Loc, Str, InsertAfter, indentNewLines )) + return reportEditFailure( Loc ); + return true; + } + +bool RewritePlugin::insertTextAfter( SourceLocation Loc, StringRef Str ) + { + if( rewriter.InsertTextAfter( Loc, Str )) + return reportEditFailure( Loc ); + return true; + } + +bool RewritePlugin::insertTextAfterToken( SourceLocation Loc, StringRef Str ) + { + if( rewriter.InsertTextAfterToken( Loc, Str )) + return reportEditFailure( Loc ); + return true; + } + +bool RewritePlugin::insertTextBefore( SourceLocation Loc, StringRef Str ) + { + if( rewriter.InsertTextBefore( Loc, Str )) + return reportEditFailure( Loc ); + return true; + } + +bool RewritePlugin::removeText( SourceLocation Start, unsigned Length, RewriteOptions opts ) + { + if( rewriter.RemoveText( Start, Length, opts )) + return reportEditFailure( Start ); + return true; + } + +bool RewritePlugin::removeText( CharSourceRange range, RewriteOptions opts ) + { + if( rewriter.RemoveText( range, opts )) + return reportEditFailure( range.getBegin()); + return true; + } + +bool RewritePlugin::removeText( SourceRange range, RewriteOptions opts ) + { + if( rewriter.RemoveText( range, opts )) + return reportEditFailure( range.getBegin()); + return true; + } + +bool RewritePlugin::replaceText( SourceLocation Start, unsigned OrigLength, StringRef NewStr ) + { + if( rewriter.ReplaceText( Start, OrigLength, NewStr )) + return reportEditFailure( Start ); + return true; + } + +bool RewritePlugin::replaceText( SourceRange range, StringRef NewStr ) + { + if( rewriter.ReplaceText( range, NewStr )) + return reportEditFailure( range.getBegin()); + return true; + } + +bool RewritePlugin::replaceText( SourceRange range, SourceRange replacementRange ) + { + if( rewriter.ReplaceText( range, replacementRange )) + return reportEditFailure( range.getBegin()); + return true; + } + +bool RewritePlugin::reportEditFailure( SourceLocation loc ) + { + DiagnosticsEngine& diag = context.getDiagnostics(); + diag.Report( loc, diag.getCustomDiagID( DiagnosticsEngine::Warning, + "cannot perform source modification (macro expansion involved?) [loplugin]" )); + return false; + } + + /** Class that manages all LO modules. */ diff --git a/compilerplugins/clang/plugin.hxx b/compilerplugins/clang/plugin.hxx index 6d273eda3c3e..b8a48fa97fd1 100644 --- a/compilerplugins/clang/plugin.hxx +++ b/compilerplugins/clang/plugin.hxx @@ -39,7 +39,25 @@ class RewritePlugin public: explicit RewritePlugin( ASTContext& context, Rewriter& rewriter ); protected: + typedef Rewriter::RewriteOptions RewriteOptions; + // These following insert/remove/replaceText functions map to functions + // in clang::Rewriter, with two differences: + // - they (more intuitively) return false on failure rather than true + // - they report a warning when the change cannot be done + bool insertText( SourceLocation Loc, StringRef Str, + bool InsertAfter = true, bool indentNewLines = false ); + bool insertTextAfter( SourceLocation Loc, StringRef Str ); + bool insertTextAfterToken( SourceLocation Loc, StringRef Str ); + bool insertTextBefore( SourceLocation Loc, StringRef Str ); + bool removeText( SourceLocation Start, unsigned Length, RewriteOptions opts = RewriteOptions()); + bool removeText( CharSourceRange range, RewriteOptions opts = RewriteOptions()); + bool removeText( SourceRange range, RewriteOptions opts = RewriteOptions()); + bool replaceText( SourceLocation Start, unsigned OrigLength, StringRef NewStr ); + bool replaceText( SourceRange range, StringRef NewStr ); + bool replaceText( SourceRange range, SourceRange replacementRange ); Rewriter& rewriter; + private: + bool reportEditFailure( SourceLocation loc ); }; inline -- cgit