]> gitweb.hamatoma.de Git - reqt/commitdiff
CFormatter: cast expr works
authorhama <hama@siduction.net>
Mon, 28 Dec 2015 23:56:58 +0000 (00:56 +0100)
committerhama <hama@siduction.net>
Mon, 28 Dec 2015 23:56:58 +0000 (00:56 +0100)
appl/recform/CFormatter.cpp
appl/recform/CFormatter.hpp
appl/recform/cuReCFormatter.cpp
expr/ReSource.cpp

index 60e1e87e90f252c36740a574186116e383f4adee..10affda5d2213a6275658e080453cde14d65855d 100644 (file)
@@ -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<abc>
+       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;
 }
+
index de993b6553964f9800e24f61636f64a9ec9ddc88..e1f73d5d774bab44e72348686080a7a0ab8019a8 100644 (file)
@@ -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<FormatToken> 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
index 836a9bcab2ce7a683090089adeecc7ea7992af23..03964a4cc12adb85bcfaeca31d5d0670a6ab234b 100644 (file)
@@ -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;
index 1b6a103055ad7fb0a246c9fc6f52e774e237aaf2..33c4c360958bd2e689c9ef8aac6d5c76e1cee71d 100644 (file)
@@ -703,6 +703,9 @@ void ReStringReader::replaceSource(ReSourceUnitName name,
                ReStringSourceUnit* unit =
                        dynamic_cast<ReStringSourceUnit*>(m_units[name]);
                unit->m_content = content;
+               unit->setCurrentPosition(0);
+               if (source().currentReader() == NULL)
+                       source().addReader(this);
        }
 }