Added import rewriting.

This commit is contained in:
Erik Verbruggen
2010-02-01 16:04:24 +01:00
parent 7d79f4f87a
commit bfac509b4a
16 changed files with 259 additions and 187 deletions

View File

@@ -27,8 +27,8 @@
** **
**************************************************************************/ **************************************************************************/
#include <qmljsast_p.h> #include <qmljs/parser/qmljsast_p.h>
#include <qmljsengine_p.h> #include <qmljs/parser/qmljsengine_p.h>
#include "changeimportsvisitor.h" #include "changeimportsvisitor.h"
@@ -37,44 +37,67 @@ using namespace QmlJS::AST;
using namespace QmlDesigner; using namespace QmlDesigner;
using namespace QmlDesigner::Internal; using namespace QmlDesigner::Internal;
using namespace QmlDesigner::Internal;
ChangeImportsVisitor::ChangeImportsVisitor(TextModifier &textModifier, const QSet<Import> &addedImports, const QSet<Import> &removedImports, const QString &source): ChangeImportsVisitor::ChangeImportsVisitor(TextModifier &textModifier,
QMLRewriter(textModifier), const QString &source):
CopyPasteUtil(source), QMLRewriter(textModifier), m_source(source)
m_addedImports(addedImports), {}
m_removedImports(removedImports)
{ bool ChangeImportsVisitor::add(QmlJS::AST::UiProgram *ast, const Import &import)
}
bool ChangeImportsVisitor::visit(QmlJS::AST::UiProgram *ast)
{
if (ast->imports)
accept(ast->imports);
return false;
}
bool ChangeImportsVisitor::visit(QmlJS::AST::UiImportList *ast)
{ {
setDidRewriting(false);
if (!ast) if (!ast)
return false; return false;
quint32 prevEnd = 0; if (ast->imports && ast->imports->import) {
for (UiImportList *it = ast; it; it = it->next) { int insertionPoint = 0;
UiImport *imp = it->import; if (ast->members && ast->members->member) {
if (!imp) insertionPoint = ast->members->member->firstSourceLocation().begin();
continue; } else {
insertionPoint = m_source.length();
if (m_removedImports.remove(createImport(imp))) }
replace(prevEnd, imp->lastSourceLocation().end() - prevEnd, ""); while (insertionPoint > 0) {
--insertionPoint;
prevEnd = imp->lastSourceLocation().end(); const QChar c = m_source.at(insertionPoint);
if (!c.isSpace() && c != QLatin1Char(';'))
break;
}
replace(insertionPoint, 0, QLatin1String("\n") + import.toString(false));
} else {
replace(0, 0, import.toString(false) + QLatin1String("\n\n"));
} }
foreach (const Import &i, m_addedImports) { setDidRewriting(true);
replace(prevEnd, 0, i.toString(false) + "\n");
}
return false; return true;
}
bool ChangeImportsVisitor::remove(QmlJS::AST::UiProgram *ast, const Import &import)
{
setDidRewriting(false);
if (!ast)
return false;
for (UiImportList *iter = ast->imports; iter; iter = iter->next) {
if (equals(iter->import, import)) {
int start = iter->firstSourceLocation().begin();
int end = iter->lastSourceLocation().end();
includeSurroundingWhitespace(start, end);
replace(start, end - start, QString());
setDidRewriting(true);
}
}
return didRewriting();
}
bool ChangeImportsVisitor::equals(QmlJS::AST::UiImport *ast, const Import &import)
{
if (import.isLibraryImport()) {
return flatten(ast->importUri) == import.url();
} else if (import.isFileImport()) {
return ast->fileName->asString() == import.file();
} else {
return false;
}
} }

View File

@@ -32,27 +32,24 @@
#include <QtCore/QSet> #include <QtCore/QSet>
#include <model/copypasteutil.h>
#include "import.h" #include "import.h"
#include "qmlrewriter.h" #include "qmlrewriter.h"
namespace QmlDesigner { namespace QmlDesigner {
namespace Internal { namespace Internal {
class ChangeImportsVisitor: public QMLRewriter, protected QmlDesigner::Internal::CopyPasteUtil class ChangeImportsVisitor: public QMLRewriter
{ {
public: public:
ChangeImportsVisitor(QmlDesigner::TextModifier &textModifier, ChangeImportsVisitor(QmlDesigner::TextModifier &textModifier, const QString &source);
const QSet<QmlDesigner::Import> &addedImports,
const QSet<QmlDesigner::Import> &removedImports, const QString &source);
protected: bool add(QmlJS::AST::UiProgram *ast, const Import &import);
virtual bool visit(QmlJS::AST::UiProgram *ast); bool remove(QmlJS::AST::UiProgram *ast, const Import &import);
virtual bool visit(QmlJS::AST::UiImportList *ast);
private: private:
QSet<QmlDesigner::Import> m_addedImports; static bool equals(QmlJS::AST::UiImport *ast, const Import &import);
QSet<QmlDesigner::Import> m_removedImports;
QString m_source;
}; };
} // namespace Internal } // namespace Internal

View File

@@ -12,7 +12,8 @@ SOURCES += \
$$PWD/astobjecttextextractor.cpp \ $$PWD/astobjecttextextractor.cpp \
$$PWD/objectlengthcalculator.cpp \ $$PWD/objectlengthcalculator.cpp \
$$PWD/firstdefinitionfinder.cpp \ $$PWD/firstdefinitionfinder.cpp \
$$PWD/moveobjectbeforeobjectvisitor.cpp $$PWD/moveobjectbeforeobjectvisitor.cpp \
$$PWD/changeimportsvisitor.cpp
HEADERS += \ HEADERS += \
$$PWD/qmlrewriter.h \ $$PWD/qmlrewriter.h \
$$PWD/qmlrefactoring.h \ $$PWD/qmlrefactoring.h \
@@ -27,4 +28,5 @@ HEADERS += \
$$PWD/astobjecttextextractor.h \ $$PWD/astobjecttextextractor.h \
$$PWD/objectlengthcalculator.h \ $$PWD/objectlengthcalculator.h \
$$PWD/firstdefinitionfinder.h \ $$PWD/firstdefinitionfinder.h \
$$PWD/moveobjectbeforeobjectvisitor.h $$PWD/moveobjectbeforeobjectvisitor.h \
$$PWD/changeimportsvisitor.h

View File

@@ -32,6 +32,7 @@
#include "addarraymembervisitor.h" #include "addarraymembervisitor.h"
#include "addobjectvisitor.h" #include "addobjectvisitor.h"
#include "addpropertyvisitor.h" #include "addpropertyvisitor.h"
#include "changeimportsvisitor.h"
#include "changeobjecttypevisitor.h" #include "changeobjecttypevisitor.h"
#include "changepropertyvisitor.h" #include "changepropertyvisitor.h"
#include "moveobjectvisitor.h" #include "moveobjectvisitor.h"
@@ -70,11 +71,16 @@ bool QmlRefactoring::reparseDocument()
} }
} }
bool QmlRefactoring::changeImports(const QSet<QmlDesigner::Import> &/*addedImports*/, const QSet<QmlDesigner::Import> &/*removedImports*/) bool QmlRefactoring::addImport(const Import &import)
{ {
// ChangeImportsVisitor visit(*textModifier, addedImports, removedImports, qmlDocument->source()); ChangeImportsVisitor visitor(*textModifier, qmlDocument->source());
// visit(qmlDocument->program()); return visitor.add(qmlDocument->qmlProgram(), import);
return false; }
bool QmlRefactoring::removeImport(const Import &import)
{
ChangeImportsVisitor visitor(*textModifier, qmlDocument->source());
return visitor.remove(qmlDocument->qmlProgram(), import);
} }
bool QmlRefactoring::addToArrayMemberList(int parentLocation, const QString &propertyName, const QString &content) bool QmlRefactoring::addToArrayMemberList(int parentLocation, const QString &propertyName, const QString &content)

View File

@@ -55,7 +55,8 @@ public:
bool reparseDocument(); bool reparseDocument();
bool changeImports(const QSet<QmlDesigner::Import> &addedImports, const QSet<QmlDesigner::Import> &removedImports); bool addImport(const Import &import);
bool removeImport(const Import &import);
bool addToArrayMemberList(int parentLocation, const QString &propertyName, const QString &content); bool addToArrayMemberList(int parentLocation, const QString &propertyName, const QString &content);
bool addToObjectMemberList(int parentLocation, const QString &content); bool addToObjectMemberList(int parentLocation, const QString &content);

View File

@@ -31,7 +31,6 @@
#define IMPORT_H #define IMPORT_H
#include <QtCore/QString> #include <QtCore/QString>
#include <QtCore/QUrl>
#include "corelib_global.h" #include "corelib_global.h"
@@ -40,7 +39,7 @@ namespace QmlDesigner {
class CORESHARED_EXPORT Import class CORESHARED_EXPORT Import
{ {
public: public:
static Import createLibraryImport(const QUrl &url, const QString &version = QString(), const QString &alias = QString()); static Import createLibraryImport(const QString &url, const QString &version = QString(), const QString &alias = QString());
static Import createFileImport(const QString &file, const QString &version = QString(), const QString &alias = QString()); static Import createFileImport(const QString &file, const QString &version = QString(), const QString &alias = QString());
static Import empty(); static Import empty();
@@ -50,7 +49,7 @@ public:
bool hasVersion() const { return !m_version.isEmpty(); } bool hasVersion() const { return !m_version.isEmpty(); }
bool hasAlias() const { return !m_alias.isEmpty(); } bool hasAlias() const { return !m_alias.isEmpty(); }
QUrl url() const { return m_url; } QString url() const { return m_url; }
QString file() const { return m_file; } QString file() const { return m_file; }
QString version() const { return m_version; } QString version() const { return m_version; }
QString alias() const { return m_alias; } QString alias() const { return m_alias; }
@@ -60,10 +59,10 @@ public:
bool operator==(const Import &other) const; bool operator==(const Import &other) const;
private: private:
Import(const QUrl &url, const QString &file, const QString &version, const QString &alias); Import(const QString &url, const QString &file, const QString &version, const QString &alias);
private: private:
QUrl m_url; QString m_url;
QString m_file; QString m_file;
QString m_version; QString m_version;
QString m_alias; QString m_alias;

View File

@@ -1,61 +0,0 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
**
** 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.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://qt.nokia.com/contact.
**
**************************************************************************/
#include <qmljsast_p.h>
#include <qmljsengine_p.h>
#include "copypasteutil.h"
using namespace QmlJS;
using namespace QmlJS::AST;
namespace QmlDesigner {
namespace Internal {
Import CopyPasteUtil::createImport(QmlJS::AST::UiImport *ast)
{
QString version;
if (ast->versionToken.isValid())
version = textAt(ast->versionToken);
QString alias;
if (ast->importId)
alias = ast->importId->asString();
if (ast->fileName)
return Import::createFileImport(ast->fileName->asString(), version, alias);
if (ast->importUri && ast->importUri->name)
return Import::createLibraryImport(ast->importUri->name->asString(), version, alias);
return Import::empty();
}
} // namespace Internal
} // namespace QmlDesigner

View File

@@ -1,63 +0,0 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
**
** 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.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://qt.nokia.com/contact.
**
**************************************************************************/
#ifndef COPYPASTEUTIL_H
#define COPYPASTEUTIL_H
#include <qmljsastfwd_p.h>
#include "import.h"
namespace QmlDesigner {
namespace Internal {
class CopyPasteUtil {
public:
CopyPasteUtil(const QString &originalSource): m_originalSource(originalSource)
{}
Import createImport(QmlJS::AST::UiImport *ast);
protected:
QString textAt(const QmlJS::AST::SourceLocation &loc) const
{ return m_originalSource.mid(loc.offset, loc.length); }
QString textAt(const QmlJS::AST::SourceLocation &firstSourceLocation, const QmlJS::AST::SourceLocation &lastSourceLocation) const
{ return m_originalSource.mid(firstSourceLocation.offset, lastSourceLocation.end() - firstSourceLocation.offset); }
QString originalSource() const { return m_originalSource; }
private:
QString m_originalSource;
};
} // namespace Internal
} // namespace QmlDesigner
#endif // COPYPASTEUTIL_H

View File

@@ -33,22 +33,22 @@
namespace QmlDesigner { namespace QmlDesigner {
Import Import::createLibraryImport(const QUrl &url, const QString &version, const QString &alias) Import Import::createLibraryImport(const QString &url, const QString &version, const QString &alias)
{ {
return Import(url, QString(), version, alias); return Import(url, QString(), version, alias);
} }
Import Import::createFileImport(const QString &file, const QString &version, const QString &alias) Import Import::createFileImport(const QString &file, const QString &version, const QString &alias)
{ {
return Import(QUrl(), file, version, alias); return Import(QString(), file, version, alias);
} }
Import Import::empty() Import Import::empty()
{ {
return Import(QUrl(), QString(), QString(), QString()); return Import(QString(), QString(), QString(), QString());
} }
Import::Import(const QUrl &url, const QString &file, const QString &version, const QString &alias): Import::Import(const QString &url, const QString &file, const QString &version, const QString &alias):
m_url(url), m_url(url),
m_file(file), m_file(file),
m_version(version), m_version(version),
@@ -63,7 +63,7 @@ QString Import::toString(bool addSemicolon) const
if (isFileImport()) if (isFileImport())
result += '"' + file() + '"'; result += '"' + file() + '"';
else if (isLibraryImport()) else if (isLibraryImport())
result += url().toString(); result += url();
else else
return QString(); return QString();
@@ -86,7 +86,7 @@ bool Import::operator==(const Import &other) const
uint qHash(const Import &import) uint qHash(const Import &import)
{ {
return ::qHash(import.url().toString()) ^ ::qHash(import.file()) ^ ::qHash(import.version()) ^ ::qHash(import.alias()); return ::qHash(import.url()) ^ ::qHash(import.file()) ^ ::qHash(import.version()) ^ ::qHash(import.alias());
} }
} // namespace QmlDesigner } // namespace QmlDesigner

View File

@@ -133,6 +133,18 @@ void ModelToTextMerger::nodeTypeChanged(const ModelNode &node,const QString &/*t
schedule(new ChangeTypeRewriteAction(node)); schedule(new ChangeTypeRewriteAction(node));
} }
void ModelToTextMerger::addImport(const Import &import)
{
if (!import.isEmpty())
schedule(new AddImportRewriteAction(import));
}
void ModelToTextMerger::removeImport(const Import &import)
{
if (!import.isEmpty())
schedule(new RemoveImportRewriteAction(import));
}
void ModelToTextMerger::nodeReparented(const ModelNode &node, const NodeAbstractProperty &newPropertyParent, const NodeAbstractProperty &oldPropertyParent, AbstractView::PropertyChangeFlags propertyChange) void ModelToTextMerger::nodeReparented(const ModelNode &node, const NodeAbstractProperty &newPropertyParent, const NodeAbstractProperty &oldPropertyParent, AbstractView::PropertyChangeFlags propertyChange)
{ {
if (isInHierarchy(oldPropertyParent) && isInHierarchy(newPropertyParent)) { // the node is moved if (isInHierarchy(oldPropertyParent) && isInHierarchy(newPropertyParent)) { // the node is moved

View File

@@ -74,6 +74,9 @@ public:
void nodeSlidAround(const ModelNode &movingNode, const ModelNode &inFrontOfNode); void nodeSlidAround(const ModelNode &movingNode, const ModelNode &inFrontOfNode);
void nodeTypeChanged(const ModelNode &node,const QString &type, int majorVersion, int minorVersion); void nodeTypeChanged(const ModelNode &node,const QString &type, int majorVersion, int minorVersion);
void addImport(const Import &import);
void removeImport(const Import &import);
protected: protected:
RewriterView *view(); RewriterView *view();

View File

@@ -36,6 +36,37 @@ using namespace QmlDesigner;
using namespace QmlDesigner::Internal; using namespace QmlDesigner::Internal;
using namespace QmlDesigner; using namespace QmlDesigner;
namespace { // anonymous
static inline QString toInfo(const Import &import)
{
QString txt;
if (import.isEmpty()) {
return QLatin1String("empty import");
} else if (import.isFileImport()) {
txt = QLatin1String("import file \"%1\"");
txt = txt.arg(import.url());
} else if (import.isLibraryImport()) {
txt = QLatin1String("import library \"%1\"");
txt = txt.arg(import.file());
} else {
return QLatin1String("unknown type of import");
}
if (import.hasVersion())
txt += QString::fromLatin1("with version \"%1\"").arg(import.version());
else
txt += QLatin1String("without version");
if (import.hasAlias())
txt += QString::fromLatin1("aliassed as \"%1\"").arg(import.alias());
else
txt += QLatin1String("unaliassed");
return txt;
}
static inline QString toString(QmlRefactoring::PropertyType type) static inline QString toString(QmlRefactoring::PropertyType type)
{ {
switch (type) { switch (type) {
@@ -46,6 +77,8 @@ static inline QString toString(QmlRefactoring::PropertyType type)
} }
} }
} // namespace anonymous
bool AddPropertyRewriteAction::execute(QmlRefactoring &refactoring, ModelNodePositionStorage &positionStore) bool AddPropertyRewriteAction::execute(QmlRefactoring &refactoring, ModelNodePositionStorage &positionStore)
{ {
const int nodeLocation = positionStore.nodeOffset(m_property.parentModelNode()); const int nodeLocation = positionStore.nodeOffset(m_property.parentModelNode());
@@ -302,3 +335,39 @@ QString MoveNodeRewriteAction::info() const
return QString("MoveNodeRewriteAction for an invalid node"); return QString("MoveNodeRewriteAction for an invalid node");
} }
} }
bool AddImportRewriteAction::execute(QmlDesigner::QmlRefactoring &refactoring,
ModelNodePositionStorage &/*positionStore*/)
{
const bool result = refactoring.addImport(m_import);
if (!result)
qDebug() << "*** AddImportRewriteAction::execute failed in changeImports ("
<< m_import.toString()
<< ") **"
<< info();
return result;
}
QString AddImportRewriteAction::info() const
{
return toInfo(m_import);
}
bool RemoveImportRewriteAction::execute(QmlDesigner::QmlRefactoring &refactoring,
ModelNodePositionStorage &/*positionStore*/)
{
const bool result = refactoring.addImport(m_import);
if (!result)
qDebug() << "*** RemoveImportRewriteAction::execute failed in changeImports ("
<< m_import.toString()
<< ") **"
<< info();
return result;
}
QString RemoveImportRewriteAction::info() const
{
return toInfo(m_import);
}

View File

@@ -38,10 +38,12 @@
namespace QmlDesigner { namespace QmlDesigner {
namespace Internal { namespace Internal {
class AddImportRewriteAction;
class AddPropertyRewriteAction; class AddPropertyRewriteAction;
class ChangeIdRewriteAction; class ChangeIdRewriteAction;
class ChangePropertyRewriteAction; class ChangePropertyRewriteAction;
class ChangeTypeRewriteAction; class ChangeTypeRewriteAction;
class RemoveImportRewriteAction;
class RemoveNodeRewriteAction; class RemoveNodeRewriteAction;
class RemovePropertyRewriteAction; class RemovePropertyRewriteAction;
class ReparentNodeRewriteAction; class ReparentNodeRewriteAction;
@@ -53,10 +55,12 @@ public:
virtual bool execute(QmlDesigner::QmlRefactoring &refactoring, ModelNodePositionStorage &positionStore) = 0; virtual bool execute(QmlDesigner::QmlRefactoring &refactoring, ModelNodePositionStorage &positionStore) = 0;
virtual QString info() const = 0; virtual QString info() const = 0;
virtual AddImportRewriteAction const *asAddImportRewriteAction() const { return 0; }
virtual AddPropertyRewriteAction const *asAddPropertyRewriteAction() const { return 0; } virtual AddPropertyRewriteAction const *asAddPropertyRewriteAction() const { return 0; }
virtual ChangeIdRewriteAction const *asChangeIdRewriteAction() const { return 0; } virtual ChangeIdRewriteAction const *asChangeIdRewriteAction() const { return 0; }
virtual ChangePropertyRewriteAction const *asChangePropertyRewriteAction() const { return 0; } virtual ChangePropertyRewriteAction const *asChangePropertyRewriteAction() const { return 0; }
virtual ChangeTypeRewriteAction const *asChangeTypeRewriteAction() const { return 0; } virtual ChangeTypeRewriteAction const *asChangeTypeRewriteAction() const { return 0; }
virtual RemoveImportRewriteAction const * asRemoveImportRewriteAction() const { return 0; }
virtual RemoveNodeRewriteAction const *asRemoveNodeRewriteAction() const { return 0; } virtual RemoveNodeRewriteAction const *asRemoveNodeRewriteAction() const { return 0; }
virtual RemovePropertyRewriteAction const *asRemovePropertyRewriteAction() const { return 0; } virtual RemovePropertyRewriteAction const *asRemovePropertyRewriteAction() const { return 0; }
virtual ReparentNodeRewriteAction const *asReparentNodeRewriteAction() const { return 0; } virtual ReparentNodeRewriteAction const *asReparentNodeRewriteAction() const { return 0; }
@@ -255,6 +259,42 @@ private:
ModelNode m_newTrailingNode; ModelNode m_newTrailingNode;
}; };
class AddImportRewriteAction: public RewriteAction
{
public:
AddImportRewriteAction(const Import &import):
m_import(import)
{}
virtual bool execute(QmlDesigner::QmlRefactoring &refactoring, ModelNodePositionStorage &positionStore);
virtual QString info() const;
virtual AddImportRewriteAction const *asAddImportRewriteAction() const { return this; }
Import import() const { return m_import; }
private:
Import m_import;
};
class RemoveImportRewriteAction: public RewriteAction
{
public:
RemoveImportRewriteAction(const Import &import):
m_import(import)
{}
virtual bool execute(QmlDesigner::QmlRefactoring &refactoring, ModelNodePositionStorage &positionStore);
virtual QString info() const;
virtual RemoveImportRewriteAction const *asRemoveImportRewriteAction() const { return this; }
Import import() const { return m_import; }
private:
Import m_import;
};
} // namespace Internal } // namespace Internal
} // namespace QmlDesigner } // namespace QmlDesigner

View File

@@ -56,6 +56,7 @@ static bool nodeOrParentInSet(const ModelNode &node, const QSet<ModelNode> &node
void RewriteActionCompressor::operator()(QList<RewriteAction *> &actions) const void RewriteActionCompressor::operator()(QList<RewriteAction *> &actions) const
{ {
compressImports(actions);
compressReparentActions(actions); compressReparentActions(actions);
compressPropertyActions(actions); compressPropertyActions(actions);
compressAddEditRemoveNodeActions(actions); compressAddEditRemoveNodeActions(actions);
@@ -63,6 +64,47 @@ void RewriteActionCompressor::operator()(QList<RewriteAction *> &actions) const
compressAddReparentActions(actions); compressAddReparentActions(actions);
} }
void RewriteActionCompressor::compressImports(QList<RewriteAction *> &actions) const
{
QHash<Import, RewriteAction *> addedImports;
QHash<Import, RewriteAction *> removedImports;
QMutableListIterator<RewriteAction *> iter(actions);
iter.toBack();
while (iter.hasPrevious()) {
RewriteAction *action = iter.previous();
if (RemoveImportRewriteAction const *removeImportAction = action->asRemoveImportRewriteAction()) {
const Import import = removeImportAction->import();
if (removedImports.contains(import)) {
remove(iter);
} else if (RewriteAction *addImportAction = addedImports.value(import, 0)) {
actions.removeOne(addImportAction);
addedImports.remove(import);
delete addImportAction;
remove(iter);
} else {
removedImports.insert(import, action);
}
} else if (AddImportRewriteAction const *addImportAction = action->asAddImportRewriteAction()) {
const Import import = addImportAction->import();
if (RewriteAction *duplicateAction = addedImports.value(import, 0)) {
actions.removeOne(duplicateAction);
addedImports.remove(import);
delete duplicateAction;
addedImports.insert(import, action);
} else if (RewriteAction *removeAction = removedImports.value(import, 0)) {
actions.removeOne(removeAction);
removedImports.remove(import);
delete removeAction;
remove(iter);
} else {
addedImports.insert(import, action);
}
}
}
}
void RewriteActionCompressor::compressReparentActions(QList<RewriteAction *> &actions) const void RewriteActionCompressor::compressReparentActions(QList<RewriteAction *> &actions) const
{ {
QSet<ModelNode> reparentedNodes; QSet<ModelNode> reparentedNodes;

View File

@@ -45,6 +45,8 @@ public:
void operator()(QList<RewriteAction *> &actions) const; void operator()(QList<RewriteAction *> &actions) const;
private: private:
void compressImports(QList<RewriteAction *> &actions) const;
void compressReparentActions(QList<RewriteAction *> &actions) const; void compressReparentActions(QList<RewriteAction *> &actions) const;
void compressAddEditRemoveNodeActions(QList<RewriteAction *> &actions) const; void compressAddEditRemoveNodeActions(QList<RewriteAction *> &actions) const;
void compressPropertyActions(QList<RewriteAction *> &actions) const; void compressPropertyActions(QList<RewriteAction *> &actions) const;

View File

@@ -75,7 +75,7 @@ void TextToModelMerger::setupImports(QmlDomDocument &doc,
foreach (const QmlDomImport &qmlImport, doc.imports()) { foreach (const QmlDomImport &qmlImport, doc.imports()) {
if (qmlImport.type() == QmlDomImport::Library) { if (qmlImport.type() == QmlDomImport::Library) {
Import import(Import::createLibraryImport(QUrl(qmlImport.uri()), Import import(Import::createLibraryImport(qmlImport.uri(),
qmlImport.version(), qmlImport.version(),
qmlImport.qualifier())); qmlImport.qualifier()));