From: hama Date: Mon, 28 Dec 2015 23:56:58 +0000 (+0100) Subject: CFormatter: cast expr works X-Git-Url: https://gitweb.hamatoma.de/?a=commitdiff_plain;h=61ffc99ee6e41126b9fd886b33df04b891e2fdf0;p=reqt CFormatter: cast expr works --- diff --git a/appl/recform/CFormatter.cpp b/appl/recform/CFormatter.cpp index 60e1e87..10affda 100644 --- a/appl/recform/CFormatter.cpp +++ b/appl/recform/CFormatter.cpp @@ -28,13 +28,14 @@ CFormatter::CFormatter(ReProgramArgs& args, ReLogger* logger) : m_parenthLevelStack(), m_logicalLine(), m_continued(false), - m_lastDeclToken(-1), m_writer(NULL), m_logger(logger), m_tabSize(4), m_useTab(true), m_lexer(NULL), - m_parser(NULL) + m_parser(NULL), + m_countIsTypeList(1024), + m_isInTypeList(new bool[m_countIsTypeList]) { } @@ -56,6 +57,65 @@ void CFormatter::addToken(ReToken* token) m_logicalLine.push_back(FormatToken(token, m_parenthLevel)); } +/** + * Find tokens belonging to a type list: cast expressions. + * + * The position of the tokens will be marked in a boolean array. + */ +void CFormatter::findTypeLists() +{ + const FormatToken* item2; + // search for cast expressions with '*' and/or '&' and/or "[]": + // examples: (char&) (int[]) (int* const) + int count = m_logicalLine.size(); + for (int ix = count - 1; ix > 0; ix--){ + const FormatToken& item = m_logicalLine.constData()[ix]; + // at least 3 elements: '(' "int" '*' + if (item.isOperator(OP_RPARENTH) && ix >= 3){ + if ( (item2 = &m_logicalLine.constData()[ix - 1])->isOperator(OP_STAR, OP_BIT_AND) + || item2->isKeyword(K_CONST) || (item2->isOperator(OP_RBRACKET) + && m_logicalLine.constData()[ix - 2].isOperator(OP_LBRACKET))){ + // mark all tokens until the previous '(' as "in typelist": + while(ix > 0 && ! m_logicalLine.constData()[ix].isOperator(OP_LPARENTH)) + m_isInTypeList[ix--] = true; + } + } + } + // search for new expressions: + // examples: new String; new Type*[3]; new Type(1, 2); + for (int ix = 0; ix < count; ix++){ + const FormatToken& item = m_logicalLine.constData()[ix]; + if (item.isKeyword(K_NEW)){ + while(++ix < count && ((item2 = &m_logicalLine.constData()[ix]) + ->isOperator(OP_LBRACKET, OP_LPARENTH) + || item2->isOperator(OP_SEMICOLON, OP_COMMA))) + m_isInTypeList[ix] = true; + } + } + // search for template expressions: '<' types '>': + // examples: new QList + for (int ix = 0; ix < count; ix++){ + const FormatToken& item = m_logicalLine.constData()[ix]; + if (item.isOperator(OP_LT)){ + bool found = false; + for (int ix2 = ix + 1; ix2 < count; ix2++){ + item2 = &m_logicalLine.constData()[ix2]; + if (item2->isOperator(OP_AND, OP_OR)) + break; + if (item2->isOperator(OP_GT)){ + found = true; + break; + } + if (found){ + while(++ix < ix2) + m_isInTypeList[ix] = true; + ix++; + } + } + } + } +} + /** * Write the current locical line to the output media. * @@ -63,15 +123,17 @@ void CFormatter::addToken(ReToken* token) */ void CFormatter::flush(bool isPart) { + resetIsTypeList(); + findTypeLists(); if (m_logicalLine.size() > 0){ QByteArray buffer; buffer.reserve(8096); indent(m_blockLevel + m_continued ? 1 : 0, buffer); FormatToken* lastItem = &m_logicalLine.data()[0]; - buffer.append(lastItem->toString()); + m_lexer->textOfToken(lastItem, buffer); for (int ix = 1; ix < m_logicalLine.size(); ix++){ FormatToken* item = &m_logicalLine.data()[ix]; - if (needsBlank(lastItem, item, ix <= m_lastDeclToken)) + if (needsBlank(lastItem, item, m_isInTypeList[ix])) buffer.append(' '); m_lexer->textOfToken(item, buffer); lastItem = item; @@ -179,8 +241,8 @@ bool CFormatter::needsBlank(ReToken* first, ReToken* second, bool isDeclaration) if (! isDeclaration) rc = needsPrecedingBlank((CppOperator) second->id()); else { - rc = (op = (CppOperator) second->id()) != OP_STAR - && op != OP_BIT_AND && op != OP_GT && op != OP_LT; + rc = !((op = (CppOperator) second->id()) == OP_STAR + || op == OP_BIT_AND || op == OP_GT || op == OP_LT); } break; default: @@ -195,14 +257,17 @@ bool CFormatter::needsBlank(ReToken* first, ReToken* second, bool isDeclaration) case TOKEN_REAL: case TOKEN_KEYWORD: case TOKEN_ID: - rc = needsTrailingBlank((CppOperator) first->id()); + if ( (op = (CppOperator) first->id()) == OP_RPARENTH) + rc = true; + else + rc = needsTrailingBlank((CppOperator) first->id()); break; case TOKEN_OPERATOR: if (! isDeclaration) rc = needsTrailingBlank((CppOperator) first->id()) || needsPrecedingBlank((CppOperator) second->id()); else { - rc = (op = (CppOperator) second->id()) != OP_GT && op != OP_LT; + rc = false; } break; default: @@ -219,6 +284,23 @@ bool CFormatter::needsBlank(ReToken* first, ReToken* second, bool isDeclaration) return rc; } +/** + * Resets the array storing the indexes of tokens belonging to a declaration. + * + * Cast expressions also are treated as declarations. + * + * @return + */ +void CFormatter::resetIsTypeList() +{ + if (m_countIsTypeList < m_logicalLine.size()){ + delete[] m_isInTypeList; + m_countIsTypeList = max(m_logicalLine.size(), 2 * m_countIsTypeList); + m_isInTypeList = new bool[m_countIsTypeList]; + } + memset(m_isInTypeList, false, sizeof *m_isInTypeList * m_countIsTypeList); +} + /** * Tests whether an operator needs a preceding blank. * @@ -228,7 +310,7 @@ bool CFormatter::needsBlank(ReToken* first, ReToken* second, bool isDeclaration) bool CFormatter::needsPrecedingBlank(CppOperator op) { - bool rc = true; + bool rc = false; switch(op){ case OP_QUESTIONMARK: case OP_COLON: @@ -277,7 +359,7 @@ bool CFormatter::needsPrecedingBlank(CppOperator op) bool CFormatter::needsTrailingBlank(CppOperator op) { - bool rc = true; + bool rc = false; switch(op){ case OP_COMMA: case OP_QUESTIONMARK: @@ -311,6 +393,7 @@ bool CFormatter::needsTrailingBlank(CppOperator op) case OP_DIV: case OP_MOD: case OP_NOT: + rc = true; default: break; } @@ -359,7 +442,9 @@ void CFormatter::setBlockLevel(int blockLevel) */ void CFormatter::setLastDeclToken(int lastDeclToken) { - m_lastDeclToken = lastDeclToken; + int count = min(lastDeclToken, m_countIsTypeList); + if (count > 0) + memset(m_isInTypeList, ~false, count * sizeof *m_isInTypeList); } /** @@ -423,3 +508,4 @@ ReWriter* CFormatter::writer() const { return m_writer; } + diff --git a/appl/recform/CFormatter.hpp b/appl/recform/CFormatter.hpp index de993b6..e1f73d5 100644 --- a/appl/recform/CFormatter.hpp +++ b/appl/recform/CFormatter.hpp @@ -66,10 +66,12 @@ public: ReWriter* writer() const; protected: + void findTypeLists(); void indent(int level, QByteArray& buffer); bool needsPrecedingBlank(CppOperator op); bool needsTrailingBlank(CppOperator op); - bool needsBlank(ReToken* first, ReToken* second, bool isDeclaration); + bool needsBlank(ReToken* first, ReToken* second, bool isTypeList); + void resetIsTypeList(); private: ReProgramArgs& m_args; int m_blockLevel; @@ -78,14 +80,15 @@ private: QVector m_logicalLine; /// true: a part of the logical line is already written (and removed) bool m_continued; - /// index of the token which ends the declaration: - int m_lastDeclToken; ReWriter* m_writer; ReLogger* m_logger; int m_tabSize; bool m_useTab; CppLexer* m_lexer; CppParser* m_parser; + int m_countIsTypeList; + // index: position of a token in m_logicalLine. Value: token is in type list. + bool* m_isInTypeList; }; #endif // CFORMATTER_HPP diff --git a/appl/recform/cuReCFormatter.cpp b/appl/recform/cuReCFormatter.cpp index 836a9bc..03964a4 100644 --- a/appl/recform/cuReCFormatter.cpp +++ b/appl/recform/cuReCFormatter.cpp @@ -41,7 +41,14 @@ public: } void testBasic() { - const char* line = "const char* ptr = (const char*) abc(1 + 2) * 3 / 4;"; + const char* line = "(char*) abc(1 + 2);\n"; + setTokens(line); + m_writer.buffer().clear(); + m_formatter.setLastDeclToken(-1); + m_formatter.flush(true); + checkEqu(line, m_writer.buffer()); + + line = "const char* ptr = (const char*) abc(1 + 2) * 3 / 4;\n"; setTokens(line); m_writer.buffer().clear(); m_formatter.setLastDeclToken(4); @@ -78,7 +85,6 @@ public: virtual void runTests() { testBasic(); testLexer(); - } ReProgramArgs m_args; ReSource m_source; diff --git a/expr/ReSource.cpp b/expr/ReSource.cpp index 1b6a103..33c4c36 100644 --- a/expr/ReSource.cpp +++ b/expr/ReSource.cpp @@ -703,6 +703,9 @@ void ReStringReader::replaceSource(ReSourceUnitName name, ReStringSourceUnit* unit = dynamic_cast(m_units[name]); unit->m_content = content; + unit->setCurrentPosition(0); + if (source().currentReader() == NULL) + source().addReader(this); } }