forked from qt-creator/qt-creator
QmlDesigner: Import only mandatory libraries or directories
Only mandatory files are imported by the newly created component. In the case that the import data is empty, All parent imports would be included. Task-number: QDS-9829 Change-Id: Ie96e2bc04a10e00b15ae12c5e58b5dc2392886ae Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io> Reviewed-by: Miikka Heikkinen <miikka.heikkinen@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
This commit is contained in:
@@ -25,7 +25,7 @@ public:
|
|||||||
TextEditor::TabSettings tabSettings() const override;
|
TextEditor::TabSettings tabSettings() const override;
|
||||||
|
|
||||||
bool renameId(const QString &oldId, const QString &newId) override;
|
bool renameId(const QString &oldId, const QString &newId) override;
|
||||||
bool moveToComponent(int nodeOffset) override;
|
bool moveToComponent(int nodeOffset, const QString &importData) override;
|
||||||
QStringList autoComplete(QTextDocument *textDocument, int position, bool explicitComplete) override;
|
QStringList autoComplete(QTextDocument *textDocument, int position, bool explicitComplete) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ public:
|
|||||||
{ return false; }
|
{ return false; }
|
||||||
QStringList autoComplete(QTextDocument * textDocument, int position, bool explicitComplete) override
|
QStringList autoComplete(QTextDocument * textDocument, int position, bool explicitComplete) override
|
||||||
{ return m_originalModifier->autoComplete(textDocument, position, explicitComplete); }
|
{ return m_originalModifier->autoComplete(textDocument, position, explicitComplete); }
|
||||||
bool moveToComponent(int /* nodeOffset */) override
|
bool moveToComponent(int /* nodeOffset */, const QString & /* importData */) override
|
||||||
{ return false; }
|
{ return false; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -194,6 +194,7 @@ public:
|
|||||||
|
|
||||||
bool isEnumeration() const;
|
bool isEnumeration() const;
|
||||||
QString importDirectoryPath() const;
|
QString importDirectoryPath() const;
|
||||||
|
QString requiredImportString() const;
|
||||||
|
|
||||||
friend bool operator==(const NodeMetaInfo &first, const NodeMetaInfo &second)
|
friend bool operator==(const NodeMetaInfo &first, const NodeMetaInfo &second)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ public:
|
|||||||
QStringList autoComplete(QTextDocument * /*textDocument*/, int /*position*/, bool /*explicitComplete*/) override
|
QStringList autoComplete(QTextDocument * /*textDocument*/, int /*position*/, bool /*explicitComplete*/) override
|
||||||
{ return QStringList(); }
|
{ return QStringList(); }
|
||||||
|
|
||||||
bool moveToComponent(int /* nodeOffset */) override
|
bool moveToComponent(int /* nodeOffset */, const QString & /* importData */) override
|
||||||
{ return false; }
|
{ return false; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ public:
|
|||||||
virtual bool renameId(const QString &oldId, const QString &newId) = 0;
|
virtual bool renameId(const QString &oldId, const QString &newId) = 0;
|
||||||
virtual QStringList autoComplete(QTextDocument * /*textDocument*/, int /*position*/, bool explicitComplete = true) = 0;
|
virtual QStringList autoComplete(QTextDocument * /*textDocument*/, int /*position*/, bool explicitComplete = true) = 0;
|
||||||
|
|
||||||
virtual bool moveToComponent(int nodeOffset) = 0;
|
virtual bool moveToComponent(int nodeOffset, const QString &importData) = 0;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void textChanged();
|
void textChanged();
|
||||||
|
|||||||
@@ -623,6 +623,7 @@ public:
|
|||||||
|
|
||||||
QString componentFileName() const;
|
QString componentFileName() const;
|
||||||
QString importDirectoryPath() const;
|
QString importDirectoryPath() const;
|
||||||
|
Import requiredImport() const;
|
||||||
|
|
||||||
static std::shared_ptr<NodeMetaInfoPrivate> create(Model *model,
|
static std::shared_ptr<NodeMetaInfoPrivate> create(Model *model,
|
||||||
const TypeName &type,
|
const TypeName &type,
|
||||||
@@ -1228,6 +1229,43 @@ QString NodeMetaInfoPrivate::importDirectoryPath() const
|
|||||||
return QString();
|
return QString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Import NodeMetaInfoPrivate::requiredImport() const
|
||||||
|
{
|
||||||
|
if (!isValid())
|
||||||
|
return {};
|
||||||
|
|
||||||
|
const auto *imports = context()->imports(document());
|
||||||
|
ImportInfo importInfo = imports->info(lookupNameComponent().constLast(), context().data());
|
||||||
|
|
||||||
|
if (importInfo.type() == ImportType::Directory) {
|
||||||
|
return Import::createFileImport(importInfo.name(),
|
||||||
|
importInfo.version().toString(),
|
||||||
|
importInfo.as());
|
||||||
|
} else if (importInfo.type() == ImportType::Library) {
|
||||||
|
const QStringList importPaths = model()->importPaths();
|
||||||
|
for (const QString &importPath : importPaths) {
|
||||||
|
const QDir importDir(importPath);
|
||||||
|
const QString targetPathVersion = importDir.filePath(
|
||||||
|
importInfo.path() + '.' + QString::number(importInfo.version().majorVersion()));
|
||||||
|
if (QDir(targetPathVersion).exists()) {
|
||||||
|
return Import::createLibraryImport(importInfo.name(),
|
||||||
|
importInfo.version().toString(),
|
||||||
|
importInfo.as(),
|
||||||
|
{targetPathVersion});
|
||||||
|
}
|
||||||
|
|
||||||
|
const QString targetPath = importDir.filePath(importInfo.path());
|
||||||
|
if (QDir(targetPath).exists()) {
|
||||||
|
return Import::createLibraryImport(importInfo.name(),
|
||||||
|
importInfo.version().toString(),
|
||||||
|
importInfo.as(),
|
||||||
|
{targetPath});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
QString NodeMetaInfoPrivate::lookupName() const
|
QString NodeMetaInfoPrivate::lookupName() const
|
||||||
{
|
{
|
||||||
QString className = QString::fromUtf8(m_qualfiedTypeName);
|
QString className = QString::fromUtf8(m_qualfiedTypeName);
|
||||||
@@ -1747,6 +1785,18 @@ QString NodeMetaInfo::importDirectoryPath() const
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString NodeMetaInfo::requiredImportString() const
|
||||||
|
{
|
||||||
|
if (!isValid())
|
||||||
|
return {};
|
||||||
|
|
||||||
|
Import imp = m_privateData->requiredImport();
|
||||||
|
if (!imp.isEmpty())
|
||||||
|
return imp.toImportString();
|
||||||
|
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
const Storage::Info::Type &NodeMetaInfo::typeData() const
|
const Storage::Info::Type &NodeMetaInfo::typeData() const
|
||||||
{
|
{
|
||||||
if (!m_typeData)
|
if (!m_typeData)
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ static QmlJS::AST::UiObjectDefinition *getObjectDefinition(const QList<QmlJS::AS
|
|||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BaseTextEditModifier::moveToComponent(int nodeOffset)
|
bool BaseTextEditModifier::moveToComponent(int nodeOffset, const QString &importData)
|
||||||
{
|
{
|
||||||
if (m_textEdit) {
|
if (m_textEdit) {
|
||||||
if (auto document = qobject_cast<QmlJSEditor::QmlJSEditorDocument *>(
|
if (auto document = qobject_cast<QmlJSEditor::QmlJSEditorDocument *>(
|
||||||
@@ -115,7 +115,8 @@ bool BaseTextEditModifier::moveToComponent(int nodeOffset)
|
|||||||
QmlJSEditor::performComponentFromObjectDef(qobject_cast<QmlJSEditor::QmlJSEditorWidget *>(
|
QmlJSEditor::performComponentFromObjectDef(qobject_cast<QmlJSEditor::QmlJSEditorWidget *>(
|
||||||
m_textEdit),
|
m_textEdit),
|
||||||
document->filePath().toString(),
|
document->filePath().toString(),
|
||||||
object);
|
object,
|
||||||
|
importData);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,6 +32,7 @@
|
|||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
|
|
||||||
#include <QRegularExpression>
|
#include <QRegularExpression>
|
||||||
|
#include <QSet>
|
||||||
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@@ -1031,11 +1032,25 @@ QSet<QPair<QString, QString> > RewriterView::qrcMapping() const
|
|||||||
|
|
||||||
void RewriterView::moveToComponent(const ModelNode &modelNode)
|
void RewriterView::moveToComponent(const ModelNode &modelNode)
|
||||||
{
|
{
|
||||||
|
if (!modelNode.isValid())
|
||||||
|
return;
|
||||||
|
|
||||||
int offset = nodeOffset(modelNode);
|
int offset = nodeOffset(modelNode);
|
||||||
|
|
||||||
|
const QList<ModelNode> nodes = modelNode.allSubModelNodesAndThisNode();
|
||||||
|
QSet<QString> directPaths;
|
||||||
|
|
||||||
textModifier()->moveToComponent(offset);
|
for (const ModelNode &partialNode : nodes) {
|
||||||
|
QString importStr = partialNode.metaInfo().requiredImportString();
|
||||||
|
if (importStr.size())
|
||||||
|
directPaths << importStr;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString importData = Utils::sorted(directPaths.values()).join(QChar::LineFeed);
|
||||||
|
if (importData.size())
|
||||||
|
importData.append(QString(2, QChar::LineFeed));
|
||||||
|
|
||||||
|
textModifier()->moveToComponent(offset, importData);
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList RewriterView::autoComplete(const QString &text, int pos, bool explicitComplete)
|
QStringList RewriterView::autoComplete(const QString &text, int pos, bool explicitComplete)
|
||||||
|
|||||||
@@ -79,7 +79,8 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void performChanges(QmlJSRefactoringFilePtr currentFile,
|
void performChanges(QmlJSRefactoringFilePtr currentFile,
|
||||||
const QmlJSRefactoringChanges &refactoring) override
|
const QmlJSRefactoringChanges &refactoring,
|
||||||
|
const QString &imports = QString()) override
|
||||||
{
|
{
|
||||||
QString componentName = m_componentName;
|
QString componentName = m_componentName;
|
||||||
|
|
||||||
@@ -128,18 +129,12 @@ public:
|
|||||||
const Utils::FilePath newFileName = path.pathAppended(componentName + QLatin1String(".")
|
const Utils::FilePath newFileName = path.pathAppended(componentName + QLatin1String(".")
|
||||||
+ suffix);
|
+ suffix);
|
||||||
|
|
||||||
QString imports;
|
QString qmlImports = imports.size() ? imports : currentFile->qmlImports();
|
||||||
UiProgram *prog = currentFile->qmljsDocument()->qmlProgram();
|
|
||||||
if (prog && prog->headers) {
|
|
||||||
const unsigned int start = currentFile->startOf(prog->headers->firstSourceLocation());
|
|
||||||
const unsigned int end = currentFile->startOf(prog->members->member->firstSourceLocation());
|
|
||||||
imports = currentFile->textOf(start, end);
|
|
||||||
}
|
|
||||||
|
|
||||||
const unsigned int start = currentFile->startOf(m_firstSourceLocation);
|
const unsigned int start = currentFile->startOf(m_firstSourceLocation);
|
||||||
const unsigned int end = currentFile->startOf(m_lastSourceLocation);
|
const unsigned int end = currentFile->startOf(m_lastSourceLocation);
|
||||||
QString newComponentSource = imports + currentFile->textOf(start, end)
|
QString newComponentSource = qmlImports + currentFile->textOf(start, end)
|
||||||
+ QLatin1String("}\n");
|
+ QLatin1String("}\n");
|
||||||
|
|
||||||
//Remove properties from resulting code...
|
//Remove properties from resulting code...
|
||||||
|
|
||||||
@@ -248,7 +243,8 @@ void matchComponentFromObjectDefQuickFix(const QmlJSQuickFixAssistInterface *int
|
|||||||
|
|
||||||
void performComponentFromObjectDef(QmlJSEditorWidget *editor,
|
void performComponentFromObjectDef(QmlJSEditorWidget *editor,
|
||||||
const QString &fileName,
|
const QString &fileName,
|
||||||
QmlJS::AST::UiObjectDefinition *objDef)
|
QmlJS::AST::UiObjectDefinition *objDef,
|
||||||
|
const QString &importData)
|
||||||
{
|
{
|
||||||
QmlJSRefactoringChanges refactoring(QmlJS::ModelManagerInterface::instance(),
|
QmlJSRefactoringChanges refactoring(QmlJS::ModelManagerInterface::instance(),
|
||||||
QmlJS::ModelManagerInterface::instance()->snapshot());
|
QmlJS::ModelManagerInterface::instance()->snapshot());
|
||||||
@@ -257,7 +253,7 @@ void performComponentFromObjectDef(QmlJSEditorWidget *editor,
|
|||||||
QmlJSQuickFixAssistInterface interface(editor, TextEditor::AssistReason::ExplicitlyInvoked);
|
QmlJSQuickFixAssistInterface interface(editor, TextEditor::AssistReason::ExplicitlyInvoked);
|
||||||
Operation operation(&interface, objDef);
|
Operation operation(&interface, objDef);
|
||||||
|
|
||||||
operation.performChanges(current, refactoring);
|
operation.performChanges(current, refactoring, importData);
|
||||||
}
|
}
|
||||||
|
|
||||||
} //namespace QmlJSEditor
|
} //namespace QmlJSEditor
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ QMLJSEDITOR_EXPORT void matchComponentFromObjectDefQuickFix(
|
|||||||
|
|
||||||
QMLJSEDITOR_EXPORT void performComponentFromObjectDef(QmlJSEditorWidget *editor,
|
QMLJSEDITOR_EXPORT void performComponentFromObjectDef(QmlJSEditorWidget *editor,
|
||||||
const QString &fileName,
|
const QString &fileName,
|
||||||
QmlJS::AST::UiObjectDefinition *objDef);
|
QmlJS::AST::UiObjectDefinition *objDef,
|
||||||
|
const QString &importData);
|
||||||
|
|
||||||
} // namespace QmlJSEditor
|
} // namespace QmlJSEditor
|
||||||
|
|||||||
@@ -40,7 +40,9 @@ protected:
|
|||||||
using Range = Utils::ChangeSet::Range;
|
using Range = Utils::ChangeSet::Range;
|
||||||
|
|
||||||
virtual void performChanges(QmlJSTools::QmlJSRefactoringFilePtr currentFile,
|
virtual void performChanges(QmlJSTools::QmlJSRefactoringFilePtr currentFile,
|
||||||
const QmlJSTools::QmlJSRefactoringChanges &refactoring) = 0;
|
const QmlJSTools::QmlJSRefactoringChanges &refactoring,
|
||||||
|
const QString &imports = QString())
|
||||||
|
= 0;
|
||||||
|
|
||||||
const QmlJSTools::SemanticInfo &semanticInfo() const;
|
const QmlJSTools::SemanticInfo &semanticInfo() const;
|
||||||
|
|
||||||
|
|||||||
@@ -50,7 +50,8 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void performChanges(QmlJSRefactoringFilePtr currentFile,
|
void performChanges(QmlJSRefactoringFilePtr currentFile,
|
||||||
const QmlJSRefactoringChanges &) override
|
const QmlJSRefactoringChanges &,
|
||||||
|
const QString &) override
|
||||||
{
|
{
|
||||||
Q_ASSERT(_objectInitializer);
|
Q_ASSERT(_objectInitializer);
|
||||||
|
|
||||||
@@ -115,7 +116,8 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void performChanges(QmlJSRefactoringFilePtr currentFile,
|
void performChanges(QmlJSRefactoringFilePtr currentFile,
|
||||||
const QmlJSRefactoringChanges &) override
|
const QmlJSRefactoringChanges &,
|
||||||
|
const QString &) override
|
||||||
{
|
{
|
||||||
Utils::ChangeSet changes;
|
Utils::ChangeSet changes;
|
||||||
const int insertLoc = _message.location.begin() - _message.location.startColumn + 1;
|
const int insertLoc = _message.location.begin() - _message.location.startColumn + 1;
|
||||||
|
|||||||
@@ -90,7 +90,8 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void performChanges(QmlJSRefactoringFilePtr currentFile,
|
void performChanges(QmlJSRefactoringFilePtr currentFile,
|
||||||
const QmlJSRefactoringChanges &) override
|
const QmlJSRefactoringChanges &,
|
||||||
|
const QString &) override
|
||||||
{
|
{
|
||||||
UiScriptBinding *idBinding;
|
UiScriptBinding *idBinding;
|
||||||
const QString id = idOfObject(m_objDef, &idBinding);
|
const QString id = idOfObject(m_objDef, &idBinding);
|
||||||
|
|||||||
@@ -136,6 +136,18 @@ Document::Ptr QmlJSRefactoringFile::qmljsDocument() const
|
|||||||
return m_qmljsDocument;
|
return m_qmljsDocument;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString QmlJSRefactoringFile::qmlImports() const
|
||||||
|
{
|
||||||
|
QString imports;
|
||||||
|
QmlJS::AST::UiProgram *prog = qmljsDocument()->qmlProgram();
|
||||||
|
if (prog && prog->headers) {
|
||||||
|
const unsigned int start = startOf(prog->headers->firstSourceLocation());
|
||||||
|
const unsigned int end = startOf(prog->members->member->firstSourceLocation());
|
||||||
|
imports = textOf(start, end);
|
||||||
|
}
|
||||||
|
return imports;
|
||||||
|
}
|
||||||
|
|
||||||
unsigned QmlJSRefactoringFile::startOf(const SourceLocation &loc) const
|
unsigned QmlJSRefactoringFile::startOf(const SourceLocation &loc) const
|
||||||
{
|
{
|
||||||
return position(loc.startLine, loc.startColumn);
|
return position(loc.startLine, loc.startColumn);
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ class QMLJSTOOLS_EXPORT QmlJSRefactoringFile: public TextEditor::RefactoringFile
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
QmlJS::Document::Ptr qmljsDocument() const;
|
QmlJS::Document::Ptr qmljsDocument() const;
|
||||||
|
QString qmlImports() const;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Returns the offset in the document for the start position of the given
|
Returns the offset in the document for the start position of the given
|
||||||
|
|||||||
Reference in New Issue
Block a user