summaryrefslogtreecommitdiff
path: root/src/plugins/cpptools/cppcodeformatter.h
diff options
context:
space:
mode:
authorChristian Kamm <christian.d.kamm@nokia.com>2010-07-02 15:43:34 +0200
committerChristian Kamm <christian.d.kamm@nokia.com>2010-07-02 16:13:12 +0200
commit88f2e340bd1144ee198e8f285b07aac42621c37b (patch)
tree2c292762319706db08851512904bea8ab5bc80cf /src/plugins/cpptools/cppcodeformatter.h
parent837e7b5abd3c18e1fb63d36c1630243172a28f90 (diff)
downloadqt-creator-88f2e340bd1144ee198e8f285b07aac42621c37b.tar.gz
C++: Introduce the new CodeFormatter.
Done-with: Erik Verbruggen
Diffstat (limited to 'src/plugins/cpptools/cppcodeformatter.h')
-rw-r--r--src/plugins/cpptools/cppcodeformatter.h195
1 files changed, 195 insertions, 0 deletions
diff --git a/src/plugins/cpptools/cppcodeformatter.h b/src/plugins/cpptools/cppcodeformatter.h
new file mode 100644
index 0000000000..051b5f2aac
--- /dev/null
+++ b/src/plugins/cpptools/cppcodeformatter.h
@@ -0,0 +1,195 @@
+#ifndef CPPCODEFORMATTER_H
+#define CPPCODEFORMATTER_H
+
+#include "cpptools_global.h"
+
+#include <cplusplus/SimpleLexer.h>
+#include <Token.h>
+
+#include <QtCore/QChar>
+#include <QtCore/QStack>
+#include <QtCore/QList>
+#include <QtCore/QVector>
+#include <QtCore/QPointer>
+
+QT_BEGIN_NAMESPACE
+class QTextDocument;
+class QTextBlock;
+QT_END_NAMESPACE
+
+namespace CppTools {
+namespace Internal {
+class CppCodeFormatterData;
+}
+
+class CPPTOOLS_EXPORT CodeFormatter
+{
+public:
+ CodeFormatter();
+ virtual ~CodeFormatter();
+
+ void setDocument(QTextDocument *document);
+
+ int indentFor(const QTextBlock &block);
+
+protected:
+ virtual void onEnter(int newState, int *indentDepth, int *savedIndentDepth) const = 0;
+ virtual void adjustIndent(const QList<CPlusPlus::Token> &tokens, int lexerState, int *indentDepth) const = 0;
+
+protected:
+ enum StateType {
+ invalid = 0,
+
+ topmost_intro, // The first line in a "topmost" definition.
+
+ multiline_comment_start, // Inside the first line of a multi-line C style block comment.
+ multiline_comment_cont, // Inside the following lines of a multi-line C style block comment.
+ cpp_macro_start, // After the '#' token
+ cpp_macro, // The start of a C preprocessor macro definition.
+ cpp_macro_cont, // Subsequent lines of a multi-line C preprocessor macro definition.
+ cpp_macro_conditional, // Special marker used for separating saved from current state when dealing with #ifdef
+ qt_like_macro, // after an identifier starting with Q_ or QT_ at the beginning of the line
+
+ defun_open, // Brace that opens a top-level function definition.
+ using_start, // right after the "using" token
+
+ class_start, // after the 'class' token
+ class_open, // Brace that opens a class definition.
+ member_init_open, // After ':' that starts a member initialization list.
+
+ enum_start, // After 'enum'
+ brace_list_open, // Open brace of an enum or static array list.
+
+ namespace_start, // after the namespace token, before the opening brace.
+ namespace_open, // Brace that opens a C++ namespace block.
+
+ declaration_start, // shifted a token which could start a declaration.
+ operator_declaration, // after 'operator' in declaration_start
+
+ template_start, // after the 'template' token
+ template_param, // after the '<' in a template_start
+
+ if_statement, // After 'if'
+ maybe_else, // after the first substatement in an if
+ else_clause, // The else line of an if-else construct.
+
+ for_statement, // After the 'for' token
+ for_statement_paren_open, // While inside the (...)
+ for_statement_init, // The initializer part of the for statement
+ for_statement_condition, // The condition part of the for statement
+ for_statement_expression, // The expression part of the for statement
+
+ switch_statement, // After 'switch' token
+ case_start, // after a 'case' or 'default' token
+ case_cont, // after the colon in a case/default
+
+ statement_with_condition, // A statement that takes a condition after the start token.
+ do_statement, // After 'do' token
+ return_statement, // After 'return'
+ block_open, // Statement block open brace.
+
+ substatement, // The first line after a conditional or loop construct.
+ substatement_open, // The brace that opens a substatement block.
+
+ arglist_open, // after the lparen. TODO: check if this is enough.
+ stream_op, // Lines continuing a stream operator (C++ only).
+ ternary_op, // The ? : operator
+
+ condition_open, // Start of a condition in 'if', 'while', entered after opening paren
+ condition_paren_open, // After an lparen in a condition
+
+ assign_open, // after an assignment token
+
+ expression, // after a '=' in a declaration_start once we're sure it's not '= {'
+ initializer, // after a '=' in a declaration start
+ };
+
+ struct State {
+ State()
+ : savedIndentDepth(0)
+ , type(0)
+ {}
+
+ State(quint8 ty, quint16 savedDepth)
+ : savedIndentDepth(savedDepth)
+ , type(ty)
+ {}
+
+ quint16 savedIndentDepth;
+ quint8 type;
+
+ bool operator==(const State &other) const {
+ return type == other.type
+ && savedIndentDepth == other.savedIndentDepth;
+ }
+ };
+
+ State state(int belowTop = 0) const;
+ int tokenIndex() const;
+ int tokenIndexFromEnd() const;
+ const CPlusPlus::Token &currentToken() const;
+ const CPlusPlus::Token &tokenAt(int idx) const;
+
+ bool isBracelessState(int type) const;
+
+ void invalidateCache();
+
+private:
+ void requireStatesUntil(const QTextBlock &block);
+ void recalculateStateAfter(const QTextBlock &block);
+ void storeBlockState(const QTextBlock &block);
+ void restoreBlockState(const QTextBlock &block);
+
+ QStringRef currentTokenText() const;
+
+ int tokenizeBlock(const QTextBlock &block, bool *endedJoined = 0);
+
+ void turnInto(int newState);
+
+ bool tryExpression(bool alsoExpression = false);
+ bool tryDeclaration();
+ bool tryStatement();
+
+ void enter(int newState);
+ void leave(bool statementDone = false);
+ void correctIndentation(const QTextBlock &block);
+
+ void dump();
+
+private:
+ static QStack<State> initialState();
+
+ QPointer<QTextDocument> m_document;
+
+ QStack<State> m_beginState;
+ QStack<State> m_currentState;
+
+ QList<CPlusPlus::Token> m_tokens;
+ QString m_currentLine;
+ CPlusPlus::Token m_currentToken;
+ int m_tokenIndex;
+
+ // should store indent level and padding instead
+ int m_indentDepth;
+
+ friend class Internal::CppCodeFormatterData;
+};
+
+class CPPTOOLS_EXPORT QtStyleCodeFormatter : public CodeFormatter
+{
+public:
+ QtStyleCodeFormatter();
+
+ void setIndentSize(int size);
+
+protected:
+ virtual void onEnter(int newState, int *indentDepth, int *savedIndentDepth) const;
+ virtual void adjustIndent(const QList<CPlusPlus::Token> &tokens, int lexerState, int *indentDepth) const;
+
+private:
+ int m_indentSize;
+};
+
+} // namespace CppTools
+
+#endif // CPPCODEFORMATTER_H