QmlDesigner: Reload file if type information is incomplete

Unfortuatly we require this. The code model might be still parsing imports
which will lead to an error. Reacting to ModelManagerInterface::libraryInfoUpdated
and then reloading the document does fix this.
This issue has high visibility.
In case the puppet debug mode is enabled we ignore this.

Task-number: QDS-3113
Task-number: QDS-1592
Change-Id: I6cbf9d01d1702f61c6bbbb86dca546174fecc825
Reviewed-by: Tim Jenssen <tim.jenssen@qt.io>
This commit is contained in:
Thomas Hartmann
2020-12-09 15:00:24 +01:00
parent a45689f85c
commit fdf6cd7899
2 changed files with 33 additions and 2 deletions

View File

@@ -190,6 +190,7 @@ protected: // functions
private: //variables private: //variables
ModelNode nodeAtTextCursorPositionHelper(const ModelNode &root, int cursorPosition) const; ModelNode nodeAtTextCursorPositionHelper(const ModelNode &root, int cursorPosition) const;
void setupCanonicalHashes() const; void setupCanonicalHashes() const;
void handleLibraryInfoUpdate();
TextModifier *m_textModifier = nullptr; TextModifier *m_textModifier = nullptr;
int transactionLevel = 0; int transactionLevel = 0;
@@ -210,6 +211,7 @@ private: //variables
std::function<void(bool)> m_setWidgetStatusCallback; std::function<void(bool)> m_setWidgetStatusCallback;
bool m_hasIncompleteTypeInformation = false; bool m_hasIncompleteTypeInformation = false;
bool m_restoringAuxData = false; bool m_restoringAuxData = false;
bool m_modelAttachPending = false;
mutable QHash<int, ModelNode> m_canonicalIntModelNode; mutable QHash<int, ModelNode> m_canonicalIntModelNode;
mutable QHash<ModelNode, int> m_canonicalModelNodeInt; mutable QHash<ModelNode, int> m_canonicalModelNodeInt;

View File

@@ -64,6 +64,19 @@ namespace QmlDesigner {
const char annotationsEscapeSequence[] = "##^##"; const char annotationsEscapeSequence[] = "##^##";
bool debugQmlPuppet()
{
#ifndef QMLDESIGNER_TEST
if (!QmlDesignerPlugin::instance())
return false;
const QString debugPuppet = QmlDesignerPlugin::instance()->settings().value(DesignerSettingsKey::
DEBUG_PUPPET).toString();
return !debugPuppet.isEmpty();
#else
return false;
#endif
}
RewriterView::RewriterView(DifferenceHandling differenceHandling, QObject *parent): RewriterView::RewriterView(DifferenceHandling differenceHandling, QObject *parent):
AbstractView(parent), AbstractView(parent),
m_differenceHandling(differenceHandling), m_differenceHandling(differenceHandling),
@@ -72,7 +85,12 @@ RewriterView::RewriterView(DifferenceHandling differenceHandling, QObject *paren
m_textToModelMerger(new Internal::TextToModelMerger(this)) m_textToModelMerger(new Internal::TextToModelMerger(this))
{ {
m_amendTimer.setSingleShot(true); m_amendTimer.setSingleShot(true);
m_amendTimer.setInterval(400);
connect(&m_amendTimer, &QTimer::timeout, this, &RewriterView::amendQmlText); connect(&m_amendTimer, &QTimer::timeout, this, &RewriterView::amendQmlText);
QmlJS::ModelManagerInterface *modelManager = QmlJS::ModelManagerInterface::instance();
connect(modelManager, &QmlJS::ModelManagerInterface::libraryInfoUpdated,
this, &RewriterView::handleLibraryInfoUpdate, Qt::QueuedConnection);
} }
RewriterView::~RewriterView() = default; RewriterView::~RewriterView() = default;
@@ -89,6 +107,8 @@ Internal::TextToModelMerger *RewriterView::textToModelMerger() const
void RewriterView::modelAttached(Model *model) void RewriterView::modelAttached(Model *model)
{ {
m_modelAttachPending = false;
if (model && model->textModifier()) if (model && model->textModifier())
setTextModifier(model->textModifier()); setTextModifier(model->textModifier());
@@ -102,10 +122,12 @@ void RewriterView::modelAttached(Model *model)
if (!(m_errors.isEmpty() && m_warnings.isEmpty())) if (!(m_errors.isEmpty() && m_warnings.isEmpty()))
notifyErrorsAndWarnings(m_errors); notifyErrorsAndWarnings(m_errors);
if (hasIncompleteTypeInformation()) if (hasIncompleteTypeInformation()) {
m_modelAttachPending = true;
QTimer::singleShot(1000, this, [this, model](){ QTimer::singleShot(1000, this, [this, model](){
modelAttached(model); modelAttached(model);
}); });
}
} }
void RewriterView::modelAboutToBeDetached(Model * /*model*/) void RewriterView::modelAboutToBeDetached(Model * /*model*/)
@@ -803,6 +825,13 @@ void RewriterView::setupCanonicalHashes() const
} }
} }
void RewriterView::handleLibraryInfoUpdate()
{
// Trigger dummy amend to reload document when library info changes
if (isAttached() && !m_modelAttachPending && !debugQmlPuppet())
m_amendTimer.start();
}
ModelNode RewriterView::nodeAtTextCursorPosition(int cursorPosition) const ModelNode RewriterView::nodeAtTextCursorPosition(int cursorPosition) const
{ {
return nodeAtTextCursorPositionHelper(rootModelNode(), cursorPosition); return nodeAtTextCursorPositionHelper(rootModelNode(), cursorPosition);
@@ -1005,7 +1034,7 @@ void RewriterView::qmlTextChanged()
auto &viewManager = QmlDesignerPlugin::instance()->viewManager(); auto &viewManager = QmlDesignerPlugin::instance()->viewManager();
if (viewManager.usesRewriterView(this)) { if (viewManager.usesRewriterView(this)) {
QmlDesignerPlugin::instance()->viewManager().disableWidgets(); QmlDesignerPlugin::instance()->viewManager().disableWidgets();
m_amendTimer.start(400); m_amendTimer.start();
} }
#else #else
/*Keep test synchronous*/ /*Keep test synchronous*/