forked from qt-creator/qt-creator
Added import rewriting.
This commit is contained in:
@@ -27,8 +27,8 @@
|
||||
**
|
||||
**************************************************************************/
|
||||
|
||||
#include <qmljsast_p.h>
|
||||
#include <qmljsengine_p.h>
|
||||
#include <qmljs/parser/qmljsast_p.h>
|
||||
#include <qmljs/parser/qmljsengine_p.h>
|
||||
|
||||
#include "changeimportsvisitor.h"
|
||||
|
||||
@@ -37,44 +37,67 @@ using namespace QmlJS::AST;
|
||||
|
||||
using namespace QmlDesigner;
|
||||
using namespace QmlDesigner::Internal;
|
||||
using namespace QmlDesigner::Internal;
|
||||
|
||||
ChangeImportsVisitor::ChangeImportsVisitor(TextModifier &textModifier, const QSet<Import> &addedImports, const QSet<Import> &removedImports, const QString &source):
|
||||
QMLRewriter(textModifier),
|
||||
CopyPasteUtil(source),
|
||||
m_addedImports(addedImports),
|
||||
m_removedImports(removedImports)
|
||||
{
|
||||
}
|
||||
|
||||
bool ChangeImportsVisitor::visit(QmlJS::AST::UiProgram *ast)
|
||||
{
|
||||
if (ast->imports)
|
||||
accept(ast->imports);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ChangeImportsVisitor::visit(QmlJS::AST::UiImportList *ast)
|
||||
ChangeImportsVisitor::ChangeImportsVisitor(TextModifier &textModifier,
|
||||
const QString &source):
|
||||
QMLRewriter(textModifier), m_source(source)
|
||||
{}
|
||||
|
||||
bool ChangeImportsVisitor::add(QmlJS::AST::UiProgram *ast, const Import &import)
|
||||
{
|
||||
setDidRewriting(false);
|
||||
if (!ast)
|
||||
return false;
|
||||
|
||||
quint32 prevEnd = 0;
|
||||
for (UiImportList *it = ast; it; it = it->next) {
|
||||
UiImport *imp = it->import;
|
||||
if (!imp)
|
||||
continue;
|
||||
|
||||
if (m_removedImports.remove(createImport(imp)))
|
||||
replace(prevEnd, imp->lastSourceLocation().end() - prevEnd, "");
|
||||
|
||||
prevEnd = imp->lastSourceLocation().end();
|
||||
if (ast->imports && ast->imports->import) {
|
||||
int insertionPoint = 0;
|
||||
if (ast->members && ast->members->member) {
|
||||
insertionPoint = ast->members->member->firstSourceLocation().begin();
|
||||
} else {
|
||||
insertionPoint = m_source.length();
|
||||
}
|
||||
while (insertionPoint > 0) {
|
||||
--insertionPoint;
|
||||
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) {
|
||||
replace(prevEnd, 0, i.toString(false) + "\n");
|
||||
}
|
||||
setDidRewriting(true);
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,27 +32,24 @@
|
||||
|
||||
#include <QtCore/QSet>
|
||||
|
||||
#include <model/copypasteutil.h>
|
||||
#include "import.h"
|
||||
#include "qmlrewriter.h"
|
||||
|
||||
namespace QmlDesigner {
|
||||
namespace Internal {
|
||||
|
||||
class ChangeImportsVisitor: public QMLRewriter, protected QmlDesigner::Internal::CopyPasteUtil
|
||||
class ChangeImportsVisitor: public QMLRewriter
|
||||
{
|
||||
public:
|
||||
ChangeImportsVisitor(QmlDesigner::TextModifier &textModifier,
|
||||
const QSet<QmlDesigner::Import> &addedImports,
|
||||
const QSet<QmlDesigner::Import> &removedImports, const QString &source);
|
||||
ChangeImportsVisitor(QmlDesigner::TextModifier &textModifier, const QString &source);
|
||||
|
||||
protected:
|
||||
virtual bool visit(QmlJS::AST::UiProgram *ast);
|
||||
virtual bool visit(QmlJS::AST::UiImportList *ast);
|
||||
bool add(QmlJS::AST::UiProgram *ast, const Import &import);
|
||||
bool remove(QmlJS::AST::UiProgram *ast, const Import &import);
|
||||
|
||||
private:
|
||||
QSet<QmlDesigner::Import> m_addedImports;
|
||||
QSet<QmlDesigner::Import> m_removedImports;
|
||||
static bool equals(QmlJS::AST::UiImport *ast, const Import &import);
|
||||
|
||||
QString m_source;
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
|
||||
@@ -12,7 +12,8 @@ SOURCES += \
|
||||
$$PWD/astobjecttextextractor.cpp \
|
||||
$$PWD/objectlengthcalculator.cpp \
|
||||
$$PWD/firstdefinitionfinder.cpp \
|
||||
$$PWD/moveobjectbeforeobjectvisitor.cpp
|
||||
$$PWD/moveobjectbeforeobjectvisitor.cpp \
|
||||
$$PWD/changeimportsvisitor.cpp
|
||||
HEADERS += \
|
||||
$$PWD/qmlrewriter.h \
|
||||
$$PWD/qmlrefactoring.h \
|
||||
@@ -27,4 +28,5 @@ HEADERS += \
|
||||
$$PWD/astobjecttextextractor.h \
|
||||
$$PWD/objectlengthcalculator.h \
|
||||
$$PWD/firstdefinitionfinder.h \
|
||||
$$PWD/moveobjectbeforeobjectvisitor.h
|
||||
$$PWD/moveobjectbeforeobjectvisitor.h \
|
||||
$$PWD/changeimportsvisitor.h
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#include "addarraymembervisitor.h"
|
||||
#include "addobjectvisitor.h"
|
||||
#include "addpropertyvisitor.h"
|
||||
#include "changeimportsvisitor.h"
|
||||
#include "changeobjecttypevisitor.h"
|
||||
#include "changepropertyvisitor.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());
|
||||
// visit(qmlDocument->program());
|
||||
return false;
|
||||
ChangeImportsVisitor visitor(*textModifier, qmlDocument->source());
|
||||
return visitor.add(qmlDocument->qmlProgram(), import);
|
||||
}
|
||||
|
||||
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)
|
||||
|
||||
@@ -55,7 +55,8 @@ public:
|
||||
|
||||
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 addToObjectMemberList(int parentLocation, const QString &content);
|
||||
|
||||
@@ -31,7 +31,6 @@
|
||||
#define IMPORT_H
|
||||
|
||||
#include <QtCore/QString>
|
||||
#include <QtCore/QUrl>
|
||||
|
||||
#include "corelib_global.h"
|
||||
|
||||
@@ -40,7 +39,7 @@ namespace QmlDesigner {
|
||||
class CORESHARED_EXPORT Import
|
||||
{
|
||||
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 empty();
|
||||
|
||||
@@ -50,7 +49,7 @@ public:
|
||||
bool hasVersion() const { return !m_version.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 version() const { return m_version; }
|
||||
QString alias() const { return m_alias; }
|
||||
@@ -60,10 +59,10 @@ public:
|
||||
bool operator==(const Import &other) const;
|
||||
|
||||
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:
|
||||
QUrl m_url;
|
||||
QString m_url;
|
||||
QString m_file;
|
||||
QString m_version;
|
||||
QString m_alias;
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -33,22 +33,22 @@
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
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_file(file),
|
||||
m_version(version),
|
||||
@@ -63,7 +63,7 @@ QString Import::toString(bool addSemicolon) const
|
||||
if (isFileImport())
|
||||
result += '"' + file() + '"';
|
||||
else if (isLibraryImport())
|
||||
result += url().toString();
|
||||
result += url();
|
||||
else
|
||||
return QString();
|
||||
|
||||
@@ -86,7 +86,7 @@ bool Import::operator==(const Import &other) const
|
||||
|
||||
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
|
||||
|
||||
@@ -133,6 +133,18 @@ void ModelToTextMerger::nodeTypeChanged(const ModelNode &node,const QString &/*t
|
||||
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)
|
||||
{
|
||||
if (isInHierarchy(oldPropertyParent) && isInHierarchy(newPropertyParent)) { // the node is moved
|
||||
|
||||
@@ -74,6 +74,9 @@ public:
|
||||
void nodeSlidAround(const ModelNode &movingNode, const ModelNode &inFrontOfNode);
|
||||
void nodeTypeChanged(const ModelNode &node,const QString &type, int majorVersion, int minorVersion);
|
||||
|
||||
void addImport(const Import &import);
|
||||
void removeImport(const Import &import);
|
||||
|
||||
protected:
|
||||
RewriterView *view();
|
||||
|
||||
|
||||
@@ -36,6 +36,37 @@ using namespace QmlDesigner;
|
||||
using namespace QmlDesigner::Internal;
|
||||
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)
|
||||
{
|
||||
switch (type) {
|
||||
@@ -46,6 +77,8 @@ static inline QString toString(QmlRefactoring::PropertyType type)
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace anonymous
|
||||
|
||||
bool AddPropertyRewriteAction::execute(QmlRefactoring &refactoring, ModelNodePositionStorage &positionStore)
|
||||
{
|
||||
const int nodeLocation = positionStore.nodeOffset(m_property.parentModelNode());
|
||||
@@ -302,3 +335,39 @@ QString MoveNodeRewriteAction::info() const
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -38,10 +38,12 @@
|
||||
namespace QmlDesigner {
|
||||
namespace Internal {
|
||||
|
||||
class AddImportRewriteAction;
|
||||
class AddPropertyRewriteAction;
|
||||
class ChangeIdRewriteAction;
|
||||
class ChangePropertyRewriteAction;
|
||||
class ChangeTypeRewriteAction;
|
||||
class RemoveImportRewriteAction;
|
||||
class RemoveNodeRewriteAction;
|
||||
class RemovePropertyRewriteAction;
|
||||
class ReparentNodeRewriteAction;
|
||||
@@ -53,10 +55,12 @@ public:
|
||||
virtual bool execute(QmlDesigner::QmlRefactoring &refactoring, ModelNodePositionStorage &positionStore) = 0;
|
||||
virtual QString info() const = 0;
|
||||
|
||||
virtual AddImportRewriteAction const *asAddImportRewriteAction() const { return 0; }
|
||||
virtual AddPropertyRewriteAction const *asAddPropertyRewriteAction() const { return 0; }
|
||||
virtual ChangeIdRewriteAction const *asChangeIdRewriteAction() const { return 0; }
|
||||
virtual ChangePropertyRewriteAction const *asChangePropertyRewriteAction() 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 RemovePropertyRewriteAction const *asRemovePropertyRewriteAction() const { return 0; }
|
||||
virtual ReparentNodeRewriteAction const *asReparentNodeRewriteAction() const { return 0; }
|
||||
@@ -255,6 +259,42 @@ private:
|
||||
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 QmlDesigner
|
||||
|
||||
|
||||
@@ -56,6 +56,7 @@ static bool nodeOrParentInSet(const ModelNode &node, const QSet<ModelNode> &node
|
||||
|
||||
void RewriteActionCompressor::operator()(QList<RewriteAction *> &actions) const
|
||||
{
|
||||
compressImports(actions);
|
||||
compressReparentActions(actions);
|
||||
compressPropertyActions(actions);
|
||||
compressAddEditRemoveNodeActions(actions);
|
||||
@@ -63,6 +64,47 @@ void RewriteActionCompressor::operator()(QList<RewriteAction *> &actions) const
|
||||
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
|
||||
{
|
||||
QSet<ModelNode> reparentedNodes;
|
||||
|
||||
@@ -45,6 +45,8 @@ public:
|
||||
void operator()(QList<RewriteAction *> &actions) const;
|
||||
|
||||
private:
|
||||
void compressImports(QList<RewriteAction *> &actions) const;
|
||||
|
||||
void compressReparentActions(QList<RewriteAction *> &actions) const;
|
||||
void compressAddEditRemoveNodeActions(QList<RewriteAction *> &actions) const;
|
||||
void compressPropertyActions(QList<RewriteAction *> &actions) const;
|
||||
|
||||
@@ -75,7 +75,7 @@ void TextToModelMerger::setupImports(QmlDomDocument &doc,
|
||||
|
||||
foreach (const QmlDomImport &qmlImport, doc.imports()) {
|
||||
if (qmlImport.type() == QmlDomImport::Library) {
|
||||
Import import(Import::createLibraryImport(QUrl(qmlImport.uri()),
|
||||
Import import(Import::createLibraryImport(qmlImport.uri(),
|
||||
qmlImport.version(),
|
||||
qmlImport.qualifier()));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user