2012-10-05 18:17:13 +02:00
|
|
|
/*
|
|
|
|
* This file is part of the LibreOffice project.
|
|
|
|
*
|
|
|
|
* Based on LLVM/Clang.
|
|
|
|
*
|
|
|
|
* This file is distributed under the University of Illinois Open Source
|
|
|
|
* License. See LICENSE.TXT for details.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2012-10-15 15:36:25 +02:00
|
|
|
#ifndef PLUGIN_H
|
|
|
|
#define PLUGIN_H
|
2012-10-05 18:17:13 +02:00
|
|
|
|
2013-01-06 18:09:04 +01:00
|
|
|
#include <config_clang.h>
|
|
|
|
|
2012-10-09 16:27:25 +02:00
|
|
|
#include <clang/AST/RecursiveASTVisitor.h>
|
2012-12-05 15:29:19 +01:00
|
|
|
|
|
|
|
#if __clang_major__ < 3 || __clang_major__ == 3 && __clang_minor__ < 2
|
2012-10-15 15:36:25 +02:00
|
|
|
#include <clang/Rewrite/Rewriter.h>
|
2012-12-05 15:29:19 +01:00
|
|
|
#else
|
|
|
|
#include <clang/Rewrite/Core/Rewriter.h>
|
|
|
|
#endif
|
2012-10-09 16:27:25 +02:00
|
|
|
|
|
|
|
using namespace clang;
|
2012-10-15 14:58:19 +02:00
|
|
|
using namespace llvm;
|
|
|
|
using namespace std;
|
2012-10-09 16:27:25 +02:00
|
|
|
|
|
|
|
namespace loplugin
|
|
|
|
{
|
|
|
|
|
|
|
|
class Plugin
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
explicit Plugin( ASTContext& context );
|
|
|
|
protected:
|
2012-10-13 17:38:58 +02:00
|
|
|
DiagnosticBuilder report( DiagnosticsEngine::Level level, StringRef message, SourceLocation loc = SourceLocation());
|
2012-10-09 16:39:49 +02:00
|
|
|
bool ignoreLocation( SourceLocation loc );
|
|
|
|
bool ignoreLocation( const Decl* decl );
|
|
|
|
bool ignoreLocation( const Stmt* stmt );
|
2012-10-09 16:27:25 +02:00
|
|
|
ASTContext& context;
|
|
|
|
};
|
|
|
|
|
2012-10-15 15:36:25 +02:00
|
|
|
class RewritePlugin
|
|
|
|
: public Plugin
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
explicit RewritePlugin( ASTContext& context, Rewriter& rewriter );
|
|
|
|
protected:
|
2012-12-20 23:08:52 +01:00
|
|
|
// This enum allows passing just 'RemoveLineIfEmpty' to functions below.
|
|
|
|
enum RemoveLineIfEmpty_t { RemoveLineIfEmpty };
|
|
|
|
// Use this to remove the declaration/statement as a whole, i.e. all whitespace before the statement
|
|
|
|
// and the trailing semicolor (is not part of the AST element range itself).
|
|
|
|
// The trailing semicolon must be present.
|
|
|
|
enum RemoveWholeStatement_t { RemoveWholeStatement };
|
|
|
|
enum RemoveLineIfEmptyAndWholeStatement_t { RemoveLineIfEmptyAndWholeStatement };
|
|
|
|
// syntactic sugar to be able to write 'RemoveLineIfEmpty | RemoveWholeStatement'
|
|
|
|
friend RemoveLineIfEmptyAndWholeStatement_t operator|( RemoveLineIfEmpty_t, RemoveWholeStatement_t )
|
|
|
|
{ return RemoveLineIfEmptyAndWholeStatement; }
|
|
|
|
struct RewriteOptions
|
|
|
|
: public Rewriter::RewriteOptions
|
|
|
|
{
|
|
|
|
RewriteOptions() : RemoveWholeStatement( false ) {} // default
|
|
|
|
RewriteOptions( RemoveLineIfEmpty_t ) : RemoveWholeStatement( false ) { RemoveLineIfEmpty = true; }
|
|
|
|
RewriteOptions( RemoveWholeStatement_t ) : RemoveWholeStatement( true ) {}
|
|
|
|
RewriteOptions( RemoveLineIfEmptyAndWholeStatement_t ) : RemoveWholeStatement( true ) { RemoveLineIfEmpty = true; }
|
|
|
|
bool RemoveWholeStatement;
|
|
|
|
};
|
2012-10-15 17:34:13 +02:00
|
|
|
// These following insert/remove/replaceText functions map to functions
|
2012-12-20 23:08:52 +01:00
|
|
|
// in clang::Rewriter, with these differences:
|
2012-10-15 17:34:13 +02:00
|
|
|
// - they (more intuitively) return false on failure rather than true
|
|
|
|
// - they report a warning when the change cannot be done
|
2012-12-20 23:08:52 +01:00
|
|
|
// - There is RemoveWholeStatement to also remove the trailing semicolon when removing (must be there)
|
|
|
|
// and al preceding whitespace.
|
2012-10-15 17:34:13 +02:00
|
|
|
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());
|
2012-12-20 23:08:52 +01:00
|
|
|
// CharSourceRange not supported, unless really needed, as it makes RemoveSemicolon more complicated
|
|
|
|
//bool removeText( CharSourceRange range, RewriteOptions opts = RewriteOptions());
|
2012-10-15 17:34:13 +02:00
|
|
|
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 );
|
2012-10-15 15:36:25 +02:00
|
|
|
Rewriter& rewriter;
|
2012-10-15 17:34:13 +02:00
|
|
|
private:
|
|
|
|
bool reportEditFailure( SourceLocation loc );
|
2012-12-20 23:08:52 +01:00
|
|
|
bool adjustForWholeStatement( SourceRange* range );
|
2012-10-15 15:36:25 +02:00
|
|
|
};
|
|
|
|
|
2012-10-09 16:39:49 +02:00
|
|
|
inline
|
|
|
|
bool Plugin::ignoreLocation( const Decl* decl )
|
|
|
|
{
|
2012-10-12 15:34:14 +02:00
|
|
|
return ignoreLocation( decl->getLocation());
|
2012-10-09 16:39:49 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
inline
|
|
|
|
bool Plugin::ignoreLocation( const Stmt* stmt )
|
|
|
|
{
|
|
|
|
return ignoreLocation( stmt->getLocStart());
|
|
|
|
}
|
|
|
|
|
2012-10-09 16:27:25 +02:00
|
|
|
} // namespace
|
|
|
|
|
2012-10-05 18:17:13 +02:00
|
|
|
#endif // COMPILEPLUGIN_H
|