| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  | /**************************************************************************
 | 
					
						
							|  |  |  | ** | 
					
						
							|  |  |  | ** This file is part of Qt Creator | 
					
						
							|  |  |  | ** | 
					
						
							| 
									
										
										
										
											2011-01-11 16:28:15 +01:00
										 |  |  | ** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies). | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  | ** | 
					
						
							| 
									
										
										
										
											2011-11-02 15:59:12 +01:00
										 |  |  | ** Contact: Nokia Corporation (qt-info@nokia.com) | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  | ** | 
					
						
							|  |  |  | ** | 
					
						
							|  |  |  | ** GNU Lesser General Public License Usage | 
					
						
							|  |  |  | ** | 
					
						
							| 
									
										
										
										
											2011-04-13 08:42:33 +02:00
										 |  |  | ** This file may be used under the terms of the GNU Lesser General Public | 
					
						
							|  |  |  | ** License version 2.1 as published by the Free Software Foundation and | 
					
						
							|  |  |  | ** appearing in the file LICENSE.LGPL included in the packaging of this file. | 
					
						
							|  |  |  | ** Please review the following information to ensure the GNU Lesser General | 
					
						
							|  |  |  | ** Public License version 2.1 requirements will be met: | 
					
						
							|  |  |  | ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
 | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  | ** | 
					
						
							| 
									
										
										
										
											2010-12-17 16:01:08 +01:00
										 |  |  | ** In addition, as a special exception, Nokia gives you certain additional | 
					
						
							| 
									
										
										
										
											2011-04-13 08:42:33 +02:00
										 |  |  | ** rights. These rights are described in the Nokia Qt LGPL Exception | 
					
						
							| 
									
										
										
										
											2010-12-17 16:01:08 +01:00
										 |  |  | ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. | 
					
						
							|  |  |  | ** | 
					
						
							| 
									
										
										
										
											2011-04-13 08:42:33 +02:00
										 |  |  | ** Other Usage | 
					
						
							|  |  |  | ** | 
					
						
							|  |  |  | ** Alternatively, this file may be used in accordance with the terms and | 
					
						
							|  |  |  | ** conditions contained in a signed written agreement between you and Nokia. | 
					
						
							|  |  |  | ** | 
					
						
							| 
									
										
										
										
											2010-12-17 16:01:08 +01:00
										 |  |  | ** If you have questions regarding the use of this file, please contact | 
					
						
							| 
									
										
										
										
											2011-11-02 15:59:12 +01:00
										 |  |  | ** Nokia at qt-info@nokia.com. | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  | ** | 
					
						
							|  |  |  | **************************************************************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-11-18 14:32:42 +01:00
										 |  |  | #include "cppcompleteswitch.h"
 | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  | #include "cppeditor.h"
 | 
					
						
							|  |  |  | #include "cppquickfix.h"
 | 
					
						
							| 
									
										
										
										
											2010-09-02 15:17:57 +02:00
										 |  |  | #include "cppinsertdecldef.h"
 | 
					
						
							| 
									
										
										
										
											2010-12-10 15:42:34 +01:00
										 |  |  | #include "cppinsertqtpropertymembers.h"
 | 
					
						
							| 
									
										
										
										
											2011-04-15 16:19:23 +02:00
										 |  |  | #include "cppquickfixassistant.h"
 | 
					
						
							|  |  |  | #include "cppcompleteswitch.h"
 | 
					
						
							| 
									
										
										
										
											2011-09-05 10:33:17 +02:00
										 |  |  | #include "cppfunctiondecldeflink.h"
 | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include <ASTVisitor.h>
 | 
					
						
							|  |  |  | #include <AST.h>
 | 
					
						
							|  |  |  | #include <ASTMatcher.h>
 | 
					
						
							|  |  |  | #include <ASTPatternBuilder.h>
 | 
					
						
							|  |  |  | #include <CoreTypes.h>
 | 
					
						
							|  |  |  | #include <Literals.h>
 | 
					
						
							|  |  |  | #include <Name.h>
 | 
					
						
							|  |  |  | #include <Names.h>
 | 
					
						
							|  |  |  | #include <Symbol.h>
 | 
					
						
							|  |  |  | #include <Symbols.h>
 | 
					
						
							|  |  |  | #include <Token.h>
 | 
					
						
							|  |  |  | #include <TranslationUnit.h>
 | 
					
						
							|  |  |  | #include <Type.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <cplusplus/DependencyTable.h>
 | 
					
						
							|  |  |  | #include <cplusplus/Overview.h>
 | 
					
						
							|  |  |  | #include <cplusplus/TypeOfExpression.h>
 | 
					
						
							| 
									
										
										
										
											2011-11-25 12:05:58 +01:00
										 |  |  | #include <cplusplus/ModelManagerInterface.h>
 | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  | #include <cplusplus/CppRewriter.h>
 | 
					
						
							|  |  |  | #include <cpptools/cpptoolsconstants.h>
 | 
					
						
							| 
									
										
										
										
											2010-11-01 17:04:48 +01:00
										 |  |  | #include <cpptools/cpprefactoringchanges.h>
 | 
					
						
							| 
									
										
										
										
											2010-12-10 15:42:34 +01:00
										 |  |  | #include <cpptools/insertionpointlocator.h>
 | 
					
						
							| 
									
										
										
										
											2011-10-12 13:47:35 +02:00
										 |  |  | #include <cpptools/cpptoolsreuse.h>
 | 
					
						
							| 
									
										
										
										
											2011-11-25 12:05:58 +01:00
										 |  |  | #include <cpptools/cppclassesfilter.h>
 | 
					
						
							|  |  |  | #include <cpptools/searchsymbols.h>
 | 
					
						
							| 
									
										
										
										
											2012-01-20 14:43:21 +01:00
										 |  |  | #include <cpptools/symbolfinder.h>
 | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  | #include <extensionsystem/iplugin.h>
 | 
					
						
							| 
									
										
										
										
											2011-11-25 12:05:58 +01:00
										 |  |  | #include <extensionsystem/pluginmanager.h>
 | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-14 14:23:25 +01:00
										 |  |  | #include <utils/qtcassert.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-20 14:03:07 +01:00
										 |  |  | #include <QtCore/QFileInfo>
 | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  | #include <QtGui/QApplication>
 | 
					
						
							|  |  |  | #include <QtGui/QTextBlock>
 | 
					
						
							|  |  |  | #include <QtGui/QTextCursor>
 | 
					
						
							| 
									
										
										
										
											2011-10-25 14:06:39 +02:00
										 |  |  | #include <cctype>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  | using namespace CppEditor; | 
					
						
							|  |  |  | using namespace CppEditor::Internal; | 
					
						
							| 
									
										
										
										
											2010-09-30 12:09:38 +02:00
										 |  |  | using namespace CppTools; | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  | using namespace TextEditor; | 
					
						
							|  |  |  | using namespace CPlusPlus; | 
					
						
							|  |  |  | using namespace Utils; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-30 10:45:11 +02:00
										 |  |  | static inline bool isQtStringLiteral(const QByteArray &id) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return id == "QLatin1String" || id == "QLatin1Literal" || id == "QStringLiteral"; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-14 14:23:25 +01:00
										 |  |  | static inline bool isQtStringTranslation(const QByteArray &id) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return id == "tr" || id == "trUtf8" || id == "translate" || id == "QT_TRANSLATE_NOOP"; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  | namespace { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |     Rewrite | 
					
						
							|  |  |  |     a op b -> !(a invop b) | 
					
						
							|  |  |  |     (a op b) -> !(a invop b) | 
					
						
							|  |  |  |     !(a op b) -> (a invob b) | 
					
						
							| 
									
										
										
										
											2011-01-07 16:55:34 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     Activates on: <= < > >= == != | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  | */ | 
					
						
							|  |  |  | class UseInverseOp: public CppQuickFixFactory | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | public: | 
					
						
							| 
									
										
										
										
											2011-04-15 16:19:23 +02:00
										 |  |  |     virtual QList<CppQuickFixOperation::Ptr> match(const QSharedPointer<const CppQuickFixAssistInterface> &interface) | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |     { | 
					
						
							|  |  |  |         QList<CppQuickFixOperation::Ptr> result; | 
					
						
							| 
									
										
										
										
											2011-08-17 11:35:57 +02:00
										 |  |  |         CppRefactoringFilePtr file = interface->currentFile(); | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-15 16:19:23 +02:00
										 |  |  |         const QList<AST *> &path = interface->path(); | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |         int index = path.size() - 1; | 
					
						
							|  |  |  |         BinaryExpressionAST *binary = path.at(index)->asBinaryExpression(); | 
					
						
							|  |  |  |         if (! binary) | 
					
						
							|  |  |  |             return result; | 
					
						
							| 
									
										
										
										
											2011-04-15 16:19:23 +02:00
										 |  |  |         if (! interface->isCursorOn(binary->binary_op_token)) | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |             return result; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         Kind invertToken; | 
					
						
							| 
									
										
										
										
											2011-08-17 11:35:57 +02:00
										 |  |  |         switch (file->tokenAt(binary->binary_op_token).kind()) { | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |         case T_LESS_EQUAL: | 
					
						
							|  |  |  |             invertToken = T_GREATER; | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         case T_LESS: | 
					
						
							|  |  |  |             invertToken = T_GREATER_EQUAL; | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         case T_GREATER: | 
					
						
							|  |  |  |             invertToken = T_LESS_EQUAL; | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         case T_GREATER_EQUAL: | 
					
						
							|  |  |  |             invertToken = T_LESS; | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         case T_EQUAL_EQUAL: | 
					
						
							|  |  |  |             invertToken = T_EXCLAIM_EQUAL; | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         case T_EXCLAIM_EQUAL: | 
					
						
							|  |  |  |             invertToken = T_EQUAL_EQUAL; | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         default: | 
					
						
							|  |  |  |             return result; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-15 16:19:23 +02:00
										 |  |  |         result.append(CppQuickFixOperation::Ptr(new Operation(interface, index, binary, invertToken))); | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |         return result; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | private: | 
					
						
							|  |  |  |     class Operation: public CppQuickFixOperation | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         BinaryExpressionAST *binary; | 
					
						
							|  |  |  |         NestedExpressionAST *nested; | 
					
						
							|  |  |  |         UnaryExpressionAST *negation; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         QString replacement; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     public: | 
					
						
							| 
									
										
										
										
											2011-04-15 16:19:23 +02:00
										 |  |  |         Operation(const QSharedPointer<const CppQuickFixAssistInterface> &interface, | 
					
						
							|  |  |  |             int priority, BinaryExpressionAST *binary, Kind invertToken) | 
					
						
							|  |  |  |             : CppQuickFixOperation(interface, priority) | 
					
						
							| 
									
										
										
										
											2011-05-11 14:41:38 +02:00
										 |  |  |             , binary(binary), nested(0), negation(0) | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |         { | 
					
						
							|  |  |  |             Token tok; | 
					
						
							|  |  |  |             tok.f.kind = invertToken; | 
					
						
							|  |  |  |             replacement = QLatin1String(tok.spell()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             // check for enclosing nested expression
 | 
					
						
							|  |  |  |             if (priority - 1 >= 0) | 
					
						
							| 
									
										
										
										
											2011-04-15 16:19:23 +02:00
										 |  |  |                 nested = interface->path()[priority - 1]->asNestedExpression(); | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |             // check for ! before parentheses
 | 
					
						
							|  |  |  |             if (nested && priority - 2 >= 0) { | 
					
						
							| 
									
										
										
										
											2011-04-15 16:19:23 +02:00
										 |  |  |                 negation = interface->path()[priority - 2]->asUnaryExpression(); | 
					
						
							| 
									
										
										
										
											2011-08-17 11:35:57 +02:00
										 |  |  |                 if (negation && ! interface->currentFile()->tokenAt(negation->unary_op_token).is(T_EXCLAIM)) | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |                     negation = 0; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         virtual QString description() const | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             return QApplication::translate("CppTools::QuickFix", "Rewrite Using %1").arg(replacement); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-17 11:35:57 +02:00
										 |  |  |         virtual void performChanges(const CppRefactoringFilePtr ¤tFile, const CppRefactoringChanges &) | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |         { | 
					
						
							|  |  |  |             ChangeSet changes; | 
					
						
							|  |  |  |             if (negation) { | 
					
						
							|  |  |  |                 // can't remove parentheses since that might break precedence
 | 
					
						
							| 
									
										
										
										
											2010-08-13 12:49:11 +02:00
										 |  |  |                 changes.remove(currentFile->range(negation->unary_op_token)); | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |             } else if (nested) { | 
					
						
							| 
									
										
										
										
											2012-01-11 14:26:09 +01:00
										 |  |  |                 changes.insert(currentFile->startOf(nested), QLatin1String("!")); | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |             } else { | 
					
						
							| 
									
										
										
										
											2012-01-11 14:26:09 +01:00
										 |  |  |                 changes.insert(currentFile->startOf(binary), QLatin1String("!(")); | 
					
						
							|  |  |  |                 changes.insert(currentFile->endOf(binary), QLatin1String(")")); | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2010-08-13 12:49:11 +02:00
										 |  |  |             changes.replace(currentFile->range(binary->binary_op_token), replacement); | 
					
						
							| 
									
										
										
										
											2011-08-17 11:35:57 +02:00
										 |  |  |             currentFile->setChangeSet(changes); | 
					
						
							|  |  |  |             currentFile->apply(); | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |         } | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |     Rewrite | 
					
						
							|  |  |  |     a op b | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     As | 
					
						
							|  |  |  |     b flipop a | 
					
						
							| 
									
										
										
										
											2011-01-07 16:55:34 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     Activates on: <= < > >= == != && || | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  | */ | 
					
						
							|  |  |  | class FlipBinaryOp: public CppQuickFixFactory | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | public: | 
					
						
							| 
									
										
										
										
											2011-04-15 16:19:23 +02:00
										 |  |  |     virtual QList<QuickFixOperation::Ptr> match(const QSharedPointer<const CppQuickFixAssistInterface> &interface) | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |     { | 
					
						
							|  |  |  |         QList<QuickFixOperation::Ptr> result; | 
					
						
							| 
									
										
										
										
											2011-04-15 16:19:23 +02:00
										 |  |  |         const QList<AST *> &path = interface->path(); | 
					
						
							| 
									
										
										
										
											2011-08-17 11:35:57 +02:00
										 |  |  |         CppRefactoringFilePtr file = interface->currentFile(); | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         int index = path.size() - 1; | 
					
						
							|  |  |  |         BinaryExpressionAST *binary = path.at(index)->asBinaryExpression(); | 
					
						
							|  |  |  |         if (! binary) | 
					
						
							|  |  |  |             return result; | 
					
						
							| 
									
										
										
										
											2011-04-15 16:19:23 +02:00
										 |  |  |         if (! interface->isCursorOn(binary->binary_op_token)) | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |             return result; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         Kind flipToken; | 
					
						
							| 
									
										
										
										
											2011-08-17 11:35:57 +02:00
										 |  |  |         switch (file->tokenAt(binary->binary_op_token).kind()) { | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |         case T_LESS_EQUAL: | 
					
						
							|  |  |  |             flipToken = T_GREATER_EQUAL; | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         case T_LESS: | 
					
						
							|  |  |  |             flipToken = T_GREATER; | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         case T_GREATER: | 
					
						
							|  |  |  |             flipToken = T_LESS; | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         case T_GREATER_EQUAL: | 
					
						
							|  |  |  |             flipToken = T_LESS_EQUAL; | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         case T_EQUAL_EQUAL: | 
					
						
							|  |  |  |         case T_EXCLAIM_EQUAL: | 
					
						
							|  |  |  |         case T_AMPER_AMPER: | 
					
						
							|  |  |  |         case T_PIPE_PIPE: | 
					
						
							|  |  |  |             flipToken = T_EOF_SYMBOL; | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         default: | 
					
						
							|  |  |  |             return result; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         QString replacement; | 
					
						
							|  |  |  |         if (flipToken != T_EOF_SYMBOL) { | 
					
						
							|  |  |  |             Token tok; | 
					
						
							|  |  |  |             tok.f.kind = flipToken; | 
					
						
							|  |  |  |             replacement = QLatin1String(tok.spell()); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-15 16:19:23 +02:00
										 |  |  |         result.append(QuickFixOperation::Ptr(new Operation(interface, index, binary, replacement))); | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |         return result; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | private: | 
					
						
							|  |  |  |     class Operation: public CppQuickFixOperation | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |     public: | 
					
						
							| 
									
										
										
										
											2011-04-15 16:19:23 +02:00
										 |  |  |         Operation(const QSharedPointer<const CppQuickFixAssistInterface> &interface, | 
					
						
							|  |  |  |                   int priority, BinaryExpressionAST *binary, QString replacement) | 
					
						
							|  |  |  |             : CppQuickFixOperation(interface) | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |             , binary(binary) | 
					
						
							|  |  |  |             , replacement(replacement) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             setPriority(priority); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         virtual QString description() const | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             if (replacement.isEmpty()) | 
					
						
							|  |  |  |                 return QApplication::translate("CppTools::QuickFix", "Swap Operands"); | 
					
						
							|  |  |  |             else | 
					
						
							|  |  |  |                 return QApplication::translate("CppTools::QuickFix", "Rewrite Using %1").arg(replacement); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-17 11:35:57 +02:00
										 |  |  |         virtual void performChanges(const CppRefactoringFilePtr ¤tFile, const CppRefactoringChanges &) | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |         { | 
					
						
							|  |  |  |             ChangeSet changes; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-13 12:49:11 +02:00
										 |  |  |             changes.flip(currentFile->range(binary->left_expression), currentFile->range(binary->right_expression)); | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |             if (! replacement.isEmpty()) | 
					
						
							| 
									
										
										
										
											2010-08-13 12:49:11 +02:00
										 |  |  |                 changes.replace(currentFile->range(binary->binary_op_token), replacement); | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-17 11:35:57 +02:00
										 |  |  |             currentFile->setChangeSet(changes); | 
					
						
							|  |  |  |             currentFile->apply(); | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     private: | 
					
						
							|  |  |  |         BinaryExpressionAST *binary; | 
					
						
							|  |  |  |         QString replacement; | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |     Rewrite | 
					
						
							|  |  |  |     !a && !b | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     As | 
					
						
							|  |  |  |     !(a || b) | 
					
						
							| 
									
										
										
										
											2011-01-07 16:55:34 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     Activates on: && | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  | */ | 
					
						
							|  |  |  | class RewriteLogicalAndOp: public CppQuickFixFactory | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | public: | 
					
						
							| 
									
										
										
										
											2011-04-15 16:19:23 +02:00
										 |  |  |     virtual QList<QuickFixOperation::Ptr> match(const QSharedPointer<const CppQuickFixAssistInterface> &interface) | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |     { | 
					
						
							|  |  |  |         QList<QuickFixOperation::Ptr> result; | 
					
						
							|  |  |  |         BinaryExpressionAST *expression = 0; | 
					
						
							| 
									
										
										
										
											2011-04-15 16:19:23 +02:00
										 |  |  |         const QList<AST *> &path = interface->path(); | 
					
						
							| 
									
										
										
										
											2011-08-17 11:35:57 +02:00
										 |  |  |         CppRefactoringFilePtr file = interface->currentFile(); | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         int index = path.size() - 1; | 
					
						
							|  |  |  |         for (; index != -1; --index) { | 
					
						
							|  |  |  |             expression = path.at(index)->asBinaryExpression(); | 
					
						
							|  |  |  |             if (expression) | 
					
						
							|  |  |  |                 break; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (! expression) | 
					
						
							|  |  |  |             return result; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-15 16:19:23 +02:00
										 |  |  |         if (! interface->isCursorOn(expression->binary_op_token)) | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |             return result; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-15 16:19:23 +02:00
										 |  |  |         QSharedPointer<Operation> op(new Operation(interface)); | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if (expression->match(op->pattern, &matcher) && | 
					
						
							| 
									
										
										
										
											2011-08-17 11:35:57 +02:00
										 |  |  |                 file->tokenAt(op->pattern->binary_op_token).is(T_AMPER_AMPER) && | 
					
						
							|  |  |  |                 file->tokenAt(op->left->unary_op_token).is(T_EXCLAIM) && | 
					
						
							|  |  |  |                 file->tokenAt(op->right->unary_op_token).is(T_EXCLAIM)) { | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |             op->setDescription(QApplication::translate("CppTools::QuickFix", "Rewrite Condition Using ||")); | 
					
						
							|  |  |  |             op->setPriority(index); | 
					
						
							|  |  |  |             result.append(op); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return result; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | private: | 
					
						
							|  |  |  |     class Operation: public CppQuickFixOperation | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |     public: | 
					
						
							|  |  |  |         QSharedPointer<ASTPatternBuilder> mk; | 
					
						
							|  |  |  |         UnaryExpressionAST *left; | 
					
						
							|  |  |  |         UnaryExpressionAST *right; | 
					
						
							|  |  |  |         BinaryExpressionAST *pattern; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-15 16:19:23 +02:00
										 |  |  |         Operation(const QSharedPointer<const CppQuickFixAssistInterface> &interface) | 
					
						
							|  |  |  |             : CppQuickFixOperation(interface) | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |             , mk(new ASTPatternBuilder) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             left = mk->UnaryExpression(); | 
					
						
							|  |  |  |             right = mk->UnaryExpression(); | 
					
						
							|  |  |  |             pattern = mk->BinaryExpression(left, right); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-17 11:35:57 +02:00
										 |  |  |         virtual void performChanges(const CppRefactoringFilePtr ¤tFile, const CppRefactoringChanges &) | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |         { | 
					
						
							|  |  |  |             ChangeSet changes; | 
					
						
							| 
									
										
										
										
											2010-08-13 12:49:11 +02:00
										 |  |  |             changes.replace(currentFile->range(pattern->binary_op_token), QLatin1String("||")); | 
					
						
							|  |  |  |             changes.remove(currentFile->range(left->unary_op_token)); | 
					
						
							|  |  |  |             changes.remove(currentFile->range(right->unary_op_token)); | 
					
						
							|  |  |  |             const int start = currentFile->startOf(pattern); | 
					
						
							|  |  |  |             const int end = currentFile->endOf(pattern); | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |             changes.insert(start, QLatin1String("!(")); | 
					
						
							|  |  |  |             changes.insert(end, QLatin1String(")")); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-17 11:35:57 +02:00
										 |  |  |             currentFile->setChangeSet(changes); | 
					
						
							|  |  |  |             currentFile->appendIndentRange(currentFile->range(pattern)); | 
					
						
							|  |  |  |             currentFile->apply(); | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |         } | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | private: | 
					
						
							|  |  |  |     ASTMatcher matcher; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-07 14:49:00 +01:00
										 |  |  | /*
 | 
					
						
							|  |  |  |     Rewrite | 
					
						
							|  |  |  |     int *a, b; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     As | 
					
						
							|  |  |  |     int *a; | 
					
						
							|  |  |  |     int b; | 
					
						
							| 
									
										
										
										
											2011-01-07 16:55:34 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     Activates on: the type or the variable names. | 
					
						
							| 
									
										
										
										
											2011-01-07 14:49:00 +01:00
										 |  |  | */ | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  | class SplitSimpleDeclarationOp: public CppQuickFixFactory | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     static bool checkDeclaration(SimpleDeclarationAST *declaration) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         if (! declaration->semicolon_token) | 
					
						
							|  |  |  |             return false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (! declaration->decl_specifier_list) | 
					
						
							|  |  |  |             return false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for (SpecifierListAST *it = declaration->decl_specifier_list; it; it = it->next) { | 
					
						
							|  |  |  |             SpecifierAST *specifier = it->value; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (specifier->asEnumSpecifier() != 0) | 
					
						
							|  |  |  |                 return false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             else if (specifier->asClassSpecifier() != 0) | 
					
						
							|  |  |  |                 return false; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (! declaration->declarator_list) | 
					
						
							|  |  |  |             return false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         else if (! declaration->declarator_list->next) | 
					
						
							|  |  |  |             return false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | public: | 
					
						
							| 
									
										
										
										
											2011-04-15 16:19:23 +02:00
										 |  |  |     virtual QList<CppQuickFixOperation::Ptr> match(const QSharedPointer<const CppQuickFixAssistInterface> &interface) | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |     { | 
					
						
							|  |  |  |         QList<CppQuickFixOperation::Ptr> result; | 
					
						
							|  |  |  |         CoreDeclaratorAST *core_declarator = 0; | 
					
						
							| 
									
										
										
										
											2011-04-15 16:19:23 +02:00
										 |  |  |         const QList<AST *> &path = interface->path(); | 
					
						
							| 
									
										
										
										
											2011-08-17 11:35:57 +02:00
										 |  |  |         CppRefactoringFilePtr file = interface->currentFile(); | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         for (int index = path.size() - 1; index != -1; --index) { | 
					
						
							|  |  |  |             AST *node = path.at(index); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (CoreDeclaratorAST *coreDecl = node->asCoreDeclarator()) | 
					
						
							|  |  |  |                 core_declarator = coreDecl; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             else if (SimpleDeclarationAST *simpleDecl = node->asSimpleDeclaration()) { | 
					
						
							|  |  |  |                 if (checkDeclaration(simpleDecl)) { | 
					
						
							|  |  |  |                     SimpleDeclarationAST *declaration = simpleDecl; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-17 11:35:57 +02:00
										 |  |  |                     const int cursorPosition = file->cursor().selectionStart(); | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-17 11:35:57 +02:00
										 |  |  |                     const int startOfDeclSpecifier = file->startOf(declaration->decl_specifier_list->firstToken()); | 
					
						
							|  |  |  |                     const int endOfDeclSpecifier = file->endOf(declaration->decl_specifier_list->lastToken() - 1); | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |                     if (cursorPosition >= startOfDeclSpecifier && cursorPosition <= endOfDeclSpecifier) { | 
					
						
							|  |  |  |                         // the AST node under cursor is a specifier.
 | 
					
						
							| 
									
										
										
										
											2011-04-15 16:19:23 +02:00
										 |  |  |                         return singleResult(new Operation(interface, index, declaration)); | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |                     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-15 16:19:23 +02:00
										 |  |  |                     if (core_declarator && interface->isCursorOn(core_declarator)) { | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |                         // got a core-declarator under the text cursor.
 | 
					
						
							| 
									
										
										
										
											2011-04-15 16:19:23 +02:00
										 |  |  |                         return singleResult(new Operation(interface, index, declaration)); | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |                     } | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 break; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return result; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | private: | 
					
						
							|  |  |  |     class Operation: public CppQuickFixOperation | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |     public: | 
					
						
							| 
									
										
										
										
											2011-04-15 16:19:23 +02:00
										 |  |  |         Operation(const QSharedPointer<const CppQuickFixAssistInterface> &interface, int priority, SimpleDeclarationAST *decl) | 
					
						
							|  |  |  |             : CppQuickFixOperation(interface, priority) | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |             , declaration(decl) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             setDescription(QApplication::translate("CppTools::QuickFix", | 
					
						
							|  |  |  |                                                    "Split Declaration")); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-17 11:35:57 +02:00
										 |  |  |         virtual void performChanges(const CppRefactoringFilePtr ¤tFile, const CppRefactoringChanges &) | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |         { | 
					
						
							|  |  |  |             ChangeSet changes; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             SpecifierListAST *specifiers = declaration->decl_specifier_list; | 
					
						
							| 
									
										
										
										
											2010-08-13 12:49:11 +02:00
										 |  |  |             int declSpecifiersStart = currentFile->startOf(specifiers->firstToken()); | 
					
						
							|  |  |  |             int declSpecifiersEnd = currentFile->endOf(specifiers->lastToken() - 1); | 
					
						
							|  |  |  |             int insertPos = currentFile->endOf(declaration->semicolon_token); | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |             DeclaratorAST *prevDeclarator = declaration->declarator_list->value; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             for (DeclaratorListAST *it = declaration->declarator_list->next; it; it = it->next) { | 
					
						
							|  |  |  |                 DeclaratorAST *declarator = it->value; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 changes.insert(insertPos, QLatin1String("\n")); | 
					
						
							|  |  |  |                 changes.copy(declSpecifiersStart, declSpecifiersEnd, insertPos); | 
					
						
							|  |  |  |                 changes.insert(insertPos, QLatin1String(" ")); | 
					
						
							| 
									
										
										
										
											2010-08-13 12:49:11 +02:00
										 |  |  |                 changes.move(currentFile->range(declarator), insertPos); | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |                 changes.insert(insertPos, QLatin1String(";")); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-13 12:49:11 +02:00
										 |  |  |                 const int prevDeclEnd = currentFile->endOf(prevDeclarator); | 
					
						
							|  |  |  |                 changes.remove(prevDeclEnd, currentFile->startOf(declarator)); | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |                 prevDeclarator = declarator; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-17 11:35:57 +02:00
										 |  |  |             currentFile->setChangeSet(changes); | 
					
						
							|  |  |  |             currentFile->appendIndentRange(currentFile->range(declaration)); | 
					
						
							|  |  |  |             currentFile->apply(); | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     private: | 
					
						
							|  |  |  |         SimpleDeclarationAST *declaration; | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |     Add curly braces to a if statement that doesn't already contain a | 
					
						
							| 
									
										
										
										
											2011-01-07 14:49:00 +01:00
										 |  |  |     compound statement. I.e. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (a) | 
					
						
							|  |  |  |         b; | 
					
						
							|  |  |  |     becomes | 
					
						
							|  |  |  |     if (a) { | 
					
						
							|  |  |  |         b; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2011-01-07 16:55:34 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     Activates on: the if | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  | */ | 
					
						
							|  |  |  | class AddBracesToIfOp: public CppQuickFixFactory | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | public: | 
					
						
							| 
									
										
										
										
											2011-04-15 16:19:23 +02:00
										 |  |  |     virtual QList<CppQuickFixOperation::Ptr> match(const QSharedPointer<const CppQuickFixAssistInterface> &interface) | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2011-04-15 16:19:23 +02:00
										 |  |  |         const QList<AST *> &path = interface->path(); | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         // show when we're on the 'if' of an if statement
 | 
					
						
							|  |  |  |         int index = path.size() - 1; | 
					
						
							|  |  |  |         IfStatementAST *ifStatement = path.at(index)->asIfStatement(); | 
					
						
							| 
									
										
										
										
											2011-04-15 16:19:23 +02:00
										 |  |  |         if (ifStatement && interface->isCursorOn(ifStatement->if_token) && ifStatement->statement | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |             && ! ifStatement->statement->asCompoundStatement()) { | 
					
						
							| 
									
										
										
										
											2011-04-15 16:19:23 +02:00
										 |  |  |             return singleResult(new Operation(interface, index, ifStatement->statement)); | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // or if we're on the statement contained in the if
 | 
					
						
							|  |  |  |         // ### This may not be such a good idea, consider nested ifs...
 | 
					
						
							|  |  |  |         for (; index != -1; --index) { | 
					
						
							|  |  |  |             IfStatementAST *ifStatement = path.at(index)->asIfStatement(); | 
					
						
							|  |  |  |             if (ifStatement && ifStatement->statement | 
					
						
							| 
									
										
										
										
											2011-04-15 16:19:23 +02:00
										 |  |  |                 && interface->isCursorOn(ifStatement->statement) | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |                 && ! ifStatement->statement->asCompoundStatement()) { | 
					
						
							| 
									
										
										
										
											2011-04-15 16:19:23 +02:00
										 |  |  |                 return singleResult(new Operation(interface, index, ifStatement->statement)); | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // ### This could very well be extended to the else branch
 | 
					
						
							|  |  |  |         // and other nodes entirely.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return noResult(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | private: | 
					
						
							|  |  |  |     class Operation: public CppQuickFixOperation | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |     public: | 
					
						
							| 
									
										
										
										
											2011-04-15 16:19:23 +02:00
										 |  |  |         Operation(const QSharedPointer<const CppQuickFixAssistInterface> &interface, int priority, StatementAST *statement) | 
					
						
							|  |  |  |             : CppQuickFixOperation(interface, priority) | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |             , _statement(statement) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             setDescription(QApplication::translate("CppTools::QuickFix", | 
					
						
							|  |  |  |                                                    "Add Curly Braces")); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-17 11:35:57 +02:00
										 |  |  |         virtual void performChanges(const CppRefactoringFilePtr ¤tFile, const CppRefactoringChanges &) | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |         { | 
					
						
							|  |  |  |             ChangeSet changes; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-13 12:49:11 +02:00
										 |  |  |             const int start = currentFile->endOf(_statement->firstToken() - 1); | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |             changes.insert(start, QLatin1String(" {")); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-13 12:49:11 +02:00
										 |  |  |             const int end = currentFile->endOf(_statement->lastToken() - 1); | 
					
						
							| 
									
										
										
										
											2012-01-11 14:26:09 +01:00
										 |  |  |             changes.insert(end, QLatin1String("\n}")); | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-17 11:35:57 +02:00
										 |  |  |             currentFile->setChangeSet(changes); | 
					
						
							|  |  |  |             currentFile->appendIndentRange(Utils::ChangeSet::Range(start, end)); | 
					
						
							|  |  |  |             currentFile->apply(); | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     private: | 
					
						
							|  |  |  |         StatementAST *_statement; | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |     Replace | 
					
						
							|  |  |  |     if (Type name = foo()) {...} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     With | 
					
						
							|  |  |  |     Type name = foo; | 
					
						
							|  |  |  |     if (name) {...} | 
					
						
							| 
									
										
										
										
											2011-01-07 16:55:34 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     Activates on: the name of the introduced variable | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  | */ | 
					
						
							|  |  |  | class MoveDeclarationOutOfIfOp: public CppQuickFixFactory | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | public: | 
					
						
							| 
									
										
										
										
											2011-04-15 16:19:23 +02:00
										 |  |  |     virtual QList<CppQuickFixOperation::Ptr> match(const QSharedPointer<const CppQuickFixAssistInterface> &interface) | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2011-04-15 16:19:23 +02:00
										 |  |  |         const QList<AST *> &path = interface->path(); | 
					
						
							|  |  |  |         QSharedPointer<Operation> op(new Operation(interface)); | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         int index = path.size() - 1; | 
					
						
							|  |  |  |         for (; index != -1; --index) { | 
					
						
							|  |  |  |             if (IfStatementAST *statement = path.at(index)->asIfStatement()) { | 
					
						
							|  |  |  |                 if (statement->match(op->pattern, &op->matcher) && op->condition->declarator) { | 
					
						
							|  |  |  |                     DeclaratorAST *declarator = op->condition->declarator; | 
					
						
							|  |  |  |                     op->core = declarator->core_declarator; | 
					
						
							|  |  |  |                     if (! op->core) | 
					
						
							|  |  |  |                         return noResult(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-15 16:19:23 +02:00
										 |  |  |                     if (interface->isCursorOn(op->core)) { | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |                         QList<CppQuickFixOperation::Ptr> result; | 
					
						
							|  |  |  |                         op->setPriority(index); | 
					
						
							|  |  |  |                         result.append(op); | 
					
						
							|  |  |  |                         return result; | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return noResult(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | private: | 
					
						
							|  |  |  |     class Operation: public CppQuickFixOperation | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |     public: | 
					
						
							| 
									
										
										
										
											2011-04-15 16:19:23 +02:00
										 |  |  |         Operation(const QSharedPointer<const CppQuickFixAssistInterface> &interface) | 
					
						
							|  |  |  |             : CppQuickFixOperation(interface) | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |         { | 
					
						
							|  |  |  |             setDescription(QApplication::translate("CppTools::QuickFix", | 
					
						
							|  |  |  |                                                    "Move Declaration out of Condition")); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             condition = mk.Condition(); | 
					
						
							|  |  |  |             pattern = mk.IfStatement(condition); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-17 11:35:57 +02:00
										 |  |  |         virtual void performChanges(const CppRefactoringFilePtr ¤tFile, const CppRefactoringChanges &) | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |         { | 
					
						
							|  |  |  |             ChangeSet changes; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-13 12:49:11 +02:00
										 |  |  |             changes.copy(currentFile->range(core), currentFile->startOf(condition)); | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-13 12:49:11 +02:00
										 |  |  |             int insertPos = currentFile->startOf(pattern); | 
					
						
							|  |  |  |             changes.move(currentFile->range(condition), insertPos); | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |             changes.insert(insertPos, QLatin1String(";\n")); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-17 11:35:57 +02:00
										 |  |  |             currentFile->setChangeSet(changes); | 
					
						
							|  |  |  |             currentFile->appendIndentRange(currentFile->range(pattern)); | 
					
						
							|  |  |  |             currentFile->apply(); | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         ASTMatcher matcher; | 
					
						
							|  |  |  |         ASTPatternBuilder mk; | 
					
						
							| 
									
										
										
										
											2011-02-21 16:02:26 +01:00
										 |  |  |         CPPEditorWidget *editor; | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |         ConditionAST *condition; | 
					
						
							|  |  |  |         IfStatementAST *pattern; | 
					
						
							|  |  |  |         CoreDeclaratorAST *core; | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |     Replace | 
					
						
							|  |  |  |     while (Type name = foo()) {...} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     With | 
					
						
							|  |  |  |     Type name; | 
					
						
							|  |  |  |     while ((name = foo()) != 0) {...} | 
					
						
							| 
									
										
										
										
											2011-01-07 16:55:34 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     Activates on: the name of the introduced variable | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  | */ | 
					
						
							|  |  |  | class MoveDeclarationOutOfWhileOp: public CppQuickFixFactory | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | public: | 
					
						
							| 
									
										
										
										
											2011-04-15 16:19:23 +02:00
										 |  |  |     virtual QList<CppQuickFixOperation::Ptr> match(const QSharedPointer<const CppQuickFixAssistInterface> &interface) | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2011-04-15 16:19:23 +02:00
										 |  |  |         const QList<AST *> &path = interface->path(); | 
					
						
							|  |  |  |         QSharedPointer<Operation> op(new Operation(interface)); | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         int index = path.size() - 1; | 
					
						
							|  |  |  |         for (; index != -1; --index) { | 
					
						
							|  |  |  |             if (WhileStatementAST *statement = path.at(index)->asWhileStatement()) { | 
					
						
							|  |  |  |                 if (statement->match(op->pattern, &op->matcher) && op->condition->declarator) { | 
					
						
							|  |  |  |                     DeclaratorAST *declarator = op->condition->declarator; | 
					
						
							|  |  |  |                     op->core = declarator->core_declarator; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                     if (! op->core) | 
					
						
							|  |  |  |                         return noResult(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-16 11:38:34 +02:00
										 |  |  |                     else if (! declarator->equal_token) | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |                         return noResult(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                     else if (! declarator->initializer) | 
					
						
							|  |  |  |                         return noResult(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-15 16:19:23 +02:00
										 |  |  |                     if (interface->isCursorOn(op->core)) { | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |                         QList<CppQuickFixOperation::Ptr> result; | 
					
						
							|  |  |  |                         op->setPriority(index); | 
					
						
							|  |  |  |                         result.append(op); | 
					
						
							|  |  |  |                         return result; | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return noResult(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | private: | 
					
						
							|  |  |  |     class Operation: public CppQuickFixOperation | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |     public: | 
					
						
							| 
									
										
										
										
											2011-04-15 16:19:23 +02:00
										 |  |  |         Operation(const QSharedPointer<const CppQuickFixAssistInterface> &interface) | 
					
						
							|  |  |  |             : CppQuickFixOperation(interface) | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |         { | 
					
						
							|  |  |  |             setDescription(QApplication::translate("CppTools::QuickFix", | 
					
						
							|  |  |  |                                                    "Move Declaration out of Condition")); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             condition = mk.Condition(); | 
					
						
							|  |  |  |             pattern = mk.WhileStatement(condition); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-17 11:35:57 +02:00
										 |  |  |         virtual void performChanges(const CppRefactoringFilePtr ¤tFile, const CppRefactoringChanges &) | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |         { | 
					
						
							|  |  |  |             ChangeSet changes; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-13 12:49:11 +02:00
										 |  |  |             changes.insert(currentFile->startOf(condition), QLatin1String("(")); | 
					
						
							|  |  |  |             changes.insert(currentFile->endOf(condition), QLatin1String(") != 0")); | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-13 12:49:11 +02:00
										 |  |  |             int insertPos = currentFile->startOf(pattern); | 
					
						
							|  |  |  |             const int conditionStart = currentFile->startOf(condition); | 
					
						
							|  |  |  |             changes.move(conditionStart, currentFile->startOf(core), insertPos); | 
					
						
							|  |  |  |             changes.copy(currentFile->range(core), insertPos); | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |             changes.insert(insertPos, QLatin1String(";\n")); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-17 11:35:57 +02:00
										 |  |  |             currentFile->setChangeSet(changes); | 
					
						
							|  |  |  |             currentFile->appendIndentRange(currentFile->range(pattern)); | 
					
						
							|  |  |  |             currentFile->apply(); | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         ASTMatcher matcher; | 
					
						
							|  |  |  |         ASTPatternBuilder mk; | 
					
						
							| 
									
										
										
										
											2011-02-21 16:02:26 +01:00
										 |  |  |         CPPEditorWidget *editor; | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |         ConditionAST *condition; | 
					
						
							|  |  |  |         WhileStatementAST *pattern; | 
					
						
							|  |  |  |         CoreDeclaratorAST *core; | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |   Replace | 
					
						
							|  |  |  |      if (something && something_else) { | 
					
						
							|  |  |  |      } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   with | 
					
						
							|  |  |  |      if (something) { | 
					
						
							|  |  |  |         if (something_else) { | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |      } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   and | 
					
						
							|  |  |  |     if (something || something_else) | 
					
						
							|  |  |  |       x; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   with | 
					
						
							|  |  |  |     if (something) | 
					
						
							|  |  |  |       x; | 
					
						
							|  |  |  |     else if (something_else) | 
					
						
							|  |  |  |       x; | 
					
						
							| 
									
										
										
										
											2011-01-07 16:55:34 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     Activates on: && or || | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  | */ | 
					
						
							|  |  |  | class SplitIfStatementOp: public CppQuickFixFactory | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | public: | 
					
						
							| 
									
										
										
										
											2011-04-15 16:19:23 +02:00
										 |  |  |     virtual QList<CppQuickFixOperation::Ptr> match(const QSharedPointer<const CppQuickFixAssistInterface> &interface) | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |     { | 
					
						
							|  |  |  |         IfStatementAST *pattern = 0; | 
					
						
							| 
									
										
										
										
											2011-04-15 16:19:23 +02:00
										 |  |  |         const QList<AST *> &path = interface->path(); | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         int index = path.size() - 1; | 
					
						
							|  |  |  |         for (; index != -1; --index) { | 
					
						
							|  |  |  |             AST *node = path.at(index); | 
					
						
							|  |  |  |             if (IfStatementAST *stmt = node->asIfStatement()) { | 
					
						
							|  |  |  |                 pattern = stmt; | 
					
						
							|  |  |  |                 break; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (! pattern || ! pattern->statement) | 
					
						
							|  |  |  |             return noResult(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         unsigned splitKind = 0; | 
					
						
							|  |  |  |         for (++index; index < path.size(); ++index) { | 
					
						
							|  |  |  |             AST *node = path.at(index); | 
					
						
							|  |  |  |             BinaryExpressionAST *condition = node->asBinaryExpression(); | 
					
						
							|  |  |  |             if (! condition) | 
					
						
							|  |  |  |                 return noResult(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-17 11:35:57 +02:00
										 |  |  |             Token binaryToken = interface->currentFile()->tokenAt(condition->binary_op_token); | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |             // only accept a chain of ||s or &&s - no mixing
 | 
					
						
							|  |  |  |             if (! splitKind) { | 
					
						
							|  |  |  |                 splitKind = binaryToken.kind(); | 
					
						
							|  |  |  |                 if (splitKind != T_AMPER_AMPER && splitKind != T_PIPE_PIPE) | 
					
						
							|  |  |  |                     return noResult(); | 
					
						
							|  |  |  |                 // we can't reliably split &&s in ifs with an else branch
 | 
					
						
							|  |  |  |                 if (splitKind == T_AMPER_AMPER && pattern->else_statement) | 
					
						
							|  |  |  |                     return noResult(); | 
					
						
							|  |  |  |             } else if (splitKind != binaryToken.kind()) { | 
					
						
							|  |  |  |                 return noResult(); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-15 16:19:23 +02:00
										 |  |  |             if (interface->isCursorOn(condition->binary_op_token)) | 
					
						
							|  |  |  |                 return singleResult(new Operation(interface, index, pattern, condition)); | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return noResult(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | private: | 
					
						
							|  |  |  |     class Operation: public CppQuickFixOperation | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |     public: | 
					
						
							| 
									
										
										
										
											2011-04-15 16:19:23 +02:00
										 |  |  |         Operation(const QSharedPointer<const CppQuickFixAssistInterface> &interface, int priority, | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |                   IfStatementAST *pattern, BinaryExpressionAST *condition) | 
					
						
							| 
									
										
										
										
											2011-04-15 16:19:23 +02:00
										 |  |  |             : CppQuickFixOperation(interface, priority) | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |             , pattern(pattern) | 
					
						
							|  |  |  |             , condition(condition) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             setDescription(QApplication::translate("CppTools::QuickFix", | 
					
						
							|  |  |  |                                                    "Split if Statement")); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-17 11:35:57 +02:00
										 |  |  |         virtual void performChanges(const CppRefactoringFilePtr ¤tFile, const CppRefactoringChanges &) | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |         { | 
					
						
							| 
									
										
										
										
											2010-08-13 12:49:11 +02:00
										 |  |  |             const Token binaryToken = currentFile->tokenAt(condition->binary_op_token); | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |             if (binaryToken.is(T_AMPER_AMPER)) | 
					
						
							| 
									
										
										
										
											2010-08-12 13:46:18 +02:00
										 |  |  |                 splitAndCondition(currentFile); | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |             else | 
					
						
							| 
									
										
										
										
											2010-08-12 13:46:18 +02:00
										 |  |  |                 splitOrCondition(currentFile); | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-17 11:35:57 +02:00
										 |  |  |         void splitAndCondition(CppRefactoringFilePtr currentFile) | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |         { | 
					
						
							|  |  |  |             ChangeSet changes; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-13 12:49:11 +02:00
										 |  |  |             int startPos = currentFile->startOf(pattern); | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |             changes.insert(startPos, QLatin1String("if (")); | 
					
						
							| 
									
										
										
										
											2010-08-13 12:49:11 +02:00
										 |  |  |             changes.move(currentFile->range(condition->left_expression), startPos); | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |             changes.insert(startPos, QLatin1String(") {\n")); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-13 12:49:11 +02:00
										 |  |  |             const int lExprEnd = currentFile->endOf(condition->left_expression); | 
					
						
							|  |  |  |             changes.remove(lExprEnd, currentFile->startOf(condition->right_expression)); | 
					
						
							|  |  |  |             changes.insert(currentFile->endOf(pattern), QLatin1String("\n}")); | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-17 11:35:57 +02:00
										 |  |  |             currentFile->setChangeSet(changes); | 
					
						
							|  |  |  |             currentFile->appendIndentRange(currentFile->range(pattern)); | 
					
						
							|  |  |  |             currentFile->apply(); | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-17 11:35:57 +02:00
										 |  |  |         void splitOrCondition(CppRefactoringFilePtr currentFile) | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |         { | 
					
						
							|  |  |  |             ChangeSet changes; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             StatementAST *ifTrueStatement = pattern->statement; | 
					
						
							|  |  |  |             CompoundStatementAST *compoundStatement = ifTrueStatement->asCompoundStatement(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-13 12:49:11 +02:00
										 |  |  |             int insertPos = currentFile->endOf(ifTrueStatement); | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |             if (compoundStatement) | 
					
						
							|  |  |  |                 changes.insert(insertPos, QLatin1String(" ")); | 
					
						
							|  |  |  |             else | 
					
						
							|  |  |  |                 changes.insert(insertPos, QLatin1String("\n")); | 
					
						
							|  |  |  |             changes.insert(insertPos, QLatin1String("else if (")); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-13 12:49:11 +02:00
										 |  |  |             const int rExprStart = currentFile->startOf(condition->right_expression); | 
					
						
							|  |  |  |             changes.move(rExprStart, currentFile->startOf(pattern->rparen_token), insertPos); | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |             changes.insert(insertPos, QLatin1String(")")); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-13 12:49:11 +02:00
										 |  |  |             const int rParenEnd = currentFile->endOf(pattern->rparen_token); | 
					
						
							|  |  |  |             changes.copy(rParenEnd, currentFile->endOf(pattern->statement), insertPos); | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-13 12:49:11 +02:00
										 |  |  |             const int lExprEnd = currentFile->endOf(condition->left_expression); | 
					
						
							|  |  |  |             changes.remove(lExprEnd, currentFile->startOf(condition->right_expression)); | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-17 11:35:57 +02:00
										 |  |  |             currentFile->setChangeSet(changes); | 
					
						
							|  |  |  |             currentFile->appendIndentRange(currentFile->range(pattern)); | 
					
						
							|  |  |  |             currentFile->apply(); | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     private: | 
					
						
							|  |  |  |         IfStatementAST *pattern; | 
					
						
							|  |  |  |         BinaryExpressionAST *condition; | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |   Replace | 
					
						
							| 
									
										
										
										
											2011-12-14 14:23:25 +01:00
										 |  |  |     "abcd"  -> QLatin1String("abcd") | 
					
						
							|  |  |  |     @"abcd" -> QLatin1String("abcd") (Objective C) | 
					
						
							|  |  |  |     'a'     -> QLatin1Char('a') | 
					
						
							|  |  |  |     'a'     -> "a" | 
					
						
							|  |  |  |     "a"     -> 'a' or QLatin1Char('a') (Single character string constants) | 
					
						
							|  |  |  |     "\n"    -> '\n', QLatin1Char('\n') | 
					
						
							| 
									
										
										
										
											2011-01-07 14:49:00 +01:00
										 |  |  |   Except if they are already enclosed in | 
					
						
							|  |  |  |     QLatin1Char, QT_TRANSLATE_NOOP, tr, | 
					
						
							|  |  |  |     trUtf8, QLatin1Literal, QLatin1String | 
					
						
							| 
									
										
										
										
											2011-01-07 16:55:34 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-14 14:23:25 +01:00
										 |  |  |     Activates on: the string or character literal | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  | */ | 
					
						
							| 
									
										
										
										
											2011-09-30 10:45:11 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | static inline QString msgQtStringLiteralDescription(const QString &replacement, int qtVersion) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return QApplication::translate("CppTools::QuickFix", "Enclose in %1(...) (Qt %2)") | 
					
						
							|  |  |  |            .arg(replacement).arg(qtVersion); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-14 14:23:25 +01:00
										 |  |  | static inline QString msgQtStringLiteralDescription(const QString &replacement) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return QApplication::translate("CppTools::QuickFix", "Enclose in %1(...)").arg(replacement); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  | class WrapStringLiteral: public CppQuickFixFactory | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | public: | 
					
						
							| 
									
										
										
										
											2011-12-14 14:23:25 +01:00
										 |  |  |     typedef const QSharedPointer<const CppQuickFixAssistInterface> AssistInterfacePtr; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     enum ActionFlags | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         EncloseInQLatin1CharAction = 0x1, EncloseInQLatin1StringAction = 0x2, EncloseInQStringLiteralAction = 0x4, | 
					
						
							|  |  |  |         EncloseActionMask = EncloseInQLatin1CharAction | EncloseInQLatin1StringAction | EncloseInQStringLiteralAction, | 
					
						
							|  |  |  |         TranslateTrAction = 0x8, TranslateQCoreApplicationAction = 0x10, TranslateNoopAction = 0x20, | 
					
						
							|  |  |  |         TranslationMask = TranslateTrAction | TranslateQCoreApplicationAction | TranslateNoopAction, | 
					
						
							|  |  |  |         RemoveObjectiveCAction = 0x40, | 
					
						
							|  |  |  |         ConvertEscapeSequencesToCharAction = 0x100, ConvertEscapeSequencesToStringAction = 0x200, | 
					
						
							|  |  |  |         SingleQuoteAction = 0x400, DoubleQuoteAction = 0x800 | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |     enum Type { TypeString, TypeObjCString, TypeChar, TypeNone }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-14 14:23:25 +01:00
										 |  |  |     virtual QList<CppQuickFixOperation::Ptr> match(const AssistInterfacePtr &interface); | 
					
						
							|  |  |  |     static QString replacement(unsigned actions); | 
					
						
							|  |  |  |     static QByteArray stringToCharEscapeSequences(const QByteArray &content); | 
					
						
							|  |  |  |     static QByteArray charToStringEscapeSequences(const QByteArray &content); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     static ExpressionAST *analyze(const QList<AST *> &path, const CppRefactoringFilePtr &file, | 
					
						
							|  |  |  |                                   Type *type, | 
					
						
							|  |  |  |                                   QByteArray *enclosingFunction = 0, | 
					
						
							|  |  |  |                                   CallAST **enclosingFunctionCall = 0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Operations performs the operations of type ActionFlags passed in as actions.
 | 
					
						
							|  |  |  |     class Operation : public CppQuickFixOperation | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2011-12-14 14:23:25 +01:00
										 |  |  |     public: | 
					
						
							|  |  |  |         Operation(const AssistInterfacePtr &interface, int priority, | 
					
						
							|  |  |  |                   unsigned actions, const QString &description, ExpressionAST *literal, | 
					
						
							|  |  |  |                   const QString &translationContext = QString()); | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-14 14:23:25 +01:00
										 |  |  |         virtual void performChanges(const CppRefactoringFilePtr ¤tFile, const CppRefactoringChanges &); | 
					
						
							|  |  |  |     private: | 
					
						
							|  |  |  |         const unsigned m_actions; | 
					
						
							|  |  |  |         ExpressionAST *m_literal; | 
					
						
							|  |  |  |         const QString m_translationContext; | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | }; | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-14 14:23:25 +01:00
										 |  |  | /* Analze a string/character literal like "x", QLatin1String("x") and return the literal
 | 
					
						
							|  |  |  |  * (StringLiteral or NumericLiteral for characters) and its type | 
					
						
							|  |  |  |  * and the enclosing function (QLatin1String, tr...) */ | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-14 14:23:25 +01:00
										 |  |  | ExpressionAST *WrapStringLiteral::analyze(const QList<AST *> &path, | 
					
						
							|  |  |  |                                           const CppRefactoringFilePtr &file, | 
					
						
							|  |  |  |                                           Type *type, | 
					
						
							|  |  |  |                                           QByteArray *enclosingFunction /* = 0 */, | 
					
						
							|  |  |  |                                           CallAST **enclosingFunctionCall /* = 0 */) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     *type = TypeNone; | 
					
						
							|  |  |  |     if (enclosingFunction) | 
					
						
							|  |  |  |         enclosingFunction->clear(); | 
					
						
							|  |  |  |     if (enclosingFunctionCall) | 
					
						
							|  |  |  |         *enclosingFunctionCall = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (path.isEmpty()) | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ExpressionAST *literal = path.last()->asExpression(); | 
					
						
							|  |  |  |     if (literal) { | 
					
						
							|  |  |  |         if (literal->asStringLiteral()) { | 
					
						
							|  |  |  |             // Check for Objective C string (@"bla")
 | 
					
						
							|  |  |  |             const QChar firstChar = file->charAt(file->startOf(literal)); | 
					
						
							|  |  |  |             *type = firstChar == QLatin1Char('@') ? TypeObjCString : TypeString; | 
					
						
							|  |  |  |         } else if (NumericLiteralAST *numericLiteral = literal->asNumericLiteral()) { | 
					
						
							|  |  |  |             // character ('c') constants are numeric.
 | 
					
						
							|  |  |  |             if (file->tokenAt(numericLiteral->literal_token).is(T_CHAR_LITERAL)) | 
					
						
							|  |  |  |                 *type = TypeChar; | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2011-12-14 14:23:25 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-14 14:23:25 +01:00
										 |  |  |     if (*type != TypeNone && enclosingFunction && path.size() > 1) { | 
					
						
							|  |  |  |         if (CallAST *call = path.at(path.size() - 2)->asCall()) { | 
					
						
							|  |  |  |             if (call->base_expression) { | 
					
						
							|  |  |  |                 if (IdExpressionAST *idExpr = call->base_expression->asIdExpression()) { | 
					
						
							|  |  |  |                     if (SimpleNameAST *functionName = idExpr->name->asSimpleName()) { | 
					
						
							|  |  |  |                         *enclosingFunction = file->tokenAt(functionName->identifier_token).identifier->chars(); | 
					
						
							|  |  |  |                         if (enclosingFunctionCall) | 
					
						
							|  |  |  |                             *enclosingFunctionCall = call; | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |                     } | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2011-12-14 14:23:25 +01:00
										 |  |  |     } | 
					
						
							|  |  |  |     return literal; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-14 14:23:25 +01:00
										 |  |  | QList<CppQuickFixOperation::Ptr> WrapStringLiteral::match(const AssistInterfacePtr &interface) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     typedef CppQuickFixOperation::Ptr OperationPtr; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Type type = TypeNone; | 
					
						
							|  |  |  |     QByteArray enclosingFunction; | 
					
						
							|  |  |  |     const QList<AST *> &path = interface->path(); | 
					
						
							|  |  |  |     CppRefactoringFilePtr file = interface->currentFile(); | 
					
						
							|  |  |  |     ExpressionAST *literal = WrapStringLiteral::analyze(path, file, &type, &enclosingFunction); | 
					
						
							|  |  |  |     if (!literal || type == TypeNone) | 
					
						
							|  |  |  |         return noResult(); | 
					
						
							|  |  |  |     if ((type == TypeChar && enclosingFunction == "QLatin1Char") | 
					
						
							|  |  |  |         || isQtStringLiteral(enclosingFunction) | 
					
						
							|  |  |  |         || isQtStringTranslation(enclosingFunction)) | 
					
						
							|  |  |  |         return noResult(); | 
					
						
							| 
									
										
										
										
											2011-09-30 10:45:11 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-14 14:23:25 +01:00
										 |  |  |     QList<CppQuickFixOperation::Ptr> result; | 
					
						
							|  |  |  |     const int priority = path.size() - 1; // very high priority
 | 
					
						
							|  |  |  |     if (type == TypeChar) { | 
					
						
							|  |  |  |         unsigned actions = EncloseInQLatin1CharAction; | 
					
						
							|  |  |  |         QString description = | 
					
						
							|  |  |  |             msgQtStringLiteralDescription(WrapStringLiteral::replacement(actions)); | 
					
						
							|  |  |  |         result << OperationPtr(new Operation(interface, priority, actions, | 
					
						
							|  |  |  |                                              description, literal)); | 
					
						
							|  |  |  |         if (NumericLiteralAST *charLiteral = literal->asNumericLiteral()) { | 
					
						
							|  |  |  |             const QByteArray contents(file->tokenAt(charLiteral->literal_token).identifier->chars()); | 
					
						
							|  |  |  |             if (!charToStringEscapeSequences(contents).isEmpty()) { | 
					
						
							|  |  |  |                 actions = DoubleQuoteAction | ConvertEscapeSequencesToStringAction; | 
					
						
							|  |  |  |                 description = QApplication::translate("CppTools::QuickFix", | 
					
						
							|  |  |  |                               "Convert to String Literal"); | 
					
						
							|  |  |  |                 result << OperationPtr(new Operation(interface, priority, actions, | 
					
						
							|  |  |  |                                                      description, literal)); | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2011-09-30 10:45:11 +02:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2011-12-14 14:23:25 +01:00
										 |  |  |     } else { | 
					
						
							|  |  |  |         const unsigned objectiveCActions = type == TypeObjCString ? | 
					
						
							|  |  |  |                                            unsigned(RemoveObjectiveCAction) : 0u; | 
					
						
							|  |  |  |         unsigned actions = 0; | 
					
						
							|  |  |  |         if (StringLiteralAST *stringLiteral = literal->asStringLiteral()) { | 
					
						
							|  |  |  |             const QByteArray contents(file->tokenAt(stringLiteral->literal_token).identifier->chars()); | 
					
						
							|  |  |  |             if (!stringToCharEscapeSequences(contents).isEmpty()) { | 
					
						
							|  |  |  |                 actions = EncloseInQLatin1CharAction | SingleQuoteAction | 
					
						
							|  |  |  |                           | ConvertEscapeSequencesToCharAction | objectiveCActions; | 
					
						
							|  |  |  |                 QString description = QApplication::translate("CppTools::QuickFix", | 
					
						
							|  |  |  |                                       "Convert to Character Literal and Enclose in QLatin1Char(...)"); | 
					
						
							|  |  |  |                 result << OperationPtr(new Operation(interface, priority, | 
					
						
							|  |  |  |                                                      actions, description, literal)); | 
					
						
							|  |  |  |                 actions &= ~EncloseInQLatin1CharAction; | 
					
						
							|  |  |  |                 description = QApplication::translate("CppTools::QuickFix", | 
					
						
							|  |  |  |                               "Convert to Character Literal"); | 
					
						
							|  |  |  |                 result << OperationPtr(new Operation(interface, priority, | 
					
						
							|  |  |  |                                                      actions, description, literal)); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         actions = EncloseInQLatin1StringAction | objectiveCActions; | 
					
						
							|  |  |  |         result << OperationPtr(new Operation(interface, priority, actions, | 
					
						
							|  |  |  |                                              msgQtStringLiteralDescription(WrapStringLiteral::replacement(actions), 4), | 
					
						
							|  |  |  |                                              literal)); | 
					
						
							|  |  |  |         actions = EncloseInQStringLiteralAction | objectiveCActions; | 
					
						
							|  |  |  |         result << OperationPtr(new Operation(interface, priority, actions, | 
					
						
							|  |  |  |                                              msgQtStringLiteralDescription(WrapStringLiteral::replacement(actions), 5), | 
					
						
							|  |  |  |                                              literal)); | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2011-12-14 14:23:25 +01:00
										 |  |  |     return result; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-14 14:23:25 +01:00
										 |  |  | QString WrapStringLiteral::replacement(unsigned actions) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (actions & EncloseInQLatin1CharAction) | 
					
						
							|  |  |  |         return QLatin1String("QLatin1Char"); | 
					
						
							|  |  |  |     if (actions & EncloseInQLatin1StringAction) | 
					
						
							|  |  |  |         return QLatin1String("QLatin1String"); | 
					
						
							|  |  |  |     if (actions & EncloseInQStringLiteralAction) | 
					
						
							|  |  |  |         return QLatin1String("QStringLiteral"); | 
					
						
							|  |  |  |     if (actions & TranslateTrAction) | 
					
						
							|  |  |  |         return QLatin1String("tr"); | 
					
						
							|  |  |  |     if (actions & TranslateQCoreApplicationAction) | 
					
						
							|  |  |  |         return QLatin1String("QCoreApplication::translate"); | 
					
						
							|  |  |  |     if (actions & TranslateNoopAction) | 
					
						
							|  |  |  |         return QLatin1String("QT_TRANSLATE_NOOP"); | 
					
						
							|  |  |  |     return QString(); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-14 14:23:25 +01:00
										 |  |  | /* Convert single-character string literals into character literals with some
 | 
					
						
							|  |  |  |  * special cases "a" --> 'a', "'" --> '\'', "\n" --> '\n', "\"" --> '"'. */ | 
					
						
							|  |  |  | QByteArray WrapStringLiteral::stringToCharEscapeSequences(const QByteArray &content) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (content.size() == 1) | 
					
						
							|  |  |  |         return content.at(0) == '\'' ? QByteArray("\\'") : content; | 
					
						
							|  |  |  |     if (content.size() == 2 && content.at(0) == '\\') | 
					
						
							|  |  |  |         return content == "\\\"" ? QByteArray(1, '"') : content; | 
					
						
							|  |  |  |     return QByteArray(); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-14 14:23:25 +01:00
										 |  |  | /* Convert character literal into a string literal with some special cases
 | 
					
						
							|  |  |  |  * 'a' -> "a", '\n' -> "\n", '\'' --> "'", '"' --> "\"". */ | 
					
						
							|  |  |  | QByteArray WrapStringLiteral::charToStringEscapeSequences(const QByteArray &content) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (content.size() == 1) | 
					
						
							|  |  |  |         return content.at(0) == '"' ? QByteArray("\\\"") : content; | 
					
						
							|  |  |  |     if (content.size() == 2) | 
					
						
							|  |  |  |         return content == "\\'" ? QByteArray("'") : content; | 
					
						
							|  |  |  |     return QByteArray(); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-14 14:23:25 +01:00
										 |  |  | WrapStringLiteral::Operation::Operation(const AssistInterfacePtr &interface, int priority, | 
					
						
							|  |  |  |                                         unsigned actions, const QString &description, ExpressionAST *literal, | 
					
						
							|  |  |  |                                         const QString &translationContext) | 
					
						
							|  |  |  |     : CppQuickFixOperation(interface, priority), m_actions(actions), m_literal(literal), | 
					
						
							|  |  |  |       m_translationContext(translationContext) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     setDescription(description); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-14 14:23:25 +01:00
										 |  |  | void WrapStringLiteral::Operation::performChanges(const CppRefactoringFilePtr ¤tFile, const CppRefactoringChanges &) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     ChangeSet changes; | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-14 14:23:25 +01:00
										 |  |  |     const int startPos = currentFile->startOf(m_literal); | 
					
						
							|  |  |  |     const int endPos = currentFile->endOf(m_literal); | 
					
						
							| 
									
										
										
										
											2011-09-30 10:45:11 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-14 14:23:25 +01:00
										 |  |  |     // kill leading '@'. No need to adapt endPos, that is done by ChangeSet
 | 
					
						
							|  |  |  |     if (m_actions & RemoveObjectiveCAction) | 
					
						
							|  |  |  |         changes.remove(startPos, startPos + 1); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Fix quotes
 | 
					
						
							|  |  |  |     if (m_actions & (SingleQuoteAction | DoubleQuoteAction)) { | 
					
						
							|  |  |  |         const QString newQuote((m_actions & SingleQuoteAction) ? QLatin1Char('\'') : QLatin1Char('"')); | 
					
						
							|  |  |  |         changes.replace(startPos, startPos + 1, newQuote); | 
					
						
							|  |  |  |         changes.replace(endPos - 1, endPos, newQuote); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Convert single character strings into character constants
 | 
					
						
							|  |  |  |     if (m_actions & ConvertEscapeSequencesToCharAction) { | 
					
						
							|  |  |  |         StringLiteralAST *stringLiteral = m_literal->asStringLiteral(); | 
					
						
							|  |  |  |         QTC_ASSERT(stringLiteral, return ;); | 
					
						
							|  |  |  |         const QByteArray oldContents(currentFile->tokenAt(stringLiteral->literal_token).identifier->chars()); | 
					
						
							|  |  |  |         const QByteArray newContents = stringToCharEscapeSequences(oldContents); | 
					
						
							|  |  |  |         QTC_ASSERT(!newContents.isEmpty(), return ;); | 
					
						
							|  |  |  |         if (oldContents != newContents) | 
					
						
							|  |  |  |             changes.replace(startPos + 1, endPos -1, QString::fromLatin1(newContents)); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Convert character constants into strings constants
 | 
					
						
							|  |  |  |     if (m_actions & ConvertEscapeSequencesToStringAction) { | 
					
						
							|  |  |  |         NumericLiteralAST *charLiteral = m_literal->asNumericLiteral(); // char 'c' constants are numerical.
 | 
					
						
							|  |  |  |         QTC_ASSERT(charLiteral, return ;); | 
					
						
							|  |  |  |         const QByteArray oldContents(currentFile->tokenAt(charLiteral->literal_token).identifier->chars()); | 
					
						
							|  |  |  |         const QByteArray newContents = charToStringEscapeSequences(oldContents); | 
					
						
							|  |  |  |         QTC_ASSERT(!newContents.isEmpty(), return ;); | 
					
						
							|  |  |  |         if (oldContents != newContents) | 
					
						
							|  |  |  |             changes.replace(startPos + 1, endPos -1, QString::fromLatin1(newContents)); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Enclose in literal or translation function, macro.
 | 
					
						
							|  |  |  |     if (m_actions & (EncloseActionMask | TranslationMask)) { | 
					
						
							|  |  |  |         changes.insert(endPos, QString(QLatin1Char(')'))); | 
					
						
							|  |  |  |         QString leading = WrapStringLiteral::replacement(m_actions); | 
					
						
							|  |  |  |         leading += QLatin1Char('('); | 
					
						
							|  |  |  |         if (m_actions & (TranslateQCoreApplicationAction | TranslateNoopAction)) { | 
					
						
							|  |  |  |             leading += QLatin1Char('"'); | 
					
						
							|  |  |  |             leading += m_translationContext; | 
					
						
							|  |  |  |             leading += QLatin1String("\", "); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         changes.insert(startPos, leading); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     currentFile->setChangeSet(changes); | 
					
						
							|  |  |  |     currentFile->apply(); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |   Replace | 
					
						
							|  |  |  |     "abcd" | 
					
						
							|  |  |  |   With | 
					
						
							|  |  |  |     tr("abcd") or | 
					
						
							|  |  |  |     QCoreApplication::translate("CONTEXT", "abcd") or | 
					
						
							|  |  |  |     QT_TRANSLATE_NOOP("GLOBAL", "abcd") | 
					
						
							| 
									
										
										
										
											2011-01-07 14:49:00 +01:00
										 |  |  |   depending on what is available. | 
					
						
							| 
									
										
										
										
											2011-01-07 16:55:34 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     Activates on: the string literal | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  | */ | 
					
						
							|  |  |  | class TranslateStringLiteral: public CppQuickFixFactory | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | public: | 
					
						
							| 
									
										
										
										
											2011-04-15 16:19:23 +02:00
										 |  |  |     virtual QList<CppQuickFixOperation::Ptr> match(const QSharedPointer<const CppQuickFixAssistInterface> &interface) | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |     { | 
					
						
							|  |  |  |         // Initialize
 | 
					
						
							| 
									
										
										
										
											2011-12-14 14:23:25 +01:00
										 |  |  |         WrapStringLiteral::Type type = WrapStringLiteral::TypeNone; | 
					
						
							|  |  |  |         QByteArray enclosingFunction; | 
					
						
							|  |  |  |         const QList<AST *> &path = interface->path(); | 
					
						
							|  |  |  |         CppRefactoringFilePtr file = interface->currentFile(); | 
					
						
							|  |  |  |         ExpressionAST *literal = WrapStringLiteral::analyze(path, file, &type, &enclosingFunction); | 
					
						
							|  |  |  |         if (!literal || type != WrapStringLiteral::TypeString | 
					
						
							|  |  |  |            || isQtStringLiteral(enclosingFunction) || isQtStringTranslation(enclosingFunction)) | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |             return noResult(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-14 14:23:25 +01:00
										 |  |  |         QString trContext; | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-15 16:19:23 +02:00
										 |  |  |         QSharedPointer<Control> control = interface->context().control(); | 
					
						
							| 
									
										
										
										
											2010-09-02 11:59:01 +02:00
										 |  |  |         const Name *trName = control->identifier("tr"); | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         // Check whether we are in a method:
 | 
					
						
							| 
									
										
										
										
											2011-12-14 14:23:25 +01:00
										 |  |  |         const QString description = QApplication::translate("CppTools::QuickFix", "Mark as Translatable"); | 
					
						
							|  |  |  |         QList<CppQuickFixOperation::Ptr> result; | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |         for (int i = path.size() - 1; i >= 0; --i) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             if (FunctionDefinitionAST *definition = path.at(i)->asFunctionDefinition()) { | 
					
						
							|  |  |  |                 Function *function = definition->symbol; | 
					
						
							| 
									
										
										
										
											2011-04-15 16:19:23 +02:00
										 |  |  |                 ClassOrNamespace *b = interface->context().lookupType(function); | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |                 if (b) { | 
					
						
							|  |  |  |                     // Do we have a tr method?
 | 
					
						
							|  |  |  |                     foreach(const LookupItem &r, b->find(trName)) { | 
					
						
							|  |  |  |                         Symbol *s = r.declaration(); | 
					
						
							|  |  |  |                         if (s->type()->isFunctionType()) { | 
					
						
							|  |  |  |                             // no context required for tr
 | 
					
						
							| 
									
										
										
										
											2011-12-14 14:23:25 +01:00
										 |  |  |                             return singleResult(new WrapStringLiteral::Operation(interface, path.size() - 1, | 
					
						
							|  |  |  |                                                                                  WrapStringLiteral::TranslateTrAction, | 
					
						
							|  |  |  |                                                                                  description, literal)); | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |                         } | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 // We need to do a QCA::translate, so we need a context.
 | 
					
						
							|  |  |  |                 // Use fully qualified class name:
 | 
					
						
							|  |  |  |                 Overview oo; | 
					
						
							|  |  |  |                 foreach (const Name *n, LookupContext::path(function)) { | 
					
						
							|  |  |  |                     if (!trContext.isEmpty()) | 
					
						
							|  |  |  |                         trContext.append(QLatin1String("::")); | 
					
						
							|  |  |  |                     trContext.append(oo.prettyName(n)); | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 // ... or global if none available!
 | 
					
						
							|  |  |  |                 if (trContext.isEmpty()) | 
					
						
							|  |  |  |                     trContext = QLatin1String("GLOBAL"); | 
					
						
							| 
									
										
										
										
											2011-12-14 14:23:25 +01:00
										 |  |  |                 return singleResult(new WrapStringLiteral::Operation(interface, path.size() - 1, | 
					
						
							|  |  |  |                                                                      WrapStringLiteral::TranslateQCoreApplicationAction, | 
					
						
							|  |  |  |                                                                      description, literal, trContext)); | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // We need to use Q_TRANSLATE_NOOP
 | 
					
						
							| 
									
										
										
										
											2011-12-14 14:23:25 +01:00
										 |  |  |         return singleResult(new WrapStringLiteral::Operation(interface, path.size() - 1, | 
					
						
							|  |  |  |                                                              WrapStringLiteral::TranslateNoopAction, | 
					
						
							|  |  |  |                                                              description, literal, trContext)); | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-07 16:55:34 +01:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * Replace | 
					
						
							|  |  |  |  *    "abcd" | 
					
						
							|  |  |  |  *    QLatin1String("abcd") | 
					
						
							|  |  |  |  *    QLatin1Literal("abcd") | 
					
						
							|  |  |  |  * With | 
					
						
							|  |  |  |  *    @"abcd" | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Activates on: the string literal, if the file type is a Objective-C(++) file. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  | class CStringToNSString: public CppQuickFixFactory | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | public: | 
					
						
							| 
									
										
										
										
											2011-04-15 16:19:23 +02:00
										 |  |  |     virtual QList<CppQuickFixOperation::Ptr> match(const QSharedPointer<const CppQuickFixAssistInterface> &interface) | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2011-08-17 11:35:57 +02:00
										 |  |  |         CppRefactoringFilePtr file = interface->currentFile(); | 
					
						
							| 
									
										
										
										
											2010-08-13 12:49:11 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-11 14:26:09 +01:00
										 |  |  |         if (interface->editor()->mimeType() != QLatin1String(CppTools::Constants::OBJECTIVE_CPP_SOURCE_MIMETYPE)) | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |             return noResult(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-14 14:23:25 +01:00
										 |  |  |         WrapStringLiteral::Type type = WrapStringLiteral::TypeNone; | 
					
						
							|  |  |  |         QByteArray enclosingFunction; | 
					
						
							|  |  |  |         CallAST *qlatin1Call; | 
					
						
							| 
									
										
										
										
											2011-04-15 16:19:23 +02:00
										 |  |  |         const QList<AST *> &path = interface->path(); | 
					
						
							| 
									
										
										
										
											2011-12-14 14:23:25 +01:00
										 |  |  |         ExpressionAST *literal = WrapStringLiteral::analyze(path, file, &type, &enclosingFunction, &qlatin1Call); | 
					
						
							|  |  |  |         if (!literal || type != WrapStringLiteral::TypeString) | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |             return noResult(); | 
					
						
							| 
									
										
										
										
											2011-12-14 14:23:25 +01:00
										 |  |  |         if (!isQtStringLiteral(enclosingFunction)) | 
					
						
							|  |  |  |             qlatin1Call = 0; | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-14 14:23:25 +01:00
										 |  |  |         return singleResult(new Operation(interface, path.size() - 1, literal->asStringLiteral(), qlatin1Call)); | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | private: | 
					
						
							|  |  |  |     class Operation: public CppQuickFixOperation | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |     public: | 
					
						
							| 
									
										
										
										
											2011-04-15 16:19:23 +02:00
										 |  |  |         Operation(const QSharedPointer<const CppQuickFixAssistInterface> &interface, int priority, StringLiteralAST *stringLiteral, CallAST *qlatin1Call) | 
					
						
							|  |  |  |             : CppQuickFixOperation(interface, priority) | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |             , stringLiteral(stringLiteral) | 
					
						
							|  |  |  |             , qlatin1Call(qlatin1Call) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             setDescription(QApplication::translate("CppTools::QuickFix", | 
					
						
							|  |  |  |                                                    "Convert to Objective-C String Literal")); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-17 11:35:57 +02:00
										 |  |  |         virtual void performChanges(const CppRefactoringFilePtr ¤tFile, const CppRefactoringChanges &) | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |         { | 
					
						
							|  |  |  |             ChangeSet changes; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (qlatin1Call) { | 
					
						
							| 
									
										
										
										
											2010-08-13 12:49:11 +02:00
										 |  |  |                 changes.replace(currentFile->startOf(qlatin1Call), currentFile->startOf(stringLiteral), QLatin1String("@")); | 
					
						
							|  |  |  |                 changes.remove(currentFile->endOf(stringLiteral), currentFile->endOf(qlatin1Call)); | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |             } else { | 
					
						
							| 
									
										
										
										
											2012-01-11 14:26:09 +01:00
										 |  |  |                 changes.insert(currentFile->startOf(stringLiteral), QLatin1String("@")); | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-17 11:35:57 +02:00
										 |  |  |             currentFile->setChangeSet(changes); | 
					
						
							|  |  |  |             currentFile->apply(); | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     private: | 
					
						
							|  |  |  |         StringLiteralAST *stringLiteral; | 
					
						
							|  |  |  |         CallAST *qlatin1Call; | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |   Base class for converting numeric literals between decimal, octal and hex. | 
					
						
							|  |  |  |   Does the base check for the specific ones and parses the number. | 
					
						
							|  |  |  |   Test cases: | 
					
						
							|  |  |  |     0xFA0Bu; | 
					
						
							|  |  |  |     0X856A; | 
					
						
							|  |  |  |     298.3; | 
					
						
							|  |  |  |     199; | 
					
						
							|  |  |  |     074; | 
					
						
							|  |  |  |     199L; | 
					
						
							|  |  |  |     074L; | 
					
						
							|  |  |  |     -199; | 
					
						
							|  |  |  |     -017; | 
					
						
							|  |  |  |     0783; // invalid octal
 | 
					
						
							|  |  |  |     0; // border case, allow only hex<->decimal
 | 
					
						
							| 
									
										
										
										
											2011-01-07 16:55:34 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     Activates on: numeric literals | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  | */ | 
					
						
							|  |  |  | class ConvertNumericLiteral: public CppQuickFixFactory | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | public: | 
					
						
							| 
									
										
										
										
											2011-04-15 16:19:23 +02:00
										 |  |  |     virtual QList<QuickFixOperation::Ptr> match(const QSharedPointer<const CppQuickFixAssistInterface> &interface) | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |     { | 
					
						
							|  |  |  |         QList<QuickFixOperation::Ptr> result; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-15 16:19:23 +02:00
										 |  |  |         const QList<AST *> &path = interface->path(); | 
					
						
							| 
									
										
										
										
											2011-08-17 11:35:57 +02:00
										 |  |  |         CppRefactoringFilePtr file = interface->currentFile(); | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if (path.isEmpty()) | 
					
						
							|  |  |  |             return result; // nothing to do
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         NumericLiteralAST *literal = path.last()->asNumericLiteral(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (! literal) | 
					
						
							|  |  |  |             return result; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-17 11:35:57 +02:00
										 |  |  |         Token token = file->tokenAt(literal->asNumericLiteral()->literal_token); | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |         if (!token.is(T_NUMERIC_LITERAL)) | 
					
						
							|  |  |  |             return result; | 
					
						
							|  |  |  |         const NumericLiteral *numeric = token.number; | 
					
						
							|  |  |  |         if (numeric->isDouble() || numeric->isFloat()) | 
					
						
							|  |  |  |             return result; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // remove trailing L or U and stuff
 | 
					
						
							|  |  |  |         const char * const spell = numeric->chars(); | 
					
						
							|  |  |  |         int numberLength = numeric->size(); | 
					
						
							| 
									
										
										
										
											2011-10-25 14:06:39 +02:00
										 |  |  |         while (numberLength > 0 && !std::isxdigit(spell[numberLength - 1])) | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |             --numberLength; | 
					
						
							|  |  |  |         if (numberLength < 1) | 
					
						
							|  |  |  |             return result; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // convert to number
 | 
					
						
							|  |  |  |         bool valid; | 
					
						
							|  |  |  |         ulong value = QString::fromUtf8(spell).left(numberLength).toULong(&valid, 0); | 
					
						
							|  |  |  |         if (!valid) // e.g. octal with digit > 7
 | 
					
						
							|  |  |  |             return result; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         const int priority = path.size() - 1; // very high priority
 | 
					
						
							| 
									
										
										
										
											2011-08-17 11:35:57 +02:00
										 |  |  |         const int start = file->startOf(literal); | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |         const char * const str = numeric->chars(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (!numeric->isHex()) { | 
					
						
							|  |  |  |             /*
 | 
					
						
							|  |  |  |               Convert integer literal to hex representation. | 
					
						
							|  |  |  |               Replace | 
					
						
							|  |  |  |                 32 | 
					
						
							|  |  |  |                 040 | 
					
						
							|  |  |  |               With | 
					
						
							|  |  |  |                 0x20 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             */ | 
					
						
							|  |  |  |             QString replacement; | 
					
						
							|  |  |  |             replacement.sprintf("0x%lX", value); | 
					
						
							| 
									
										
										
										
											2011-04-15 16:19:23 +02:00
										 |  |  |             QuickFixOperation::Ptr op(new ConvertNumeric(interface, start, start + numberLength, replacement)); | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |             op->setDescription(QApplication::translate("CppTools::QuickFix", "Convert to Hexadecimal")); | 
					
						
							|  |  |  |             op->setPriority(priority); | 
					
						
							|  |  |  |             result.append(op); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (value != 0) { | 
					
						
							|  |  |  |             if (!(numberLength > 1 && str[0] == '0' && str[1] != 'x' && str[1] != 'X')) { | 
					
						
							|  |  |  |                 /*
 | 
					
						
							|  |  |  |                   Convert integer literal to octal representation. | 
					
						
							|  |  |  |                   Replace | 
					
						
							|  |  |  |                     32 | 
					
						
							|  |  |  |                     0x20 | 
					
						
							|  |  |  |                   With | 
					
						
							|  |  |  |                     040 | 
					
						
							|  |  |  |                 */ | 
					
						
							|  |  |  |                 QString replacement; | 
					
						
							|  |  |  |                 replacement.sprintf("0%lo", value); | 
					
						
							| 
									
										
										
										
											2011-04-15 16:19:23 +02:00
										 |  |  |                 QuickFixOperation::Ptr op(new ConvertNumeric(interface, start, start + numberLength, replacement)); | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |                 op->setDescription(QApplication::translate("CppTools::QuickFix", "Convert to Octal")); | 
					
						
							|  |  |  |                 op->setPriority(priority); | 
					
						
							|  |  |  |                 result.append(op); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (value != 0 || numeric->isHex()) { | 
					
						
							|  |  |  |             if (!(numberLength > 1 && str[0] != '0')) { | 
					
						
							|  |  |  |                 /*
 | 
					
						
							|  |  |  |                   Convert integer literal to decimal representation. | 
					
						
							|  |  |  |                   Replace | 
					
						
							|  |  |  |                     0x20 | 
					
						
							|  |  |  |                     040 | 
					
						
							|  |  |  |                   With | 
					
						
							|  |  |  |                     32 | 
					
						
							|  |  |  |                 */ | 
					
						
							|  |  |  |                 QString replacement; | 
					
						
							|  |  |  |                 replacement.sprintf("%lu", value); | 
					
						
							| 
									
										
										
										
											2011-04-15 16:19:23 +02:00
										 |  |  |                 QuickFixOperation::Ptr op(new ConvertNumeric(interface, start, start + numberLength, replacement)); | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |                 op->setDescription(QApplication::translate("CppTools::QuickFix", "Convert to Decimal")); | 
					
						
							|  |  |  |                 op->setPriority(priority); | 
					
						
							|  |  |  |                 result.append(op); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return result; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | private: | 
					
						
							|  |  |  |     class ConvertNumeric: public CppQuickFixOperation | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |     public: | 
					
						
							| 
									
										
										
										
											2011-04-15 16:19:23 +02:00
										 |  |  |         ConvertNumeric(const QSharedPointer<const CppQuickFixAssistInterface> &interface, | 
					
						
							|  |  |  |                        int start, int end, const QString &replacement) | 
					
						
							|  |  |  |             : CppQuickFixOperation(interface) | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |             , start(start) | 
					
						
							|  |  |  |             , end(end) | 
					
						
							|  |  |  |             , replacement(replacement) | 
					
						
							|  |  |  |         {} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-17 11:35:57 +02:00
										 |  |  |         virtual void performChanges(const CppRefactoringFilePtr ¤tFile, const CppRefactoringChanges &) | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |         { | 
					
						
							|  |  |  |             ChangeSet changes; | 
					
						
							|  |  |  |             changes.replace(start, end, replacement); | 
					
						
							| 
									
										
										
										
											2011-08-17 11:35:57 +02:00
										 |  |  |             currentFile->setChangeSet(changes); | 
					
						
							|  |  |  |             currentFile->apply(); | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     protected: | 
					
						
							|  |  |  |         int start, end; | 
					
						
							|  |  |  |         QString replacement; | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-07 14:49:00 +01:00
										 |  |  | /*
 | 
					
						
							|  |  |  |     Can be triggered on a class forward declaration to add the matching #include. | 
					
						
							| 
									
										
										
										
											2011-01-07 16:55:34 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     Activates on: the name of a forward-declared class or struct | 
					
						
							| 
									
										
										
										
											2011-01-07 14:49:00 +01:00
										 |  |  | */ | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  | class FixForwardDeclarationOp: public CppQuickFixFactory | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | public: | 
					
						
							| 
									
										
										
										
											2011-04-15 16:19:23 +02:00
										 |  |  |     virtual QList<CppQuickFixOperation::Ptr> match(const QSharedPointer<const CppQuickFixAssistInterface> &interface) | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2011-04-15 16:19:23 +02:00
										 |  |  |         const QList<AST *> &path = interface->path(); | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         for (int index = path.size() - 1; index != -1; --index) { | 
					
						
							|  |  |  |             AST *ast = path.at(index); | 
					
						
							|  |  |  |             if (NamedTypeSpecifierAST *namedTy = ast->asNamedTypeSpecifier()) { | 
					
						
							| 
									
										
										
										
											2011-04-15 16:19:23 +02:00
										 |  |  |                 if (Symbol *fwdClass = checkName(interface, namedTy->name)) | 
					
						
							|  |  |  |                     return singleResult(new Operation(interface, index, fwdClass)); | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |             } else if (ElaboratedTypeSpecifierAST *eTy = ast->asElaboratedTypeSpecifier()) { | 
					
						
							| 
									
										
										
										
											2011-04-15 16:19:23 +02:00
										 |  |  |                 if (Symbol *fwdClass = checkName(interface, eTy->name)) | 
					
						
							|  |  |  |                     return singleResult(new Operation(interface, index, fwdClass)); | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return noResult(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | protected: | 
					
						
							| 
									
										
										
										
											2011-04-15 16:19:23 +02:00
										 |  |  |     static Symbol *checkName(const QSharedPointer<const CppQuickFixAssistInterface> &interface, NameAST *ast) | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2011-04-15 16:19:23 +02:00
										 |  |  |         if (ast && interface->isCursorOn(ast)) { | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |             if (const Name *name = ast->name) { | 
					
						
							|  |  |  |                 unsigned line, column; | 
					
						
							| 
									
										
										
										
											2011-04-15 16:19:23 +02:00
										 |  |  |                 interface->semanticInfo().doc->translationUnit()->getTokenStartPosition(ast->firstToken(), &line, &column); | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |                 Symbol *fwdClass = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-15 16:19:23 +02:00
										 |  |  |                 foreach (const LookupItem &r, | 
					
						
							|  |  |  |                          interface->context().lookup(name, | 
					
						
							|  |  |  |                                                      interface->semanticInfo().doc->scopeAt(line, column))) { | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |                     if (! r.declaration()) | 
					
						
							|  |  |  |                         continue; | 
					
						
							|  |  |  |                     else if (ForwardClassDeclaration *fwd = r.declaration()->asForwardClassDeclaration()) | 
					
						
							|  |  |  |                         fwdClass = fwd; | 
					
						
							|  |  |  |                     else if (r.declaration()->isClass()) | 
					
						
							|  |  |  |                         return 0; // nothing to do.
 | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 return fwdClass; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | private: | 
					
						
							|  |  |  |     class Operation: public CppQuickFixOperation | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |     public: | 
					
						
							| 
									
										
										
										
											2011-04-15 16:19:23 +02:00
										 |  |  |         Operation(const QSharedPointer<const CppQuickFixAssistInterface> &interface, int priority, Symbol *fwdClass) | 
					
						
							|  |  |  |             : CppQuickFixOperation(interface, priority) | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |             , fwdClass(fwdClass) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             setDescription(QApplication::translate("CppTools::QuickFix", | 
					
						
							| 
									
										
										
										
											2010-10-06 16:33:49 +02:00
										 |  |  |                                                    "#include Header File")); | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-17 11:35:57 +02:00
										 |  |  |         virtual void performChanges(const CppRefactoringFilePtr ¤tFile, | 
					
						
							|  |  |  |                                     const CppRefactoringChanges &) | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |         { | 
					
						
							| 
									
										
										
										
											2012-01-23 17:44:49 +01:00
										 |  |  |             QTC_ASSERT(fwdClass != 0, return); | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-23 16:08:01 +01:00
										 |  |  |             CppTools::SymbolFinder symbolFinder; | 
					
						
							| 
									
										
										
										
											2012-01-20 14:43:21 +01:00
										 |  |  |             if (Class *k = | 
					
						
							|  |  |  |                     symbolFinder.findMatchingClassDeclaration(fwdClass, | 
					
						
							|  |  |  |                                                               assistInterface()->snapshot())) { | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |                 const QString headerFile = QString::fromUtf8(k->fileName(), k->fileNameLength()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 // collect the fwd headers
 | 
					
						
							|  |  |  |                 Snapshot fwdHeaders; | 
					
						
							| 
									
										
										
										
											2011-04-15 16:19:23 +02:00
										 |  |  |                 fwdHeaders.insert(assistInterface()->snapshot().document(headerFile)); | 
					
						
							|  |  |  |                 foreach (Document::Ptr doc, assistInterface()->snapshot()) { | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |                     QFileInfo headerFileInfo(doc->fileName()); | 
					
						
							|  |  |  |                     if (doc->globalSymbolCount() == 0 && doc->includes().size() == 1) | 
					
						
							|  |  |  |                         fwdHeaders.insert(doc); | 
					
						
							|  |  |  |                     else if (headerFileInfo.suffix().isEmpty()) | 
					
						
							|  |  |  |                         fwdHeaders.insert(doc); | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 DependencyTable dep; | 
					
						
							|  |  |  |                 dep.build(fwdHeaders); | 
					
						
							|  |  |  |                 QStringList candidates = dep.dependencyTable().value(headerFile); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 const QString className = QString::fromUtf8(k->identifier()->chars()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 QString best; | 
					
						
							|  |  |  |                 foreach (const QString &c, candidates) { | 
					
						
							|  |  |  |                     QFileInfo headerFileInfo(c); | 
					
						
							|  |  |  |                     if (headerFileInfo.fileName() == className) { | 
					
						
							|  |  |  |                         best = c; | 
					
						
							|  |  |  |                         break; | 
					
						
							|  |  |  |                     } else if (headerFileInfo.fileName().at(0).isUpper()) { | 
					
						
							|  |  |  |                         best = c; | 
					
						
							|  |  |  |                         // and continue
 | 
					
						
							|  |  |  |                     } else if (! best.isEmpty()) { | 
					
						
							|  |  |  |                         if (c.count(QLatin1Char('/')) < best.count(QLatin1Char('/'))) | 
					
						
							|  |  |  |                             best = c; | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 if (best.isEmpty()) | 
					
						
							|  |  |  |                     best = headerFile; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-13 12:49:11 +02:00
										 |  |  |                 int pos = currentFile->startOf(1); | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-13 12:49:11 +02:00
										 |  |  |                 unsigned currentLine = currentFile->cursor().blockNumber() + 1; | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |                 unsigned bestLine = 0; | 
					
						
							| 
									
										
										
										
											2011-04-15 16:19:23 +02:00
										 |  |  |                 foreach (const Document::Include &incl, assistInterface()->semanticInfo().doc->includes()) { | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |                     if (incl.line() < currentLine) | 
					
						
							|  |  |  |                         bestLine = incl.line(); | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 if (bestLine) | 
					
						
							| 
									
										
										
										
											2010-08-13 12:49:11 +02:00
										 |  |  |                     pos = currentFile->document()->findBlockByNumber(bestLine).position(); | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |                 Utils::ChangeSet changes; | 
					
						
							| 
									
										
										
										
											2012-01-11 14:26:09 +01:00
										 |  |  |                 changes.insert(pos, QLatin1String("#include <") | 
					
						
							|  |  |  |                                + QFileInfo(best).fileName() + QLatin1String(">\n")); | 
					
						
							| 
									
										
										
										
											2011-08-17 11:35:57 +02:00
										 |  |  |                 currentFile->setChangeSet(changes); | 
					
						
							|  |  |  |                 currentFile->apply(); | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     private: | 
					
						
							|  |  |  |         Symbol *fwdClass; | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-07 14:49:00 +01:00
										 |  |  | /*
 | 
					
						
							|  |  |  |   Rewrites | 
					
						
							|  |  |  |     a = foo(); | 
					
						
							|  |  |  |   As | 
					
						
							|  |  |  |     Type a = foo(); | 
					
						
							|  |  |  |   Where Type is the return type of foo() | 
					
						
							| 
									
										
										
										
											2011-01-07 16:55:34 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     Activates on: the assignee, if the type of the right-hand side of the assignment is known. | 
					
						
							| 
									
										
										
										
											2011-01-07 14:49:00 +01:00
										 |  |  | */ | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  | class AddLocalDeclarationOp: public CppQuickFixFactory | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | public: | 
					
						
							| 
									
										
										
										
											2011-04-15 16:19:23 +02:00
										 |  |  |     virtual QList<CppQuickFixOperation::Ptr> match(const QSharedPointer<const CppQuickFixAssistInterface> &interface) | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2011-04-15 16:19:23 +02:00
										 |  |  |         const QList<AST *> &path = interface->path(); | 
					
						
							| 
									
										
										
										
											2011-08-17 11:35:57 +02:00
										 |  |  |         CppRefactoringFilePtr file = interface->currentFile(); | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         for (int index = path.size() - 1; index != -1; --index) { | 
					
						
							|  |  |  |             if (BinaryExpressionAST *binary = path.at(index)->asBinaryExpression()) { | 
					
						
							| 
									
										
										
										
											2011-08-17 11:35:57 +02:00
										 |  |  |                 if (binary->left_expression && binary->right_expression && file->tokenAt(binary->binary_op_token).is(T_EQUAL)) { | 
					
						
							| 
									
										
										
										
											2010-08-02 12:04:59 +02:00
										 |  |  |                     IdExpressionAST *idExpr = binary->left_expression->asIdExpression(); | 
					
						
							| 
									
										
										
										
											2011-04-15 16:19:23 +02:00
										 |  |  |                     if (interface->isCursorOn(binary->left_expression) && idExpr && idExpr->name->asSimpleName() != 0) { | 
					
						
							| 
									
										
										
										
											2010-08-02 12:04:59 +02:00
										 |  |  |                         SimpleNameAST *nameAST = idExpr->name->asSimpleName(); | 
					
						
							| 
									
										
										
										
											2011-08-17 11:35:57 +02:00
										 |  |  |                         const QList<LookupItem> results = interface->context().lookup(nameAST->name, file->scopeAt(nameAST->firstToken())); | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |                         Declaration *decl = 0; | 
					
						
							|  |  |  |                         foreach (const LookupItem &r, results) { | 
					
						
							|  |  |  |                             if (! r.declaration()) | 
					
						
							|  |  |  |                                 continue; | 
					
						
							|  |  |  |                             else if (Declaration *d = r.declaration()->asDeclaration()) { | 
					
						
							|  |  |  |                                 if (! d->type()->isFunctionType()) { | 
					
						
							|  |  |  |                                     decl = d; | 
					
						
							|  |  |  |                                     break; | 
					
						
							|  |  |  |                                 } | 
					
						
							|  |  |  |                             } | 
					
						
							|  |  |  |                         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                         if (! decl) { | 
					
						
							| 
									
										
										
										
											2011-04-15 16:19:23 +02:00
										 |  |  |                             return singleResult(new Operation(interface, index, binary)); | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |                         } | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return noResult(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | private: | 
					
						
							|  |  |  |     class Operation: public CppQuickFixOperation | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |     public: | 
					
						
							| 
									
										
										
										
											2011-04-15 16:19:23 +02:00
										 |  |  |         Operation(const QSharedPointer<const CppQuickFixAssistInterface> &interface, int priority, BinaryExpressionAST *binaryAST) | 
					
						
							|  |  |  |             : CppQuickFixOperation(interface, priority) | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |             , binaryAST(binaryAST) | 
					
						
							|  |  |  |         { | 
					
						
							| 
									
										
										
										
											2011-04-14 20:32:13 +02:00
										 |  |  |             setDescription(QApplication::translate("CppTools::QuickFix", "Add Local Declaration")); | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-17 11:35:57 +02:00
										 |  |  |         virtual void performChanges(const CppRefactoringFilePtr ¤tFile, | 
					
						
							|  |  |  |                                     const CppRefactoringChanges &) | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |         { | 
					
						
							|  |  |  |             TypeOfExpression typeOfExpression; | 
					
						
							| 
									
										
										
										
											2011-04-15 16:19:23 +02:00
										 |  |  |             typeOfExpression.init(assistInterface()->semanticInfo().doc, | 
					
						
							|  |  |  |                                   assistInterface()->snapshot(), assistInterface()->context().bindings()); | 
					
						
							| 
									
										
										
										
											2011-08-15 13:02:51 +02:00
										 |  |  |             Scope *scope = currentFile->scopeAt(binaryAST->firstToken()); | 
					
						
							| 
									
										
										
										
											2012-01-12 17:35:37 +01:00
										 |  |  |             const QList<LookupItem> result = | 
					
						
							|  |  |  |                     typeOfExpression(currentFile->textOf(binaryAST->right_expression).toUtf8(), | 
					
						
							|  |  |  |                                      scope, | 
					
						
							|  |  |  |                                      TypeOfExpression::Preprocess); | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |             if (! result.isEmpty()) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 SubstitutionEnvironment env; | 
					
						
							| 
									
										
										
										
											2011-04-15 16:19:23 +02:00
										 |  |  |                 env.setContext(assistInterface()->context()); | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |                 env.switchScope(result.first().scope()); | 
					
						
							| 
									
										
										
										
											2011-08-15 13:02:51 +02:00
										 |  |  |                 ClassOrNamespace *con = typeOfExpression.context().lookupType(scope); | 
					
						
							|  |  |  |                 if (!con) | 
					
						
							|  |  |  |                     con = typeOfExpression.context().globalNamespace(); | 
					
						
							|  |  |  |                 UseMinimalNames q(con); | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |                 env.enter(&q); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-15 16:19:23 +02:00
										 |  |  |                 Control *control = assistInterface()->context().control().data(); | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |                 FullySpecifiedType tn = rewriteType(result.first().type(), &env, control); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 Overview oo; | 
					
						
							|  |  |  |                 QString ty = oo(tn); | 
					
						
							|  |  |  |                 if (! ty.isEmpty()) { | 
					
						
							|  |  |  |                     const QChar ch = ty.at(ty.size() - 1); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                     if (ch.isLetterOrNumber() || ch == QLatin1Char(' ') || ch == QLatin1Char('>')) | 
					
						
							|  |  |  |                         ty += QLatin1Char(' '); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                     Utils::ChangeSet changes; | 
					
						
							| 
									
										
										
										
											2010-08-13 12:49:11 +02:00
										 |  |  |                     changes.insert(currentFile->startOf(binaryAST), ty); | 
					
						
							| 
									
										
										
										
											2011-08-17 11:35:57 +02:00
										 |  |  |                     currentFile->setChangeSet(changes); | 
					
						
							|  |  |  |                     currentFile->apply(); | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     private: | 
					
						
							|  |  |  |         BinaryExpressionAST *binaryAST; | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-07 16:55:34 +01:00
										 |  |  | /**
 | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |  * Turns "an_example_symbol" into "anExampleSymbol" and | 
					
						
							|  |  |  |  * "AN_EXAMPLE_SYMBOL" into "AnExampleSymbol". | 
					
						
							| 
									
										
										
										
											2011-01-07 16:55:34 +01:00
										 |  |  |  * | 
					
						
							|  |  |  |  * Activates on: identifiers | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |  */ | 
					
						
							|  |  |  | class ToCamelCaseConverter : public CppQuickFixFactory | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | public: | 
					
						
							| 
									
										
										
										
											2011-04-15 16:19:23 +02:00
										 |  |  |     virtual QList<CppQuickFixOperation::Ptr> match(const QSharedPointer<const CppQuickFixAssistInterface> &interface) | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2011-04-15 16:19:23 +02:00
										 |  |  |         const QList<AST *> &path = interface->path(); | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if (path.isEmpty()) | 
					
						
							|  |  |  |             return noResult(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         AST * const ast = path.last(); | 
					
						
							|  |  |  |         const Name *name = 0; | 
					
						
							|  |  |  |         if (const NameAST * const nameAst = ast->asName()) { | 
					
						
							|  |  |  |             if (nameAst->name && nameAst->name->asNameId()) | 
					
						
							|  |  |  |                 name = nameAst->name; | 
					
						
							|  |  |  |         } else if (const NamespaceAST * const namespaceAst = ast->asNamespace()) { | 
					
						
							|  |  |  |             name = namespaceAst->symbol->name(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (!name) | 
					
						
							|  |  |  |             return noResult(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         QString newName = QString::fromUtf8(name->identifier()->chars()); | 
					
						
							|  |  |  |         if (newName.length() < 3) | 
					
						
							|  |  |  |             return noResult(); | 
					
						
							|  |  |  |         for (int i = 1; i < newName.length() - 1; ++i) { | 
					
						
							|  |  |  |             if (Operation::isConvertibleUnderscore(newName, i)) | 
					
						
							| 
									
										
										
										
											2011-04-15 16:19:23 +02:00
										 |  |  |                 return singleResult(new Operation(interface, path.size() - 1, newName)); | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return noResult(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | private: | 
					
						
							|  |  |  |     class Operation: public CppQuickFixOperation | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |     public: | 
					
						
							| 
									
										
										
										
											2011-04-15 16:19:23 +02:00
										 |  |  |         Operation(const QSharedPointer<const CppQuickFixAssistInterface> &interface, int priority, const QString &newName) | 
					
						
							|  |  |  |             : CppQuickFixOperation(interface, priority) | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |             , m_name(newName) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             setDescription(QApplication::translate("CppTools::QuickFix", | 
					
						
							| 
									
										
										
										
											2011-04-14 20:32:13 +02:00
										 |  |  |                                                    "Convert to Camel Case")); | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-08-17 11:35:57 +02:00
										 |  |  |         virtual void performChanges(const CppRefactoringFilePtr &, | 
					
						
							|  |  |  |                                     const CppRefactoringChanges &) | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |         { | 
					
						
							|  |  |  |             for (int i = 1; i < m_name.length(); ++i) { | 
					
						
							|  |  |  |                 QCharRef c = m_name[i]; | 
					
						
							|  |  |  |                 if (c.isUpper()) { | 
					
						
							|  |  |  |                     c = c.toLower(); | 
					
						
							|  |  |  |                 } else if (i < m_name.length() - 1 | 
					
						
							|  |  |  |                            && isConvertibleUnderscore(m_name, i)) { | 
					
						
							|  |  |  |                     m_name.remove(i, 1); | 
					
						
							|  |  |  |                     m_name[i] = m_name.at(i).toUpper(); | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2011-04-15 16:19:23 +02:00
										 |  |  |             static_cast<CppEditor::Internal::CPPEditorWidget*>(assistInterface()->editor())->renameUsagesNow(m_name); | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         static bool isConvertibleUnderscore(const QString &name, int pos) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             return name.at(pos) == QLatin1Char('_') && name.at(pos+1).isLetter() | 
					
						
							|  |  |  |                     && !(pos == 1 && name.at(0) == QLatin1Char('m')); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     private: | 
					
						
							|  |  |  |         QString m_name; | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-11-25 12:05:58 +01:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * Adds an include for an undefined identifier. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | class IncludeAdder : public CppQuickFixFactory | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | public: | 
					
						
							|  |  |  |     virtual QList<CppQuickFixOperation::Ptr> match(const QSharedPointer<const CppQuickFixAssistInterface> &interface) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         CppClassesFilter *classesFilter = ExtensionSystem::PluginManager::instance()->getObject<CppClassesFilter>(); | 
					
						
							|  |  |  |         if (!classesFilter) | 
					
						
							|  |  |  |             return noResult(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         const QList<AST *> &path = interface->path(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (path.isEmpty()) | 
					
						
							|  |  |  |             return noResult(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // find the largest enclosing Name
 | 
					
						
							|  |  |  |         const NameAST *enclosingName = 0; | 
					
						
							|  |  |  |         const SimpleNameAST *innermostName = 0; | 
					
						
							|  |  |  |         for (int i = path.size() - 1; i >= 0; --i) { | 
					
						
							|  |  |  |             if (NameAST *nameAst = path.at(i)->asName()) { | 
					
						
							|  |  |  |                 enclosingName = nameAst; | 
					
						
							|  |  |  |                 if (!innermostName) { | 
					
						
							|  |  |  |                     innermostName = nameAst->asSimpleName(); | 
					
						
							|  |  |  |                     if (!innermostName) | 
					
						
							|  |  |  |                         return noResult(); | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } else { | 
					
						
							|  |  |  |                 break; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if (!enclosingName || !enclosingName->name) | 
					
						
							|  |  |  |             return noResult(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // find the enclosing scope
 | 
					
						
							|  |  |  |         unsigned line, column; | 
					
						
							|  |  |  |         const Document::Ptr &doc = interface->semanticInfo().doc; | 
					
						
							|  |  |  |         doc->translationUnit()->getTokenStartPosition(enclosingName->firstToken(), &line, &column); | 
					
						
							|  |  |  |         Scope *scope = doc->scopeAt(line, column); | 
					
						
							|  |  |  |         if (!scope) | 
					
						
							|  |  |  |             return noResult(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // check if the name resolves to something
 | 
					
						
							|  |  |  |         QList<LookupItem> existingResults = interface->context().lookup(enclosingName->name, scope); | 
					
						
							|  |  |  |         if (!existingResults.isEmpty()) | 
					
						
							|  |  |  |             return noResult(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         const QString &className = Overview()(innermostName->name); | 
					
						
							|  |  |  |         if (className.isEmpty()) | 
					
						
							|  |  |  |             return noResult(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         QList<CppQuickFixOperation::Ptr> results; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // find the include paths
 | 
					
						
							|  |  |  |         QStringList includePaths; | 
					
						
							|  |  |  |         CppModelManagerInterface *modelManager = CppModelManagerInterface::instance(); | 
					
						
							|  |  |  |         QList<CppModelManagerInterface::ProjectInfo> projectInfos = modelManager->projectInfos(); | 
					
						
							|  |  |  |         bool inProject = false; | 
					
						
							|  |  |  |         foreach (const CppModelManagerInterface::ProjectInfo &info, projectInfos) { | 
					
						
							|  |  |  |             if (info.sourceFiles.contains(doc->fileName())) { | 
					
						
							|  |  |  |                 inProject = true; | 
					
						
							|  |  |  |                 includePaths += info.includePaths; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if (!inProject) { | 
					
						
							|  |  |  |             // better use all include paths than none
 | 
					
						
							|  |  |  |             foreach (const CppModelManagerInterface::ProjectInfo &info, projectInfos) | 
					
						
							|  |  |  |                 includePaths += info.includePaths; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // find a include file through the locator
 | 
					
						
							|  |  |  |         QFutureInterface<Locator::FilterEntry> dummyInterface; | 
					
						
							|  |  |  |         QList<Locator::FilterEntry> matches = classesFilter->matchesFor(dummyInterface, className); | 
					
						
							|  |  |  |         bool classExists = false; | 
					
						
							|  |  |  |         foreach (const Locator::FilterEntry &entry, matches) { | 
					
						
							|  |  |  |             const ModelItemInfo info = entry.internalData.value<ModelItemInfo>(); | 
					
						
							|  |  |  |             if (info.symbolName != className) | 
					
						
							|  |  |  |                 continue; | 
					
						
							|  |  |  |             classExists = true; | 
					
						
							|  |  |  |             const QString &fileName = info.fileName; | 
					
						
							|  |  |  |             const QFileInfo fileInfo(fileName); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             // find the shortest way to include fileName given the includePaths
 | 
					
						
							|  |  |  |             QString shortestInclude; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (fileInfo.path() == QFileInfo(doc->fileName()).path()) { | 
					
						
							| 
									
										
										
										
											2012-01-11 14:26:09 +01:00
										 |  |  |                 shortestInclude = QLatin1Char('"') + fileInfo.fileName() + QLatin1Char('"'); | 
					
						
							| 
									
										
										
										
											2011-11-25 12:05:58 +01:00
										 |  |  |             } else { | 
					
						
							|  |  |  |                 foreach (const QString &includePath, includePaths) { | 
					
						
							|  |  |  |                     if (!fileName.startsWith(includePath)) | 
					
						
							|  |  |  |                         continue; | 
					
						
							|  |  |  |                     QString relativePath = fileName.mid(includePath.size()); | 
					
						
							|  |  |  |                     if (!relativePath.isEmpty() && relativePath.at(0) == QLatin1Char('/')) | 
					
						
							|  |  |  |                         relativePath = relativePath.mid(1); | 
					
						
							|  |  |  |                     if (shortestInclude.isEmpty() || relativePath.size() + 2 < shortestInclude.size()) | 
					
						
							| 
									
										
										
										
											2012-01-11 14:26:09 +01:00
										 |  |  |                         shortestInclude = QLatin1Char('<') + relativePath + QLatin1Char('>'); | 
					
						
							| 
									
										
										
										
											2011-11-25 12:05:58 +01:00
										 |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (!shortestInclude.isEmpty()) | 
					
						
							|  |  |  |                 results += CppQuickFixOperation::Ptr(new Operation(interface, 0, shortestInclude)); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // for QSomething, propose a <QSomething> include -- if such a class was in the locator
 | 
					
						
							|  |  |  |         if (classExists | 
					
						
							|  |  |  |                 && className.size() > 2 | 
					
						
							|  |  |  |                 && className.at(0) == QLatin1Char('Q') | 
					
						
							|  |  |  |                 && className.at(1).isUpper()) { | 
					
						
							| 
									
										
										
										
											2012-01-11 14:26:09 +01:00
										 |  |  |             const QString include = QLatin1Char('<') + className + QLatin1Char('>'); | 
					
						
							|  |  |  |             results += CppQuickFixOperation::Ptr(new Operation(interface, 1, include)); | 
					
						
							| 
									
										
										
										
											2011-11-25 12:05:58 +01:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return results; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | private: | 
					
						
							|  |  |  |     class Operation: public CppQuickFixOperation | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |     public: | 
					
						
							|  |  |  |         Operation(const QSharedPointer<const CppQuickFixAssistInterface> &interface, int priority, const QString &include) | 
					
						
							|  |  |  |             : CppQuickFixOperation(interface, priority) | 
					
						
							|  |  |  |             , m_include(include) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             setDescription(QApplication::translate("CppTools::QuickFix", | 
					
						
							|  |  |  |                                                    "Add #include %1").arg(m_include)); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         virtual void performChanges(const CppRefactoringFilePtr &file, | 
					
						
							|  |  |  |                                     const CppRefactoringChanges &) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             // find location of last include in file
 | 
					
						
							|  |  |  |             QList<Document::Include> includes = file->cppDocument()->includes(); | 
					
						
							|  |  |  |             unsigned lastIncludeLine = 0; | 
					
						
							|  |  |  |             foreach (const Document::Include &include, includes) { | 
					
						
							|  |  |  |                 if (include.line() > lastIncludeLine) | 
					
						
							|  |  |  |                     lastIncludeLine = include.line(); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             // add include
 | 
					
						
							|  |  |  |             const int insertPos = file->position(lastIncludeLine + 1, 1) - 1; | 
					
						
							|  |  |  |             ChangeSet changes; | 
					
						
							| 
									
										
										
										
											2012-01-11 14:26:09 +01:00
										 |  |  |             changes.insert(insertPos, QLatin1String("\n#include ") + m_include); | 
					
						
							| 
									
										
										
										
											2011-11-25 12:05:58 +01:00
										 |  |  |             file->setChangeSet(changes); | 
					
						
							|  |  |  |             file->apply(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     private: | 
					
						
							|  |  |  |         QString m_include; | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-21 18:24:14 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  | } // end of anonymous namespace
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-15 16:19:23 +02:00
										 |  |  | void registerQuickFixes(ExtensionSystem::IPlugin *plugIn) | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     plugIn->addAutoReleasedObject(new UseInverseOp); | 
					
						
							|  |  |  |     plugIn->addAutoReleasedObject(new FlipBinaryOp); | 
					
						
							|  |  |  |     plugIn->addAutoReleasedObject(new RewriteLogicalAndOp); | 
					
						
							|  |  |  |     plugIn->addAutoReleasedObject(new SplitSimpleDeclarationOp); | 
					
						
							|  |  |  |     plugIn->addAutoReleasedObject(new AddBracesToIfOp); | 
					
						
							|  |  |  |     plugIn->addAutoReleasedObject(new MoveDeclarationOutOfIfOp); | 
					
						
							|  |  |  |     plugIn->addAutoReleasedObject(new MoveDeclarationOutOfWhileOp); | 
					
						
							|  |  |  |     plugIn->addAutoReleasedObject(new SplitIfStatementOp); | 
					
						
							|  |  |  |     plugIn->addAutoReleasedObject(new WrapStringLiteral); | 
					
						
							|  |  |  |     plugIn->addAutoReleasedObject(new TranslateStringLiteral); | 
					
						
							|  |  |  |     plugIn->addAutoReleasedObject(new CStringToNSString); | 
					
						
							|  |  |  |     plugIn->addAutoReleasedObject(new ConvertNumericLiteral); | 
					
						
							| 
									
										
										
										
											2011-04-15 16:19:23 +02:00
										 |  |  |     plugIn->addAutoReleasedObject(new CompleteSwitchCaseStatement); | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  |     plugIn->addAutoReleasedObject(new FixForwardDeclarationOp); | 
					
						
							|  |  |  |     plugIn->addAutoReleasedObject(new AddLocalDeclarationOp); | 
					
						
							|  |  |  |     plugIn->addAutoReleasedObject(new ToCamelCaseConverter); | 
					
						
							| 
									
										
										
										
											2011-04-15 16:19:23 +02:00
										 |  |  |     plugIn->addAutoReleasedObject(new InsertQtPropertyMembers); | 
					
						
							|  |  |  |     plugIn->addAutoReleasedObject(new DeclFromDef); | 
					
						
							|  |  |  |     plugIn->addAutoReleasedObject(new DefFromDecl); | 
					
						
							| 
									
										
										
										
											2011-09-05 10:33:17 +02:00
										 |  |  |     plugIn->addAutoReleasedObject(new ApplyDeclDefLinkChanges); | 
					
						
							| 
									
										
										
										
											2011-11-25 12:05:58 +01:00
										 |  |  |     plugIn->addAutoReleasedObject(new IncludeAdder); | 
					
						
							| 
									
										
										
										
											2011-12-21 18:24:14 +01:00
										 |  |  |     plugIn->addAutoReleasedObject(new ExtractFunction); | 
					
						
							| 
									
										
										
										
											2010-07-26 13:06:33 +02:00
										 |  |  | } |