| 
									
										
										
										
											2012-10-02 09:12:39 +02:00
										 |  |  | /****************************************************************************
 | 
					
						
							| 
									
										
										
										
											2010-06-30 13:42:35 +02:00
										 |  |  | ** | 
					
						
							| 
									
										
										
										
											2013-01-28 17:12:19 +01:00
										 |  |  | ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). | 
					
						
							| 
									
										
										
										
											2012-10-02 09:12:39 +02:00
										 |  |  | ** Contact: http://www.qt-project.org/legal
 | 
					
						
							| 
									
										
										
										
											2010-06-30 13:42:35 +02:00
										 |  |  | ** | 
					
						
							| 
									
										
										
										
											2012-10-02 09:12:39 +02:00
										 |  |  | ** This file is part of Qt Creator. | 
					
						
							| 
									
										
										
										
											2010-06-30 13:42:35 +02:00
										 |  |  | ** | 
					
						
							| 
									
										
										
										
											2012-10-02 09:12:39 +02:00
										 |  |  | ** Commercial License Usage | 
					
						
							|  |  |  | ** Licensees holding valid commercial Qt licenses may use this file in | 
					
						
							|  |  |  | ** accordance with the commercial license agreement provided with the | 
					
						
							|  |  |  | ** Software or, alternatively, in accordance with the terms contained in | 
					
						
							|  |  |  | ** a written agreement between you and Digia.  For licensing terms and | 
					
						
							|  |  |  | ** conditions see http://qt.digia.com/licensing.  For further information
 | 
					
						
							|  |  |  | ** use the contact form at http://qt.digia.com/contact-us.
 | 
					
						
							| 
									
										
										
										
											2010-06-30 13:42:35 +02:00
										 |  |  | ** | 
					
						
							|  |  |  | ** GNU Lesser General Public License Usage | 
					
						
							| 
									
										
										
										
											2012-10-02 09:12:39 +02:00
										 |  |  | ** Alternatively, 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.
 | 
					
						
							|  |  |  | ** | 
					
						
							|  |  |  | ** In addition, as a special exception, Digia gives you certain additional | 
					
						
							|  |  |  | ** rights.  These rights are described in the Digia Qt LGPL Exception | 
					
						
							| 
									
										
										
										
											2010-12-17 16:01:08 +01:00
										 |  |  | ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. | 
					
						
							|  |  |  | ** | 
					
						
							| 
									
										
										
										
											2012-10-02 09:12:39 +02:00
										 |  |  | ****************************************************************************/ | 
					
						
							| 
									
										
										
										
											2010-06-30 13:42:35 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include "qmljsrewriter.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <qmljs/parser/qmljsast_p.h>
 | 
					
						
							| 
									
										
										
										
											2011-10-07 14:04:06 +02:00
										 |  |  | #include <qmljs/qmljsutils.h>
 | 
					
						
							| 
									
										
										
										
											2010-06-30 13:42:35 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | // ### FIXME: remove these includes:
 | 
					
						
							| 
									
										
										
										
											2012-02-15 10:42:41 +01:00
										 |  |  | #include <QTextBlock>
 | 
					
						
							|  |  |  | #include <QTextCursor>
 | 
					
						
							|  |  |  | #include <QTextDocument>
 | 
					
						
							| 
									
										
										
										
											2010-06-30 13:42:35 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | using namespace QmlJS; | 
					
						
							|  |  |  | using namespace QmlJS::AST; | 
					
						
							|  |  |  | using namespace Utils; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Rewriter::Rewriter(const QString &originalText, | 
					
						
							|  |  |  |                    ChangeSet *changeSet, | 
					
						
							|  |  |  |                    const QStringList &propertyOrder) | 
					
						
							|  |  |  |     : m_originalText(originalText) | 
					
						
							|  |  |  |     , m_changeSet(changeSet) | 
					
						
							|  |  |  |     , m_propertyOrder(propertyOrder) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     Q_ASSERT(changeSet); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-21 12:21:29 +02:00
										 |  |  | Rewriter::Range Rewriter::addBinding(AST::UiObjectInitializer *ast, | 
					
						
							|  |  |  |                                      const QString &propertyName, | 
					
						
							|  |  |  |                                      const QString &propertyValue, | 
					
						
							|  |  |  |                                      BindingType bindingType) | 
					
						
							| 
									
										
										
										
											2010-07-21 09:19:51 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     UiObjectMemberList *insertAfter = searchMemberToInsertAfter(ast->members, | 
					
						
							|  |  |  |                                                                 propertyName, | 
					
						
							|  |  |  |                                                                 m_propertyOrder); | 
					
						
							| 
									
										
										
										
											2010-07-21 12:21:29 +02:00
										 |  |  |     return addBinding(ast, propertyName, propertyValue, bindingType, insertAfter); | 
					
						
							| 
									
										
										
										
											2010-07-21 09:19:51 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-21 12:21:29 +02:00
										 |  |  | Rewriter::Range Rewriter::addBinding(AST::UiObjectInitializer *ast, | 
					
						
							|  |  |  |                                      const QString &propertyName, | 
					
						
							|  |  |  |                                      const QString &propertyValue, | 
					
						
							|  |  |  |                                      BindingType bindingType, | 
					
						
							|  |  |  |                                      UiObjectMemberList *insertAfter) | 
					
						
							| 
									
										
										
										
											2010-06-30 13:42:35 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     SourceLocation endOfPreviousMember; | 
					
						
							|  |  |  |     SourceLocation startOfNextMember; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (insertAfter == 0 || insertAfter->member == 0) { | 
					
						
							|  |  |  |         // insert as first member
 | 
					
						
							|  |  |  |         endOfPreviousMember = ast->lbraceToken; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (ast->members && ast->members->member) | 
					
						
							|  |  |  |             startOfNextMember = ast->members->member->firstSourceLocation(); | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |             startOfNextMember = ast->rbraceToken; | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |         endOfPreviousMember = insertAfter->member->lastSourceLocation(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (insertAfter->next && insertAfter->next->member) | 
					
						
							|  |  |  |             startOfNextMember = insertAfter->next->member->firstSourceLocation(); | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |             startOfNextMember = ast->rbraceToken; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     const bool isOneLiner = endOfPreviousMember.startLine == startOfNextMember.startLine; | 
					
						
							|  |  |  |     bool needsPreceedingSemicolon = false; | 
					
						
							|  |  |  |     bool needsTrailingSemicolon = false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (isOneLiner) { | 
					
						
							|  |  |  |         if (insertAfter == 0) { // we're inserting after an lbrace
 | 
					
						
							|  |  |  |             if (ast->members) { // we're inserting before a member (and not the rbrace)
 | 
					
						
							|  |  |  |                 needsTrailingSemicolon = bindingType == ScriptBinding; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } else { // we're inserting after a member, not after the lbrace
 | 
					
						
							|  |  |  |             if (endOfPreviousMember.isValid()) { // there already is a semicolon after the previous member
 | 
					
						
							|  |  |  |                 if (insertAfter->next && insertAfter->next->member) { // and the after us there is a member, not an rbrace, so:
 | 
					
						
							|  |  |  |                     needsTrailingSemicolon = bindingType == ScriptBinding; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } else { // there is no semicolon after the previous member (probably because there is an rbrace after us/it, so:
 | 
					
						
							|  |  |  |                 needsPreceedingSemicolon = true; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     QString newPropertyTemplate; | 
					
						
							|  |  |  |     switch (bindingType) { | 
					
						
							|  |  |  |     case ArrayBinding: | 
					
						
							|  |  |  |         newPropertyTemplate = QLatin1String("%1: [\n%2\n]"); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case ObjectBinding: | 
					
						
							|  |  |  |         newPropertyTemplate = QLatin1String("%1: %2"); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case ScriptBinding: | 
					
						
							|  |  |  |         newPropertyTemplate = QLatin1String("%1: %2"); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     default: | 
					
						
							|  |  |  |         Q_ASSERT(!"unknown property type"); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (isOneLiner) { | 
					
						
							|  |  |  |         if (needsPreceedingSemicolon) | 
					
						
							|  |  |  |             newPropertyTemplate.prepend(QLatin1Char(';')); | 
					
						
							|  |  |  |         newPropertyTemplate.prepend(QLatin1Char(' ')); | 
					
						
							|  |  |  |         if (needsTrailingSemicolon) | 
					
						
							|  |  |  |             newPropertyTemplate.append(QLatin1Char(';')); | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |         newPropertyTemplate.prepend(QLatin1Char('\n')); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-07 13:05:25 +02:00
										 |  |  |     m_changeSet->insert(endOfPreviousMember.end(), | 
					
						
							| 
									
										
										
										
											2010-06-30 13:42:35 +02:00
										 |  |  |                          newPropertyTemplate.arg(propertyName, propertyValue)); | 
					
						
							| 
									
										
										
										
											2010-07-21 12:21:29 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     return Range(endOfPreviousMember.end(), endOfPreviousMember.end()); | 
					
						
							| 
									
										
										
										
											2010-06-30 13:42:35 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | UiObjectMemberList *Rewriter::searchMemberToInsertAfter(UiObjectMemberList *members, | 
					
						
							|  |  |  |                                                         const QStringList &propertyOrder) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2011-05-10 15:19:38 +02:00
										 |  |  |     const int objectDefinitionInsertionPoint = propertyOrder.indexOf(QString()); | 
					
						
							| 
									
										
										
										
											2010-06-30 13:42:35 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     UiObjectMemberList *lastObjectDef = 0; | 
					
						
							|  |  |  |     UiObjectMemberList *lastNonObjectDef = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (UiObjectMemberList *iter = members; iter; iter = iter->next) { | 
					
						
							|  |  |  |         UiObjectMember *member = iter->member; | 
					
						
							|  |  |  |         int idx = -1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (cast<UiObjectDefinition*>(member)) | 
					
						
							|  |  |  |             lastObjectDef = iter; | 
					
						
							|  |  |  |         else if (UiArrayBinding *arrayBinding = cast<UiArrayBinding*>(member)) | 
					
						
							| 
									
										
										
										
											2011-10-07 14:04:06 +02:00
										 |  |  |             idx = propertyOrder.indexOf(toString(arrayBinding->qualifiedId)); | 
					
						
							| 
									
										
										
										
											2010-06-30 13:42:35 +02:00
										 |  |  |         else if (UiObjectBinding *objectBinding = cast<UiObjectBinding*>(member)) | 
					
						
							| 
									
										
										
										
											2011-10-07 14:04:06 +02:00
										 |  |  |             idx = propertyOrder.indexOf(toString(objectBinding->qualifiedId)); | 
					
						
							| 
									
										
										
										
											2010-06-30 13:42:35 +02:00
										 |  |  |         else if (UiScriptBinding *scriptBinding = cast<UiScriptBinding*>(member)) | 
					
						
							| 
									
										
										
										
											2011-10-07 14:04:06 +02:00
										 |  |  |             idx = propertyOrder.indexOf(toString(scriptBinding->qualifiedId)); | 
					
						
							| 
									
										
										
										
											2010-06-30 13:42:35 +02:00
										 |  |  |         else if (cast<UiPublicMember*>(member)) | 
					
						
							|  |  |  |             idx = propertyOrder.indexOf(QLatin1String("property")); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (idx < objectDefinitionInsertionPoint) | 
					
						
							|  |  |  |             lastNonObjectDef = iter; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (lastObjectDef) | 
					
						
							|  |  |  |         return lastObjectDef; | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |         return lastNonObjectDef; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-12 18:05:50 +02:00
										 |  |  | UiArrayMemberList *Rewriter::searchMemberToInsertAfter(UiArrayMemberList *members, | 
					
						
							|  |  |  |                                                         const QStringList &propertyOrder) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2011-05-10 15:19:38 +02:00
										 |  |  |     const int objectDefinitionInsertionPoint = propertyOrder.indexOf(QString()); | 
					
						
							| 
									
										
										
										
											2010-08-12 18:05:50 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     UiArrayMemberList *lastObjectDef = 0; | 
					
						
							|  |  |  |     UiArrayMemberList *lastNonObjectDef = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (UiArrayMemberList *iter = members; iter; iter = iter->next) { | 
					
						
							|  |  |  |         UiObjectMember *member = iter->member; | 
					
						
							|  |  |  |         int idx = -1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (cast<UiObjectDefinition*>(member)) | 
					
						
							|  |  |  |             lastObjectDef = iter; | 
					
						
							|  |  |  |         else if (UiArrayBinding *arrayBinding = cast<UiArrayBinding*>(member)) | 
					
						
							| 
									
										
										
										
											2011-10-07 14:04:06 +02:00
										 |  |  |             idx = propertyOrder.indexOf(toString(arrayBinding->qualifiedId)); | 
					
						
							| 
									
										
										
										
											2010-08-12 18:05:50 +02:00
										 |  |  |         else if (UiObjectBinding *objectBinding = cast<UiObjectBinding*>(member)) | 
					
						
							| 
									
										
										
										
											2011-10-07 14:04:06 +02:00
										 |  |  |             idx = propertyOrder.indexOf(toString(objectBinding->qualifiedId)); | 
					
						
							| 
									
										
										
										
											2010-08-12 18:05:50 +02:00
										 |  |  |         else if (UiScriptBinding *scriptBinding = cast<UiScriptBinding*>(member)) | 
					
						
							| 
									
										
										
										
											2011-10-07 14:04:06 +02:00
										 |  |  |             idx = propertyOrder.indexOf(toString(scriptBinding->qualifiedId)); | 
					
						
							| 
									
										
										
										
											2010-08-12 18:05:50 +02:00
										 |  |  |         else if (cast<UiPublicMember*>(member)) | 
					
						
							|  |  |  |             idx = propertyOrder.indexOf(QLatin1String("property")); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (idx < objectDefinitionInsertionPoint) | 
					
						
							|  |  |  |             lastNonObjectDef = iter; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (lastObjectDef) | 
					
						
							|  |  |  |         return lastObjectDef; | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |         return lastNonObjectDef; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-30 13:42:35 +02:00
										 |  |  | UiObjectMemberList *Rewriter::searchMemberToInsertAfter(UiObjectMemberList *members, | 
					
						
							|  |  |  |                                                         const QString &propertyName, | 
					
						
							|  |  |  |                                                         const QStringList &propertyOrder) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (!members) | 
					
						
							|  |  |  |         return 0; // empty members
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     QHash<QString, UiObjectMemberList *> orderedMembers; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (UiObjectMemberList *iter = members; iter; iter = iter->next) { | 
					
						
							|  |  |  |         UiObjectMember *member = iter->member; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (UiArrayBinding *arrayBinding = cast<UiArrayBinding*>(member)) | 
					
						
							| 
									
										
										
										
											2011-10-07 14:04:06 +02:00
										 |  |  |             orderedMembers[toString(arrayBinding->qualifiedId)] = iter; | 
					
						
							| 
									
										
										
										
											2010-06-30 13:42:35 +02:00
										 |  |  |         else if (UiObjectBinding *objectBinding = cast<UiObjectBinding*>(member)) | 
					
						
							| 
									
										
										
										
											2011-10-07 14:04:06 +02:00
										 |  |  |             orderedMembers[toString(objectBinding->qualifiedId)] = iter; | 
					
						
							| 
									
										
										
										
											2010-06-30 13:42:35 +02:00
										 |  |  |         else if (cast<UiObjectDefinition*>(member)) | 
					
						
							|  |  |  |             orderedMembers[QString::null] = iter; | 
					
						
							|  |  |  |         else if (UiScriptBinding *scriptBinding = cast<UiScriptBinding*>(member)) | 
					
						
							| 
									
										
										
										
											2011-10-07 14:04:06 +02:00
										 |  |  |             orderedMembers[toString(scriptBinding->qualifiedId)] = iter; | 
					
						
							| 
									
										
										
										
											2010-06-30 13:42:35 +02:00
										 |  |  |         else if (cast<UiPublicMember*>(member)) | 
					
						
							|  |  |  |             orderedMembers[QLatin1String("property")] = iter; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     int idx = propertyOrder.indexOf(propertyName); | 
					
						
							|  |  |  |     if (idx == -1) | 
					
						
							|  |  |  |         idx = propertyOrder.indexOf(QString()); | 
					
						
							|  |  |  |     if (idx == -1) | 
					
						
							|  |  |  |         idx = propertyOrder.size() - 1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (; idx > 0; --idx) { | 
					
						
							|  |  |  |         const QString prop = propertyOrder.at(idx - 1); | 
					
						
							|  |  |  |         UiObjectMemberList *candidate = orderedMembers.value(prop, 0); | 
					
						
							|  |  |  |         if (candidate != 0) | 
					
						
							|  |  |  |             return candidate; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-21 13:17:44 +02:00
										 |  |  | void Rewriter::changeBinding(UiObjectInitializer *ast, | 
					
						
							|  |  |  |                              const QString &propertyName, | 
					
						
							|  |  |  |                              const QString &newValue, | 
					
						
							|  |  |  |                              BindingType binding) | 
					
						
							| 
									
										
										
										
											2010-06-30 13:42:35 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     QString prefix, suffix; | 
					
						
							|  |  |  |     int dotIdx = propertyName.indexOf(QLatin1Char('.')); | 
					
						
							|  |  |  |     if (dotIdx != -1) { | 
					
						
							|  |  |  |         prefix = propertyName.left(dotIdx); | 
					
						
							|  |  |  |         suffix = propertyName.mid(dotIdx + 1); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (UiObjectMemberList *members = ast->members; members; members = members->next) { | 
					
						
							|  |  |  |         UiObjectMember *member = members->member; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // for non-grouped properties:
 | 
					
						
							|  |  |  |         if (isMatchingPropertyMember(propertyName, member)) { | 
					
						
							|  |  |  |             switch (binding) { | 
					
						
							|  |  |  |             case ArrayBinding: | 
					
						
							|  |  |  |                 insertIntoArray(cast<UiArrayBinding*>(member), newValue); | 
					
						
							|  |  |  |                 break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             case ObjectBinding: | 
					
						
							|  |  |  |                 replaceMemberValue(member, newValue, false); | 
					
						
							|  |  |  |                 break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             case ScriptBinding: | 
					
						
							|  |  |  |                 replaceMemberValue(member, newValue, nextMemberOnSameLine(members)); | 
					
						
							|  |  |  |                 break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             default: | 
					
						
							|  |  |  |                 Q_ASSERT(!"Unhandled QmlRefactoring::PropertyType"); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         // for grouped properties:
 | 
					
						
							|  |  |  |         else if (!prefix.isEmpty()) { | 
					
						
							|  |  |  |             if (UiObjectDefinition *def = cast<UiObjectDefinition *>(member)) { | 
					
						
							| 
									
										
										
											
												Remove braces for single lines of conditions
#!/usr/bin/env ruby
Dir.glob('**/*.cpp') { |file|
  # skip ast (excluding paste, astpath, and canv'ast'imer)
  next if file =~ /ast[^eip]|keywords\.|qualifiers|preprocessor|names.cpp/i
  s = File.read(file)
  next if s.include?('qlalr')
  orig = s.dup
  s.gsub!(/\n *if [^\n]*{\n[^\n]*\n\s+}(\s+else if [^\n]* {\n[^\n]*\n\s+})*(\s+else {\n[^\n]*\n\s+})?\n/m) { |m|
    res = $&
    if res =~ /^\s*(\/\/|[A-Z_]{3,})/ # C++ comment or macro (Q_UNUSED, SDEBUG), do not touch braces
      res
    else
      res.gsub!('} else', 'else')
      res.gsub!(/\n +} *\n/m, "\n")
      res.gsub(/ *{$/, '')
    end
  }
  s.gsub!(/ *$/, '')
  File.open(file, 'wb').write(s) if s != orig
}
Change-Id: I3b30ee60df0986f66c02132c65fc38a3fbb6bbdc
Reviewed-by: hjk <qthjk@ovi.com>
											
										 
											2013-01-08 03:32:53 +02:00
										 |  |  |                 if (toString(def->qualifiedTypeNameId) == prefix) | 
					
						
							| 
									
										
										
										
											2010-07-21 13:17:44 +02:00
										 |  |  |                     changeBinding(def->initializer, suffix, newValue, binding); | 
					
						
							| 
									
										
										
										
											2010-06-30 13:42:35 +02:00
										 |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void Rewriter::replaceMemberValue(UiObjectMember *propertyMember, | 
					
						
							|  |  |  |                                   const QString &newValue, | 
					
						
							|  |  |  |                                   bool needsSemicolon) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     QString replacement = newValue; | 
					
						
							|  |  |  |     int startOffset = -1; | 
					
						
							|  |  |  |     int endOffset = -1; | 
					
						
							|  |  |  |     if (UiObjectBinding *objectBinding = AST::cast<UiObjectBinding *>(propertyMember)) { | 
					
						
							|  |  |  |         startOffset = objectBinding->qualifiedTypeNameId->identifierToken.offset; | 
					
						
							|  |  |  |         endOffset = objectBinding->initializer->rbraceToken.end(); | 
					
						
							|  |  |  |     } else if (UiScriptBinding *scriptBinding = AST::cast<UiScriptBinding *>(propertyMember)) { | 
					
						
							|  |  |  |         startOffset = scriptBinding->statement->firstSourceLocation().offset; | 
					
						
							|  |  |  |         endOffset = scriptBinding->statement->lastSourceLocation().end(); | 
					
						
							|  |  |  |     } else if (UiArrayBinding *arrayBinding = AST::cast<UiArrayBinding *>(propertyMember)) { | 
					
						
							|  |  |  |         startOffset = arrayBinding->lbracketToken.offset; | 
					
						
							|  |  |  |         endOffset = arrayBinding->rbracketToken.end(); | 
					
						
							|  |  |  |     } else if (UiPublicMember *publicMember = AST::cast<UiPublicMember*>(propertyMember)) { | 
					
						
							| 
									
										
										
										
											2011-05-12 13:25:35 +02:00
										 |  |  |         if (publicMember->statement) { | 
					
						
							|  |  |  |             startOffset = publicMember->statement->firstSourceLocation().offset; | 
					
						
							| 
									
										
										
										
											2010-06-30 13:42:35 +02:00
										 |  |  |             if (publicMember->semicolonToken.isValid()) | 
					
						
							|  |  |  |                 endOffset = publicMember->semicolonToken.end(); | 
					
						
							|  |  |  |             else | 
					
						
							| 
									
										
										
										
											2011-05-12 13:25:35 +02:00
										 |  |  |                 endOffset = publicMember->statement->lastSourceLocation().offset; | 
					
						
							| 
									
										
										
										
											2010-06-30 13:42:35 +02:00
										 |  |  |         } else { | 
					
						
							|  |  |  |             startOffset = publicMember->lastSourceLocation().end(); | 
					
						
							|  |  |  |             endOffset = startOffset; | 
					
						
							|  |  |  |             if (publicMember->semicolonToken.isValid()) | 
					
						
							|  |  |  |                 startOffset = publicMember->semicolonToken.offset; | 
					
						
							|  |  |  |             replacement.prepend(QLatin1String(": ")); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (needsSemicolon) | 
					
						
							| 
									
										
										
										
											2012-11-27 20:20:02 +02:00
										 |  |  |         replacement += QLatin1Char(';'); | 
					
						
							| 
									
										
										
										
											2010-06-30 13:42:35 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-07 13:05:25 +02:00
										 |  |  |     m_changeSet->replace(startOffset, endOffset, replacement); | 
					
						
							| 
									
										
										
										
											2010-06-30 13:42:35 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool Rewriter::isMatchingPropertyMember(const QString &propertyName, | 
					
						
							|  |  |  |                                         UiObjectMember *member) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (UiPublicMember *publicMember = cast<UiPublicMember*>(member)) | 
					
						
							| 
									
										
										
										
											2011-09-13 09:57:24 +02:00
										 |  |  |         return publicMember->name == propertyName; | 
					
						
							| 
									
										
										
										
											2010-06-30 13:42:35 +02:00
										 |  |  |     else if (UiObjectBinding *objectBinding = cast<UiObjectBinding*>(member)) | 
					
						
							| 
									
										
										
										
											2011-10-07 14:04:06 +02:00
										 |  |  |         return toString(objectBinding->qualifiedId) == propertyName; | 
					
						
							| 
									
										
										
										
											2010-06-30 13:42:35 +02:00
										 |  |  |     else if (UiScriptBinding *scriptBinding = cast<UiScriptBinding*>(member)) | 
					
						
							| 
									
										
										
										
											2011-10-07 14:04:06 +02:00
										 |  |  |         return toString(scriptBinding->qualifiedId) == propertyName; | 
					
						
							| 
									
										
										
										
											2010-06-30 13:42:35 +02:00
										 |  |  |     else if (UiArrayBinding *arrayBinding = cast<UiArrayBinding*>(member)) | 
					
						
							| 
									
										
										
										
											2011-10-07 14:04:06 +02:00
										 |  |  |         return toString(arrayBinding->qualifiedId) == propertyName; | 
					
						
							| 
									
										
										
										
											2010-06-30 13:42:35 +02:00
										 |  |  |     else | 
					
						
							|  |  |  |         return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool Rewriter::nextMemberOnSameLine(UiObjectMemberList *members) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
											
												Remove braces for single lines of conditions
#!/usr/bin/env ruby
Dir.glob('**/*.cpp') { |file|
  # skip ast (excluding paste, astpath, and canv'ast'imer)
  next if file =~ /ast[^eip]|keywords\.|qualifiers|preprocessor|names.cpp/i
  s = File.read(file)
  next if s.include?('qlalr')
  orig = s.dup
  s.gsub!(/\n *if [^\n]*{\n[^\n]*\n\s+}(\s+else if [^\n]* {\n[^\n]*\n\s+})*(\s+else {\n[^\n]*\n\s+})?\n/m) { |m|
    res = $&
    if res =~ /^\s*(\/\/|[A-Z_]{3,})/ # C++ comment or macro (Q_UNUSED, SDEBUG), do not touch braces
      res
    else
      res.gsub!('} else', 'else')
      res.gsub!(/\n +} *\n/m, "\n")
      res.gsub(/ *{$/, '')
    end
  }
  s.gsub!(/ *$/, '')
  File.open(file, 'wb').write(s) if s != orig
}
Change-Id: I3b30ee60df0986f66c02132c65fc38a3fbb6bbdc
Reviewed-by: hjk <qthjk@ovi.com>
											
										 
											2013-01-08 03:32:53 +02:00
										 |  |  |     if (members && members->next && members->next->member) | 
					
						
							| 
									
										
										
										
											2010-06-30 13:42:35 +02:00
										 |  |  |         return members->next->member->firstSourceLocation().startLine == members->member->lastSourceLocation().startLine; | 
					
						
							| 
									
										
										
											
												Remove braces for single lines of conditions
#!/usr/bin/env ruby
Dir.glob('**/*.cpp') { |file|
  # skip ast (excluding paste, astpath, and canv'ast'imer)
  next if file =~ /ast[^eip]|keywords\.|qualifiers|preprocessor|names.cpp/i
  s = File.read(file)
  next if s.include?('qlalr')
  orig = s.dup
  s.gsub!(/\n *if [^\n]*{\n[^\n]*\n\s+}(\s+else if [^\n]* {\n[^\n]*\n\s+})*(\s+else {\n[^\n]*\n\s+})?\n/m) { |m|
    res = $&
    if res =~ /^\s*(\/\/|[A-Z_]{3,})/ # C++ comment or macro (Q_UNUSED, SDEBUG), do not touch braces
      res
    else
      res.gsub!('} else', 'else')
      res.gsub!(/\n +} *\n/m, "\n")
      res.gsub(/ *{$/, '')
    end
  }
  s.gsub!(/ *$/, '')
  File.open(file, 'wb').write(s) if s != orig
}
Change-Id: I3b30ee60df0986f66c02132c65fc38a3fbb6bbdc
Reviewed-by: hjk <qthjk@ovi.com>
											
										 
											2013-01-08 03:32:53 +02:00
										 |  |  |     else | 
					
						
							| 
									
										
										
										
											2010-06-30 13:42:35 +02:00
										 |  |  |         return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void Rewriter::insertIntoArray(UiArrayBinding *ast, const QString &newValue) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (!ast) | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     UiObjectMember *lastMember = 0; | 
					
						
							|  |  |  |     for (UiArrayMemberList *iter = ast->members; iter; iter = iter->next) { | 
					
						
							|  |  |  |         lastMember = iter->member; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!lastMember) | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const int insertionPoint = lastMember->lastSourceLocation().end(); | 
					
						
							| 
									
										
										
										
											2010-07-07 13:05:25 +02:00
										 |  |  |     m_changeSet->insert(insertionPoint, QLatin1String(",\n") + newValue); | 
					
						
							| 
									
										
										
										
											2010-06-30 13:42:35 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-21 13:17:44 +02:00
										 |  |  | void Rewriter::removeBindingByName(UiObjectInitializer *ast, const QString &propertyName) | 
					
						
							| 
									
										
										
										
											2010-06-30 13:42:35 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     QString prefix; | 
					
						
							|  |  |  |     int dotIdx = propertyName.indexOf(QLatin1Char('.')); | 
					
						
							|  |  |  |     if (dotIdx != -1) | 
					
						
							|  |  |  |         prefix = propertyName.left(dotIdx); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (UiObjectMemberList *it = ast->members; it; it = it->next) { | 
					
						
							|  |  |  |         UiObjectMember *member = it->member; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // run full name match (for ungrouped properties):
 | 
					
						
							| 
									
										
										
											
												Remove braces for single lines of conditions
#!/usr/bin/env ruby
Dir.glob('**/*.cpp') { |file|
  # skip ast (excluding paste, astpath, and canv'ast'imer)
  next if file =~ /ast[^eip]|keywords\.|qualifiers|preprocessor|names.cpp/i
  s = File.read(file)
  next if s.include?('qlalr')
  orig = s.dup
  s.gsub!(/\n *if [^\n]*{\n[^\n]*\n\s+}(\s+else if [^\n]* {\n[^\n]*\n\s+})*(\s+else {\n[^\n]*\n\s+})?\n/m) { |m|
    res = $&
    if res =~ /^\s*(\/\/|[A-Z_]{3,})/ # C++ comment or macro (Q_UNUSED, SDEBUG), do not touch braces
      res
    else
      res.gsub!('} else', 'else')
      res.gsub!(/\n +} *\n/m, "\n")
      res.gsub(/ *{$/, '')
    end
  }
  s.gsub!(/ *$/, '')
  File.open(file, 'wb').write(s) if s != orig
}
Change-Id: I3b30ee60df0986f66c02132c65fc38a3fbb6bbdc
Reviewed-by: hjk <qthjk@ovi.com>
											
										 
											2013-01-08 03:32:53 +02:00
										 |  |  |         if (isMatchingPropertyMember(propertyName, member)) | 
					
						
							| 
									
										
										
										
											2010-06-30 13:42:35 +02:00
										 |  |  |             removeMember(member); | 
					
						
							|  |  |  |         // check for grouped properties:
 | 
					
						
							|  |  |  |         else if (!prefix.isEmpty()) { | 
					
						
							|  |  |  |             if (UiObjectDefinition *def = cast<UiObjectDefinition *>(member)) { | 
					
						
							| 
									
										
										
											
												Remove braces for single lines of conditions
#!/usr/bin/env ruby
Dir.glob('**/*.cpp') { |file|
  # skip ast (excluding paste, astpath, and canv'ast'imer)
  next if file =~ /ast[^eip]|keywords\.|qualifiers|preprocessor|names.cpp/i
  s = File.read(file)
  next if s.include?('qlalr')
  orig = s.dup
  s.gsub!(/\n *if [^\n]*{\n[^\n]*\n\s+}(\s+else if [^\n]* {\n[^\n]*\n\s+})*(\s+else {\n[^\n]*\n\s+})?\n/m) { |m|
    res = $&
    if res =~ /^\s*(\/\/|[A-Z_]{3,})/ # C++ comment or macro (Q_UNUSED, SDEBUG), do not touch braces
      res
    else
      res.gsub!('} else', 'else')
      res.gsub!(/\n +} *\n/m, "\n")
      res.gsub(/ *{$/, '')
    end
  }
  s.gsub!(/ *$/, '')
  File.open(file, 'wb').write(s) if s != orig
}
Change-Id: I3b30ee60df0986f66c02132c65fc38a3fbb6bbdc
Reviewed-by: hjk <qthjk@ovi.com>
											
										 
											2013-01-08 03:32:53 +02:00
										 |  |  |                 if (toString(def->qualifiedTypeNameId) == prefix) | 
					
						
							| 
									
										
										
										
											2010-06-30 13:42:35 +02:00
										 |  |  |                     removeGroupedProperty(def, propertyName); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void Rewriter::removeGroupedProperty(UiObjectDefinition *ast, | 
					
						
							|  |  |  |                                      const QString &propertyName) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     int dotIdx = propertyName.indexOf(QLatin1Char('.')); | 
					
						
							|  |  |  |     if (dotIdx == -1) | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const QString propName = propertyName.mid(dotIdx + 1); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     UiObjectMember *wanted = 0; | 
					
						
							|  |  |  |     unsigned memberCount = 0; | 
					
						
							|  |  |  |     for (UiObjectMemberList *it = ast->initializer->members; it; it = it->next) { | 
					
						
							|  |  |  |         ++memberCount; | 
					
						
							|  |  |  |         UiObjectMember *member = it->member; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
											
												Remove braces for single lines of conditions
#!/usr/bin/env ruby
Dir.glob('**/*.cpp') { |file|
  # skip ast (excluding paste, astpath, and canv'ast'imer)
  next if file =~ /ast[^eip]|keywords\.|qualifiers|preprocessor|names.cpp/i
  s = File.read(file)
  next if s.include?('qlalr')
  orig = s.dup
  s.gsub!(/\n *if [^\n]*{\n[^\n]*\n\s+}(\s+else if [^\n]* {\n[^\n]*\n\s+})*(\s+else {\n[^\n]*\n\s+})?\n/m) { |m|
    res = $&
    if res =~ /^\s*(\/\/|[A-Z_]{3,})/ # C++ comment or macro (Q_UNUSED, SDEBUG), do not touch braces
      res
    else
      res.gsub!('} else', 'else')
      res.gsub!(/\n +} *\n/m, "\n")
      res.gsub(/ *{$/, '')
    end
  }
  s.gsub!(/ *$/, '')
  File.open(file, 'wb').write(s) if s != orig
}
Change-Id: I3b30ee60df0986f66c02132c65fc38a3fbb6bbdc
Reviewed-by: hjk <qthjk@ovi.com>
											
										 
											2013-01-08 03:32:53 +02:00
										 |  |  |         if (!wanted && isMatchingPropertyMember(propName, member)) | 
					
						
							| 
									
										
										
										
											2010-06-30 13:42:35 +02:00
										 |  |  |             wanted = member; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!wanted) | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     if (memberCount == 1) | 
					
						
							|  |  |  |         removeMember(ast); | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |         removeMember(wanted); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void Rewriter::removeMember(UiObjectMember *member) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     int start = member->firstSourceLocation().offset; | 
					
						
							|  |  |  |     int end = member->lastSourceLocation().end(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-20 12:47:50 +02:00
										 |  |  |     includeSurroundingWhitespace(m_originalText, start, end); | 
					
						
							| 
									
										
										
										
											2010-06-30 13:42:35 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-09 16:01:19 +02:00
										 |  |  |     m_changeSet->remove(start, end); | 
					
						
							| 
									
										
										
										
											2010-06-30 13:42:35 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-20 12:47:50 +02:00
										 |  |  | bool Rewriter::includeSurroundingWhitespace(const QString &source, int &start, int &end) | 
					
						
							| 
									
										
										
										
											2010-06-30 13:42:35 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     bool includeStartingWhitespace = true; | 
					
						
							|  |  |  |     bool paragraphFound = false; | 
					
						
							| 
									
										
										
										
											2010-07-20 15:05:43 +02:00
										 |  |  |     bool paragraphSkipped = false; | 
					
						
							| 
									
										
										
										
											2010-06-30 13:42:35 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (end >= 0) { | 
					
						
							| 
									
										
										
										
											2010-07-20 12:47:50 +02:00
										 |  |  |         QChar c = source.at(end); | 
					
						
							| 
									
										
										
										
											2010-07-09 16:01:19 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-30 13:42:35 +02:00
										 |  |  |         while (c.isSpace()) { | 
					
						
							|  |  |  |             ++end; | 
					
						
							| 
									
										
										
										
											2010-07-09 16:01:19 +02:00
										 |  |  |             if (c.unicode() == 10) { | 
					
						
							| 
									
										
										
										
											2010-06-30 13:42:35 +02:00
										 |  |  |                 paragraphFound = true; | 
					
						
							| 
									
										
										
										
											2010-07-20 15:05:43 +02:00
										 |  |  |                 paragraphSkipped = true; | 
					
						
							| 
									
										
										
										
											2010-06-30 13:42:35 +02:00
										 |  |  |                 break; | 
					
						
							| 
									
										
										
										
											2010-07-20 12:47:50 +02:00
										 |  |  |             } else if (end == source.length()) { | 
					
						
							| 
									
										
										
										
											2010-06-30 13:42:35 +02:00
										 |  |  |                 break; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-20 12:47:50 +02:00
										 |  |  |             c = source.at(end); | 
					
						
							| 
									
										
										
										
											2010-06-30 13:42:35 +02:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         includeStartingWhitespace = paragraphFound; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-09 18:08:00 +02:00
										 |  |  |     paragraphFound = false; | 
					
						
							| 
									
										
										
										
											2010-06-30 13:42:35 +02:00
										 |  |  |     if (includeStartingWhitespace) { | 
					
						
							|  |  |  |         while (start > 0) { | 
					
						
							| 
									
										
										
										
											2010-07-20 12:47:50 +02:00
										 |  |  |             const QChar c = source.at(start - 1); | 
					
						
							| 
									
										
										
										
											2010-06-30 13:42:35 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-09 18:08:00 +02:00
										 |  |  |             if (c.unicode() == 10) { | 
					
						
							|  |  |  |                 paragraphFound = true; | 
					
						
							| 
									
										
										
										
											2010-06-30 13:42:35 +02:00
										 |  |  |                 break; | 
					
						
							| 
									
										
										
										
											2010-07-09 18:08:00 +02:00
										 |  |  |             } | 
					
						
							|  |  |  |             if (!c.isSpace()) | 
					
						
							| 
									
										
										
										
											2010-06-30 13:42:35 +02:00
										 |  |  |                 break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             --start; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2010-07-20 15:05:43 +02:00
										 |  |  |     if (!paragraphFound && paragraphSkipped) //keep the line ending
 | 
					
						
							| 
									
										
										
										
											2010-07-09 18:08:00 +02:00
										 |  |  |         --end; | 
					
						
							| 
									
										
										
										
											2010-06-30 13:42:35 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     return paragraphFound; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-20 12:47:50 +02:00
										 |  |  | void Rewriter::includeLeadingEmptyLine(const QString &source, int &start) | 
					
						
							| 
									
										
										
										
											2010-06-30 13:42:35 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-07-20 12:47:50 +02:00
										 |  |  |     QTextDocument doc(source); | 
					
						
							| 
									
										
										
										
											2010-06-30 13:42:35 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (start == 0) | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (doc.characterAt(start - 1) != QChar::ParagraphSeparator) | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     QTextCursor tc(&doc); | 
					
						
							|  |  |  |     tc.setPosition(start); | 
					
						
							|  |  |  |     const int blockNr = tc.blockNumber(); | 
					
						
							|  |  |  |     if (blockNr == 0) | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const QTextBlock prevBlock = tc.block().previous(); | 
					
						
							|  |  |  |     const QString trimmedPrevBlockText = prevBlock.text().trimmed(); | 
					
						
							|  |  |  |     if (!trimmedPrevBlockText.isEmpty()) | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     start = prevBlock.position(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-21 13:49:14 +02:00
										 |  |  | void Rewriter::includeEmptyGroupedProperty(UiObjectDefinition *groupedProperty, UiObjectMember *memberToBeRemoved, int &start, int &end) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2011-09-13 09:57:24 +02:00
										 |  |  |     if (groupedProperty->qualifiedTypeNameId && !groupedProperty->qualifiedTypeNameId->name.isEmpty() | 
					
						
							|  |  |  |             && groupedProperty->qualifiedTypeNameId->name.at(0).isLower()) { | 
					
						
							| 
									
										
										
										
											2010-07-21 13:49:14 +02:00
										 |  |  |         // grouped property
 | 
					
						
							|  |  |  |         UiObjectMemberList *memberIter = groupedProperty->initializer->members; | 
					
						
							|  |  |  |         while (memberIter) { | 
					
						
							| 
									
										
										
											
												Remove braces for single lines of conditions
#!/usr/bin/env ruby
Dir.glob('**/*.cpp') { |file|
  # skip ast (excluding paste, astpath, and canv'ast'imer)
  next if file =~ /ast[^eip]|keywords\.|qualifiers|preprocessor|names.cpp/i
  s = File.read(file)
  next if s.include?('qlalr')
  orig = s.dup
  s.gsub!(/\n *if [^\n]*{\n[^\n]*\n\s+}(\s+else if [^\n]* {\n[^\n]*\n\s+})*(\s+else {\n[^\n]*\n\s+})?\n/m) { |m|
    res = $&
    if res =~ /^\s*(\/\/|[A-Z_]{3,})/ # C++ comment or macro (Q_UNUSED, SDEBUG), do not touch braces
      res
    else
      res.gsub!('} else', 'else')
      res.gsub!(/\n +} *\n/m, "\n")
      res.gsub(/ *{$/, '')
    end
  }
  s.gsub!(/ *$/, '')
  File.open(file, 'wb').write(s) if s != orig
}
Change-Id: I3b30ee60df0986f66c02132c65fc38a3fbb6bbdc
Reviewed-by: hjk <qthjk@ovi.com>
											
										 
											2013-01-08 03:32:53 +02:00
										 |  |  |             if (memberIter->member != memberToBeRemoved) | 
					
						
							| 
									
										
										
										
											2010-07-21 13:49:14 +02:00
										 |  |  |                 return; | 
					
						
							|  |  |  |             memberIter = memberIter->next; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         start = groupedProperty->firstSourceLocation().begin(); | 
					
						
							|  |  |  |         end = groupedProperty->lastSourceLocation().end(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-30 13:42:35 +02:00
										 |  |  | #if 0
 | 
					
						
							|  |  |  | UiObjectMemberList *QMLRewriter::searchMemberToInsertAfter(UiObjectMemberList *members, const QStringList &propertyOrder) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     const int objectDefinitionInsertionPoint = propertyOrder.indexOf(QString::null); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     UiObjectMemberList *lastObjectDef = 0; | 
					
						
							|  |  |  |     UiObjectMemberList *lastNonObjectDef = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (UiObjectMemberList *iter = members; iter; iter = iter->next) { | 
					
						
							|  |  |  |         UiObjectMember *member = iter->member; | 
					
						
							|  |  |  |         int idx = -1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (cast<UiObjectDefinition*>(member)) | 
					
						
							|  |  |  |             lastObjectDef = iter; | 
					
						
							|  |  |  |         else if (UiArrayBinding *arrayBinding = cast<UiArrayBinding*>(member)) | 
					
						
							| 
									
										
										
										
											2011-10-07 14:04:06 +02:00
										 |  |  |             idx = propertyOrder.indexOf(toString(arrayBinding->qualifiedId)); | 
					
						
							| 
									
										
										
										
											2010-06-30 13:42:35 +02:00
										 |  |  |         else if (UiObjectBinding *objectBinding = cast<UiObjectBinding*>(member)) | 
					
						
							| 
									
										
										
										
											2011-10-07 14:04:06 +02:00
										 |  |  |             idx = propertyOrder.indexOf(toString(objectBinding->qualifiedId)); | 
					
						
							| 
									
										
										
										
											2010-06-30 13:42:35 +02:00
										 |  |  |         else if (UiScriptBinding *scriptBinding = cast<UiScriptBinding*>(member)) | 
					
						
							| 
									
										
										
										
											2011-10-07 14:04:06 +02:00
										 |  |  |             idx = propertyOrder.indexOf(toString(scriptBinding->qualifiedId)); | 
					
						
							| 
									
										
										
										
											2010-06-30 13:42:35 +02:00
										 |  |  |         else if (cast<UiPublicMember*>(member)) | 
					
						
							|  |  |  |             idx = propertyOrder.indexOf(QLatin1String("property")); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (idx < objectDefinitionInsertionPoint) | 
					
						
							|  |  |  |             lastNonObjectDef = iter; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (lastObjectDef) | 
					
						
							|  |  |  |         return lastObjectDef; | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |         return lastNonObjectDef; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | UiObjectMemberList *QMLRewriter::searchMemberToInsertAfter(UiObjectMemberList *members, const QString &propertyName, const QStringList &propertyOrder) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (!members) | 
					
						
							|  |  |  |         return 0; // empty members
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     QHash<QString, UiObjectMemberList *> orderedMembers; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (UiObjectMemberList *iter = members; iter; iter = iter->next) { | 
					
						
							|  |  |  |         UiObjectMember *member = iter->member; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (UiArrayBinding *arrayBinding = cast<UiArrayBinding*>(member)) | 
					
						
							| 
									
										
										
										
											2011-10-07 14:04:06 +02:00
										 |  |  |             orderedMembers[toString(arrayBinding->qualifiedId)] = iter; | 
					
						
							| 
									
										
										
										
											2010-06-30 13:42:35 +02:00
										 |  |  |         else if (UiObjectBinding *objectBinding = cast<UiObjectBinding*>(member)) | 
					
						
							| 
									
										
										
										
											2011-10-07 14:04:06 +02:00
										 |  |  |             orderedMembers[toString(objectBinding->qualifiedId)] = iter; | 
					
						
							| 
									
										
										
										
											2010-06-30 13:42:35 +02:00
										 |  |  |         else if (cast<UiObjectDefinition*>(member)) | 
					
						
							|  |  |  |             orderedMembers[QString::null] = iter; | 
					
						
							|  |  |  |         else if (UiScriptBinding *scriptBinding = cast<UiScriptBinding*>(member)) | 
					
						
							| 
									
										
										
										
											2011-10-07 14:04:06 +02:00
										 |  |  |             orderedMembers[toString(scriptBinding->qualifiedId)] = iter; | 
					
						
							| 
									
										
										
										
											2010-06-30 13:42:35 +02:00
										 |  |  |         else if (cast<UiPublicMember*>(member)) | 
					
						
							|  |  |  |             orderedMembers[QLatin1String("property")] = iter; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     int idx = propertyOrder.indexOf(propertyName); | 
					
						
							|  |  |  |     if (idx == -1) | 
					
						
							|  |  |  |         idx = propertyOrder.indexOf(QString()); | 
					
						
							|  |  |  |     if (idx == -1) | 
					
						
							|  |  |  |         idx = propertyOrder.size() - 1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (; idx > 0; --idx) { | 
					
						
							|  |  |  |         const QString prop = propertyOrder.at(idx - 1); | 
					
						
							|  |  |  |         UiObjectMemberList *candidate = orderedMembers.value(prop, 0); | 
					
						
							|  |  |  |         if (candidate != 0) | 
					
						
							|  |  |  |             return candidate; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void Rewriter::appendToArrayBinding(UiArrayBinding *arrayBinding, | 
					
						
							|  |  |  |                                     const QString &content) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     UiObjectMember *lastMember = 0; | 
					
						
							|  |  |  |     for (UiArrayMemberList *iter = arrayBinding->members; iter; iter = iter->next) | 
					
						
							|  |  |  |         if (iter->member) | 
					
						
							|  |  |  |             lastMember = iter->member; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!lastMember) | 
					
						
							|  |  |  |         return; // an array binding cannot be empty, so there will (or should) always be a last member.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const int insertionPoint = lastMember->lastSourceLocation().end(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-07 13:05:25 +02:00
										 |  |  |     m_changeSet->insert(insertionPoint, QLatin1String(",\n") + content); | 
					
						
							| 
									
										
										
										
											2010-06-30 13:42:35 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-21 12:21:29 +02:00
										 |  |  | Rewriter::Range Rewriter::addObject(UiObjectInitializer *ast, const QString &content) | 
					
						
							| 
									
										
										
										
											2010-06-30 13:42:35 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-07-21 09:19:51 +02:00
										 |  |  |     UiObjectMemberList *insertAfter = searchMemberToInsertAfter(ast->members, m_propertyOrder); | 
					
						
							| 
									
										
										
										
											2010-07-21 12:21:29 +02:00
										 |  |  |     return addObject(ast, content, insertAfter); | 
					
						
							| 
									
										
										
										
											2010-07-21 09:19:51 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2010-06-30 13:42:35 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-21 12:21:29 +02:00
										 |  |  | Rewriter::Range Rewriter::addObject(UiObjectInitializer *ast, const QString &content, UiObjectMemberList *insertAfter) | 
					
						
							| 
									
										
										
										
											2010-07-21 09:19:51 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-06-30 13:42:35 +02:00
										 |  |  |     int insertionPoint; | 
					
						
							|  |  |  |     QString textToInsert; | 
					
						
							|  |  |  |     if (insertAfter && insertAfter->member) { | 
					
						
							|  |  |  |         insertionPoint = insertAfter->member->lastSourceLocation().end(); | 
					
						
							|  |  |  |         textToInsert += QLatin1String("\n"); | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |         insertionPoint = ast->lbraceToken.end(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     textToInsert += content; | 
					
						
							| 
									
										
										
										
											2010-07-07 13:05:25 +02:00
										 |  |  |     m_changeSet->insert(insertionPoint, QLatin1String("\n") + textToInsert); | 
					
						
							| 
									
										
										
										
											2010-08-12 18:05:50 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     return Range(insertionPoint, insertionPoint); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Rewriter::Range Rewriter::addObject(UiArrayBinding *ast, const QString &content) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     UiArrayMemberList *insertAfter = searchMemberToInsertAfter(ast->members, m_propertyOrder); | 
					
						
							|  |  |  |     return addObject(ast, content, insertAfter); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Rewriter::Range Rewriter::addObject(UiArrayBinding *ast, const QString &content, UiArrayMemberList *insertAfter) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     int insertionPoint; | 
					
						
							|  |  |  |     QString textToInsert; | 
					
						
							|  |  |  |     if (insertAfter && insertAfter->member) { | 
					
						
							|  |  |  |         insertionPoint = insertAfter->member->lastSourceLocation().end(); | 
					
						
							| 
									
										
										
										
											2010-10-20 14:28:29 +02:00
										 |  |  |         textToInsert = QLatin1String(",\n") + content; | 
					
						
							| 
									
										
										
										
											2010-08-12 18:05:50 +02:00
										 |  |  |     } else { | 
					
						
							|  |  |  |         insertionPoint = ast->lbracketToken.end(); | 
					
						
							| 
									
										
										
										
											2010-10-20 14:28:29 +02:00
										 |  |  |         textToInsert += QLatin1String("\n") + content + QLatin1Char(','); | 
					
						
							| 
									
										
										
										
											2010-08-12 18:05:50 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-20 14:28:29 +02:00
										 |  |  |     m_changeSet->insert(insertionPoint, textToInsert); | 
					
						
							| 
									
										
										
										
											2010-07-21 12:21:29 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     return Range(insertionPoint, insertionPoint); | 
					
						
							| 
									
										
										
										
											2010-06-30 13:42:35 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void Rewriter::removeObjectMember(UiObjectMember *member, UiObjectMember *parent) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     int start = member->firstSourceLocation().offset; | 
					
						
							|  |  |  |     int end = member->lastSourceLocation().end(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (UiArrayBinding *parentArray = cast<UiArrayBinding *>(parent)) { | 
					
						
							|  |  |  |         extendToLeadingOrTrailingComma(parentArray, member, start, end); | 
					
						
							|  |  |  |     } else { | 
					
						
							| 
									
										
										
											
												Remove braces for single lines of conditions
#!/usr/bin/env ruby
Dir.glob('**/*.cpp') { |file|
  # skip ast (excluding paste, astpath, and canv'ast'imer)
  next if file =~ /ast[^eip]|keywords\.|qualifiers|preprocessor|names.cpp/i
  s = File.read(file)
  next if s.include?('qlalr')
  orig = s.dup
  s.gsub!(/\n *if [^\n]*{\n[^\n]*\n\s+}(\s+else if [^\n]* {\n[^\n]*\n\s+})*(\s+else {\n[^\n]*\n\s+})?\n/m) { |m|
    res = $&
    if res =~ /^\s*(\/\/|[A-Z_]{3,})/ # C++ comment or macro (Q_UNUSED, SDEBUG), do not touch braces
      res
    else
      res.gsub!('} else', 'else')
      res.gsub!(/\n +} *\n/m, "\n")
      res.gsub(/ *{$/, '')
    end
  }
  s.gsub!(/ *$/, '')
  File.open(file, 'wb').write(s) if s != orig
}
Change-Id: I3b30ee60df0986f66c02132c65fc38a3fbb6bbdc
Reviewed-by: hjk <qthjk@ovi.com>
											
										 
											2013-01-08 03:32:53 +02:00
										 |  |  |         if (UiObjectDefinition *parentObjectDefinition = cast<UiObjectDefinition *>(parent)) | 
					
						
							| 
									
										
										
										
											2010-07-21 13:49:14 +02:00
										 |  |  |             includeEmptyGroupedProperty(parentObjectDefinition, member, start, end); | 
					
						
							| 
									
										
										
										
											2010-07-20 12:47:50 +02:00
										 |  |  |         includeSurroundingWhitespace(m_originalText, start, end); | 
					
						
							| 
									
										
										
										
											2010-06-30 13:42:35 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-20 12:47:50 +02:00
										 |  |  |     includeLeadingEmptyLine(m_originalText, start); | 
					
						
							| 
									
										
										
										
											2010-07-09 16:01:19 +02:00
										 |  |  |     m_changeSet->remove(start, end); | 
					
						
							| 
									
										
										
										
											2010-06-30 13:42:35 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void Rewriter::extendToLeadingOrTrailingComma(UiArrayBinding *parentArray, | 
					
						
							|  |  |  |                                               UiObjectMember *member, | 
					
						
							|  |  |  |                                               int &start, | 
					
						
							|  |  |  |                                               int &end) const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     UiArrayMemberList *currentMember = 0; | 
					
						
							|  |  |  |     for (UiArrayMemberList *it = parentArray->members; it; it = it->next) { | 
					
						
							|  |  |  |         if (it->member == member) { | 
					
						
							|  |  |  |             currentMember = it; | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!currentMember) | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (currentMember->commaToken.isValid()) { | 
					
						
							|  |  |  |         // leading comma
 | 
					
						
							|  |  |  |         start = currentMember->commaToken.offset; | 
					
						
							| 
									
										
										
										
											2010-07-20 12:47:50 +02:00
										 |  |  |         if (includeSurroundingWhitespace(m_originalText, start, end)) | 
					
						
							| 
									
										
										
										
											2010-06-30 13:42:35 +02:00
										 |  |  |             --end; | 
					
						
							|  |  |  |     } else if (currentMember->next && currentMember->next->commaToken.isValid()) { | 
					
						
							|  |  |  |         // trailing comma
 | 
					
						
							|  |  |  |         end = currentMember->next->commaToken.end(); | 
					
						
							| 
									
										
										
										
											2010-07-20 12:47:50 +02:00
										 |  |  |         includeSurroundingWhitespace(m_originalText, start, end); | 
					
						
							| 
									
										
										
										
											2010-06-30 13:42:35 +02:00
										 |  |  |     } else { | 
					
						
							|  |  |  |         // array with 1 element, so remove the complete binding
 | 
					
						
							|  |  |  |         start = parentArray->firstSourceLocation().offset; | 
					
						
							|  |  |  |         end = parentArray->lastSourceLocation().end(); | 
					
						
							| 
									
										
										
										
											2010-07-20 12:47:50 +02:00
										 |  |  |         includeSurroundingWhitespace(m_originalText, start, end); | 
					
						
							| 
									
										
										
										
											2010-06-30 13:42:35 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | } |