1 /**************************************************************************
3 ** This file is part of Qt Creator
5 ** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
7 ** Contact: Nokia Corporation (qt-info@nokia.com)
11 ** This file contains pre-release code and may not be distributed.
12 ** You may use this file in accordance with the terms and conditions
13 ** contained in the Technology Preview License Agreement accompanying
16 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25 ** In addition, as a special exception, Nokia gives you certain additional
26 ** rights. These rights are described in the Nokia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29 ** If you have questions regarding the use of this file, please contact
30 ** Nokia at qt-info@nokia.com.
32 **************************************************************************/
34 #include "moveobjectbeforeobjectvisitor.h"
35 #include "textmodifier.h"
37 #include <qmljs/parser/qmljsast_p.h>
38 #include <qmljs/parser/qmljsengine_p.h>
40 #include <QtCore/QDebug>
42 using namespace QmlJS;
43 using namespace QmlJS::AST;
44 using namespace QmlDesigner::Internal;
45 using namespace QmlDesigner;
47 MoveObjectBeforeObjectVisitor::MoveObjectBeforeObjectVisitor(TextModifier &modifier,
48 quint32 movingObjectLocation,
49 bool inDefaultProperty):
50 QMLRewriter(modifier),
51 movingObjectLocation(movingObjectLocation),
52 inDefaultProperty(inDefaultProperty),
54 beforeObjectLocation(0)
57 MoveObjectBeforeObjectVisitor::MoveObjectBeforeObjectVisitor(TextModifier &modifier,
58 quint32 movingObjectLocation,
59 quint32 beforeObjectLocation,
60 bool inDefaultProperty):
61 QMLRewriter(modifier),
62 movingObjectLocation(movingObjectLocation),
63 inDefaultProperty(inDefaultProperty),
65 beforeObjectLocation(beforeObjectLocation)
68 bool MoveObjectBeforeObjectVisitor::operator ()(QmlJS::AST::UiProgram *ast)
72 movingObjectParents.clear();
74 QMLRewriter::operator ()(ast);
76 if (foundEverything()) {
80 return didRewriting();
83 bool MoveObjectBeforeObjectVisitor::preVisit(Node *ast)
84 { if (ast) parents.push(ast); return true; }
86 void MoveObjectBeforeObjectVisitor::postVisit(Node *ast)
87 { if (ast) parents.pop(); }
89 bool MoveObjectBeforeObjectVisitor::visit(UiObjectDefinition *ast)
91 if (foundEverything())
94 const quint32 start = ast->firstSourceLocation().offset;
95 if (start == movingObjectLocation) {
97 movingObjectParents = parents;
98 movingObjectParents.pop();
99 } else if (!toEnd && start == beforeObjectLocation) {
103 if (movingObjectLocation < start)
105 else if (!toEnd && beforeObjectLocation < start)
107 else if (foundEverything())
113 void MoveObjectBeforeObjectVisitor::doMove()
115 Q_ASSERT(movingObject);
116 Q_ASSERT(!movingObjectParents.isEmpty());
118 TextModifier::MoveInfo moveInfo;
119 Node *parent = movingObjectParent();
120 UiArrayMemberList *arrayMember = 0, *otherArrayMember = 0;
123 if (!inDefaultProperty) {
124 UiArrayBinding *initializer = cast<UiArrayBinding*>(parent);
125 Q_ASSERT(initializer);
127 otherArrayMember = 0;
128 for (UiArrayMemberList *cur = initializer->members; cur; cur = cur->next) {
129 if (cur->member == movingObject) {
132 otherArrayMember = cur->next;
135 otherArrayMember = cur;
137 Q_ASSERT(arrayMember && otherArrayMember);
138 separator = QLatin1String(",");
141 moveInfo.objectStart = movingObject->firstSourceLocation().offset;
142 moveInfo.objectEnd = movingObject->lastSourceLocation().end();
144 int start = moveInfo.objectStart;
145 int end = moveInfo.objectEnd;
146 if (!inDefaultProperty) {
147 if (arrayMember->commaToken.isValid()) {
148 start = arrayMember->commaToken.begin();
151 end = otherArrayMember->commaToken.end();
155 includeSurroundingWhitespace(start, end);
156 moveInfo.leadingCharsToRemove = moveInfo.objectStart - start;
157 moveInfo.trailingCharsToRemove = end - moveInfo.objectEnd;
160 moveInfo.destination = beforeObject->firstSourceLocation().offset;
162 includeSurroundingWhitespace(moveInfo.destination, dummy);
164 moveInfo.prefixToInsert = QString(moveInfo.leadingCharsToRemove, QLatin1Char(' '));
165 moveInfo.suffixToInsert = separator + QLatin1String("\n\n");
167 const SourceLocation insertionPoint = lastParentLocation();
168 Q_ASSERT(insertionPoint.isValid());
169 moveInfo.destination = insertionPoint.offset;
171 includeSurroundingWhitespace(moveInfo.destination, dummy);
173 moveInfo.prefixToInsert = separator + QString(moveInfo.leadingCharsToRemove, QLatin1Char(' '));
174 moveInfo.suffixToInsert = QLatin1String("\n");
178 setDidRewriting(true);
181 Node *MoveObjectBeforeObjectVisitor::movingObjectParent() const
183 if (movingObjectParents.size() > 1)
184 return movingObjectParents.at(movingObjectParents.size() - 2);
189 SourceLocation MoveObjectBeforeObjectVisitor::lastParentLocation() const
191 dump(movingObjectParents);
193 Node *parent = movingObjectParent();
194 if (UiObjectInitializer *initializer = cast<UiObjectInitializer*>(parent))
195 return initializer->rbraceToken;
196 else if (UiArrayBinding *initializer = cast<UiArrayBinding*>(parent))
197 return initializer->rbracketToken;
199 return SourceLocation();