qmlls: Make LanguageClientManager manage qmlls

Remove the custom unfit qmlls-managing functionality from
QmlJSEditorDocumentPrivate and use the LanguageClient implementation
instead.

Move the settings page from Qt Quick to the Language Server settings
page to have all language servers in one central point.

Introduce new class for QmllsClientSettings and
QmllsClientSettingsWidget that allows the LanguageClient code to manage
the qmlls state (starting, restarting, shutdown etc) and to configure
qmlls from the Language Server settings page.

Split qmlls specific functionality away from QmlJSEditingSettings into
QmllsClientSettings and squash QmllsSettingsManager into
QmllsClientSettings as its not needed anymore.

Remove QmlJSEditorDocumentPrivate::settingsChanged() because thats
almost completely handled by the LanguageClient generic implementation.
The missing bits (enabling/disabling of the builtin code model) will be
re-added in a future commit, tracked by QTCREATORBUG-32025.

Currently the ProjectSettings::save() does not do anything, such that
the project specific settings under Qt Quick does not do anything anymore
(before the checkbox there allowed to disable/enable qmlls
project-wise), tracked by QTCREATORBUG-32026.

Task-number: QTCREATORBUG-31897
Change-Id: I62d807e478ab105e67ec7d94af6782810e6bd2ed
Reviewed-by: David Schulz <david.schulz@qt.io>
This commit is contained in:
Sami Shalayel
2024-11-14 16:06:40 +01:00
parent 8cc973371d
commit a737828d7d
14 changed files with 409 additions and 339 deletions

View File

@@ -4,6 +4,7 @@ add_qtc_plugin(QmlJSEditor
SOURCES SOURCES
qmlexpressionundercursor.cpp qmlexpressionundercursor.h qmlexpressionundercursor.cpp qmlexpressionundercursor.h
qmllsclient.h qmllsclient.cpp qmllsclient.h qmllsclient.cpp
qmllsclientsettings.h qmllsclientsettings.cpp
qmljsautocompleter.cpp qmljsautocompleter.h qmljsautocompleter.cpp qmljsautocompleter.h
qmljscompletionassist.cpp qmljscompletionassist.h qmljscompletionassist.cpp qmljscompletionassist.h
qmljscomponentfromobjectdef.cpp qmljscomponentfromobjectdef.h qmljscomponentfromobjectdef.cpp qmljscomponentfromobjectdef.h

View File

@@ -5,15 +5,16 @@
#include "qmljsautocompleter.h" #include "qmljsautocompleter.h"
#include "qmljscompletionassist.h" #include "qmljscompletionassist.h"
#include "qmljseditorsettings.h"
#include "qmljseditorconstants.h" #include "qmljseditorconstants.h"
#include "qmljseditordocument.h" #include "qmljseditordocument.h"
#include "qmljseditorplugin.h" #include "qmljseditorplugin.h"
#include "qmljseditorsettings.h"
#include "qmljseditortr.h" #include "qmljseditortr.h"
#include "qmljsfindreferences.h" #include "qmljsfindreferences.h"
#include "qmljshighlighter.h" #include "qmljshighlighter.h"
#include "qmljshoverhandler.h" #include "qmljshoverhandler.h"
#include "qmljsquickfixassist.h" #include "qmljsquickfixassist.h"
#include "qmllsclientsettings.h"
#include "qmloutlinemodel.h" #include "qmloutlinemodel.h"
#include "quicktoolbar.h" #include "quicktoolbar.h"
@@ -98,15 +99,13 @@ namespace QmlJSEditor {
static LanguageClient::Client *getQmllsClient(const Utils::FilePath &fileName) static LanguageClient::Client *getQmllsClient(const Utils::FilePath &fileName)
{ {
// the value in disableBuiltinCodemodel is only valid when useQmlls is enabled if (qmllsSettings()->useQmllsWithBuiltinCodemodelOnProject(fileName))
if (settings().useQmlls() && !settings().disableBuiltinCodemodel())
return nullptr; return nullptr;
auto client = LanguageClient::LanguageClientManager::clientForFilePath(fileName); auto client = LanguageClient::LanguageClientManager::clientForFilePath(fileName);
return client; return client;
} }
// //
// QmlJSEditorWidget // QmlJSEditorWidget
// //

View File

@@ -25,5 +25,7 @@ const char QML_SNIPPETS_GROUP_ID[] = "QML";
const char QMLLINT_BUILD_TARGET[] = "all_qmllint"; const char QMLLINT_BUILD_TARGET[] = "all_qmllint";
const char QMLLS_CLIENT_SETTINGS_ID[] = "LanguageClient::QmllsClientSettingsID";
} // namespace Constants } // namespace Constants
} // namespace QmlJSEditor } // namespace QmlJSEditor

View File

@@ -6,13 +6,12 @@
#include "qmljseditordocument_p.h" #include "qmljseditordocument_p.h"
#include "qmljseditorplugin.h" #include "qmljseditorplugin.h"
#include "qmljseditortr.h" #include "qmljseditortr.h"
#include "qmljseditorsettings.h"
#include "qmljshighlighter.h" #include "qmljshighlighter.h"
#include "qmljsquickfixassist.h" #include "qmljsquickfixassist.h"
#include "qmljssemantichighlighter.h" #include "qmljssemantichighlighter.h"
#include "qmljssemanticinfoupdater.h" #include "qmljssemanticinfoupdater.h"
#include "qmljstextmark.h" #include "qmljstextmark.h"
#include "qmllsclient.h" #include "qmllsclientsettings.h"
#include "qmloutlinemodel.h" #include "qmloutlinemodel.h"
#include <coreplugin/coreconstants.h> #include <coreplugin/coreconstants.h>
@@ -43,8 +42,6 @@ using namespace Utils;
namespace { namespace {
Q_LOGGING_CATEGORY(qmllsLog, "qtc.qmlls.editor", QtWarningMsg);
enum { enum {
UPDATE_DOCUMENT_DEFAULT_INTERVAL = 100, UPDATE_DOCUMENT_DEFAULT_INTERVAL = 100,
UPDATE_OUTLINE_INTERVAL = 500 UPDATE_OUTLINE_INTERVAL = 500
@@ -480,13 +477,6 @@ QmlJSEditorDocumentPrivate::QmlJSEditorDocumentPrivate(QmlJSEditorDocument *pare
this, &QmlJSEditorDocumentPrivate::reparseDocument); this, &QmlJSEditorDocumentPrivate::reparseDocument);
connect(modelManager, &ModelManagerInterface::documentUpdated, connect(modelManager, &ModelManagerInterface::documentUpdated,
this, &QmlJSEditorDocumentPrivate::onDocumentUpdated); this, &QmlJSEditorDocumentPrivate::onDocumentUpdated);
connect(QmllsSettingsManager::instance(), &QmllsSettingsManager::settingsChanged,
this, &QmlJSEditorDocumentPrivate::settingsChanged);
connect(
modelManager,
&ModelManagerInterface::projectInfoUpdated,
this,
&QmlJSEditorDocumentPrivate::settingsChanged);
// semantic info // semantic info
m_semanticInfoUpdater = new SemanticInfoUpdater(); m_semanticInfoUpdater = new SemanticInfoUpdater();
@@ -734,104 +724,12 @@ void QmlJSEditorDocumentPrivate::setSourcesWithCapabilities(
setSemanticWarningSource(QmllsStatus::Source::Qmlls); setSemanticWarningSource(QmllsStatus::Source::Qmlls);
else else
setSemanticWarningSource(QmllsStatus::Source::EmbeddedCodeModel); setSemanticWarningSource(QmllsStatus::Source::EmbeddedCodeModel);
if (cap.semanticTokensProvider() && settings().enableQmllsSemanticHighlighting()) if (cap.semanticTokensProvider() && qmllsSettings()->m_useQmllsSemanticHighlighting)
setSemanticHighlightSource(QmllsStatus::Source::Qmlls); setSemanticHighlightSource(QmllsStatus::Source::Qmlls);
else else
setSemanticHighlightSource(QmllsStatus::Source::EmbeddedCodeModel); setSemanticHighlightSource(QmllsStatus::Source::EmbeddedCodeModel);
} }
static FilePath qmllsForFile(const FilePath &file, QmlJS::ModelManagerInterface *modelManager)
{
QmllsSettingsManager *settingsManager = QmllsSettingsManager::instance();
ProjectExplorer::Project *project = ProjectExplorer::ProjectManager::projectForFile(file);
const bool enabled = settingsManager->useQmlls(project);
if (!enabled)
return {};
if (settingsManager->useLatestQmlls())
return settingsManager->latestQmlls();
QmlJS::ModelManagerInterface::ProjectInfo pInfo = modelManager->projectInfoForPath(file);
if (!settings().ignoreMinimumQmllsVersion()
&& QVersionNumber::fromString(pInfo.qtVersionString)
< QmlJsEditingSettings::mininumQmllsVersion) {
return {};
}
return pInfo.qmllsPath.exists() ? pInfo.qmllsPath : Utils::FilePath();
}
void QmlJSEditorDocumentPrivate::settingsChanged()
{
if (q->isTemporary())
return;
FilePath newQmlls = qmllsForFile(q->filePath(), ModelManagerInterface::instance());
if (m_qmllsStatus.qmllsPath == newQmlls) {
if (QmllsClient *client = QmllsClient::clientForQmlls(newQmlls)) {
client->updateQmllsSemanticHighlightingCapability();
setSourcesWithCapabilities(client->capabilities());
client->activateDocument(q);
}
return;
}
using namespace LanguageClient;
m_qmllsStatus.qmllsPath = newQmlls;
if (newQmlls.isEmpty()) {
qCDebug(qmllsLog) << "disabling qmlls for" << q->filePath();
if (LanguageClientManager::clientForDocument(q) != nullptr) {
qCDebug(qmllsLog) << "deactivating " << q->filePath() << "in qmlls" << newQmlls;
LanguageClientManager::openDocumentWithClient(q, nullptr);
} else
qCWarning(qmllsLog) << "Could not find client to disable for document " << q->filePath()
<< " in LanguageClient::LanguageClientManager";
setCompletionSource(QmllsStatus::Source::EmbeddedCodeModel);
setSemanticWarningSource(QmllsStatus::Source::EmbeddedCodeModel);
setSemanticHighlightSource(QmllsStatus::Source::EmbeddedCodeModel);
} else if (QmllsClient *client = QmllsClient::clientForQmlls(newQmlls)) {
bool shouldActivate = false;
if (auto oldClient = LanguageClientManager::clientForDocument(q)) {
// check if it was disabled
if (client == oldClient)
shouldActivate = true;
}
client->updateQmllsSemanticHighlightingCapability();
switch (client->state()) {
case Client::State::Uninitialized:
case Client::State::InitializeRequested:
connect(client,
&Client::initialized,
this,
&QmlJSEditorDocumentPrivate::setSourcesWithCapabilities);
break;
case Client::State::Initialized:
setSourcesWithCapabilities(client->capabilities());
break;
case Client::State::FailedToInitialize:
case Client::State::Error:
qCWarning(qmllsLog) << "qmlls" << newQmlls << "requested for document" << q->filePath()
<< "had errors, skipping setSourcesWithCababilities";
break;
case Client::State::Shutdown:
qCWarning(qmllsLog) << "qmlls" << newQmlls << "requested for document" << q->filePath()
<< "did stop, skipping setSourcesWithCababilities";
break;
case Client::State::ShutdownRequested:
qCWarning(qmllsLog) << "qmlls" << newQmlls << "requested for document" << q->filePath()
<< "is stopping, skipping setSourcesWithCababilities";
break;
}
if (shouldActivate) {
qCDebug(qmllsLog) << "reactivating " << q->filePath() << "in qmlls" << newQmlls;
client->activateDocument(q);
} else {
qCDebug(qmllsLog) << "opening " << q->filePath() << "in qmlls" << newQmlls;
LanguageClientManager::openDocumentWithClient(q, client);
}
} else {
qCWarning(qmllsLog) << "could not start qmlls " << newQmlls << "for" << q->filePath();
}
}
} // Internal } // Internal
QmlJSEditorDocument::QmlJSEditorDocument(Utils::Id id) QmlJSEditorDocument::QmlJSEditorDocument(Utils::Id id)
@@ -840,8 +738,6 @@ QmlJSEditorDocument::QmlJSEditorDocument(Utils::Id id)
setId(id); setId(id);
connect(this, &TextEditor::TextDocument::tabSettingsChanged, connect(this, &TextEditor::TextDocument::tabSettingsChanged,
d, &Internal::QmlJSEditorDocumentPrivate::invalidateFormatterCache); d, &Internal::QmlJSEditorDocumentPrivate::invalidateFormatterCache);
connect(this, &TextEditor::TextDocument::openFinishedSuccessfully,
d, &Internal::QmlJSEditorDocumentPrivate::settingsChanged);
resetSyntaxHighlighter([] { return new QmlJSHighlighter(); }); resetSyntaxHighlighter([] { return new QmlJSHighlighter(); });
setCodec(QTextCodec::codecForName("UTF-8")); // qml files are defined to be utf-8 setCodec(QTextCodec::codecForName("UTF-8")); // qml files are defined to be utf-8
setIndenter(createQmlJsIndenter(document())); setIndenter(createQmlJsIndenter(document()));

View File

@@ -62,7 +62,6 @@ public:
void setCompletionSource(QmllsStatus::Source newSource); void setCompletionSource(QmllsStatus::Source newSource);
public slots: public slots:
void setSourcesWithCapabilities(const LanguageServerProtocol::ServerCapabilities &); void setSourcesWithCapabilities(const LanguageServerProtocol::ServerCapabilities &);
void settingsChanged();
public: public:
QmlJSEditorDocument *q = nullptr; QmlJSEditorDocument *q = nullptr;

View File

@@ -9,6 +9,7 @@
#include "qmljseditortr.h" #include "qmljseditortr.h"
#include "qmljsoutline.h" #include "qmljsoutline.h"
#include "qmljsquickfixassist.h" #include "qmljsquickfixassist.h"
#include "qmllsclientsettings.h"
#include "qmltaskmanager.h" #include "qmltaskmanager.h"
#include <qmljs/jsoncheck.h> #include <qmljs/jsoncheck.h>
@@ -89,7 +90,7 @@ static QmlJSEditorPluginPrivate *dd = nullptr;
QmlJSEditorPluginPrivate::QmlJSEditorPluginPrivate() QmlJSEditorPluginPrivate::QmlJSEditorPluginPrivate()
{ {
QmlJS::ModelManagerInterface *modelManager = QmlJS::ModelManagerInterface::instance(); QmlJS::ModelManagerInterface *modelManager = QmlJS::ModelManagerInterface::instance();
QmllsSettingsManager::instance(); setupQmllsClientSettings();
// QML task updating manager // QML task updating manager
connect(modelManager, &QmlJS::ModelManagerInterface::documentChangedOnDisk, connect(modelManager, &QmlJS::ModelManagerInterface::documentChangedOnDisk,
@@ -346,7 +347,6 @@ class QmlJSEditorPlugin final : public ExtensionSystem::IPlugin
Tr::tr("QML Analysis"), Tr::tr("QML Analysis"),
Tr::tr("Issues that the QML static analyzer found."), Tr::tr("Issues that the QML static analyzer found."),
false}); false});
QmllsSettingsManager::instance()->setupAutoupdate();
} }
}; };

View File

@@ -4,10 +4,17 @@
#include "qmljseditorsettings.h" #include "qmljseditorsettings.h"
#include "qmljseditorconstants.h" #include "qmljseditorconstants.h"
#include "qmljseditortr.h" #include "qmljseditortr.h"
#include "qmllsclient.h"
#include "qmllsclientsettings.h"
#include <coreplugin/coreconstants.h> #include <coreplugin/coreconstants.h>
#include <coreplugin/icore.h> #include <coreplugin/icore.h>
#include <languageclient/languageclientinterface.h>
#include <languageclient/languageclientmanager.h>
#include <languageclient/languageclientsettings.h>
#include <projectexplorer/projectmanager.h>
#include <projectexplorer/projectpanelfactory.h> #include <projectexplorer/projectpanelfactory.h>
#include <projectexplorer/projectsettingswidget.h> #include <projectexplorer/projectsettingswidget.h>
#include <projectexplorer/projecttree.h> #include <projectexplorer/projecttree.h>
@@ -49,8 +56,6 @@ using namespace ProjectExplorer;
namespace QmlJSEditor::Internal { namespace QmlJSEditor::Internal {
static Q_LOGGING_CATEGORY(qmllsLog, "qtc.qmlls.settings", QtWarningMsg)
const char SETTINGS_KEY_MAIN[] = "QmlJSEditor"; const char SETTINGS_KEY_MAIN[] = "QmlJSEditor";
const char AUTO_FORMAT_ON_SAVE[] = "QmlJSEditor.AutoFormatOnSave"; const char AUTO_FORMAT_ON_SAVE[] = "QmlJSEditor.AutoFormatOnSave";
const char AUTO_FORMAT_ONLY_CURRENT_PROJECT[] = "QmlJSEditor.AutoFormatOnlyCurrentProject"; const char AUTO_FORMAT_ONLY_CURRENT_PROJECT[] = "QmlJSEditor.AutoFormatOnlyCurrentProject";
@@ -59,11 +64,6 @@ const char QML_CONTEXTPANEPIN_KEY[] = "QmlJSEditor.ContextPanePinned";
const char FOLD_AUX_DATA[] = "QmlJSEditor.FoldAuxData"; const char FOLD_AUX_DATA[] = "QmlJSEditor.FoldAuxData";
const char USE_GLOBAL_SETTINGS[] = "QmlJSEditor.UseGlobalSettings"; const char USE_GLOBAL_SETTINGS[] = "QmlJSEditor.UseGlobalSettings";
const char USE_QMLLS[] = "QmlJSEditor.UseQmlls"; const char USE_QMLLS[] = "QmlJSEditor.UseQmlls";
const char USE_LATEST_QMLLS[] = "QmlJSEditor.UseLatestQmlls";
const char IGNORE_MINIMUM_QMLLS_VERSION[] = "QmlJSEditor.IgnoreMinimumQmllsVersion";
const char USE_QMLLS_SEMANTIC_HIGHLIGHTING[] = "QmlJSEditor.EnableQmllsSemanticHighlighting";
const char DISABLE_BUILTIN_CODEMODEL[] = "QmlJSEditor.DisableBuiltinCodemodel";
const char GENERATE_QMLLS_INI_FILES[] = "QmlJSEditor.GenerateQmllsIniFiles";
const char UIQML_OPEN_MODE[] = "QmlJSEditor.openUiQmlMode"; const char UIQML_OPEN_MODE[] = "QmlJSEditor.openUiQmlMode";
const char FORMAT_COMMAND[] = "QmlJSEditor.formatCommand"; const char FORMAT_COMMAND[] = "QmlJSEditor.formatCommand";
const char FORMAT_COMMAND_OPTIONS[] = "QmlJSEditor.formatCommandOptions"; const char FORMAT_COMMAND_OPTIONS[] = "QmlJSEditor.formatCommandOptions";
@@ -81,110 +81,7 @@ QmlJsEditingSettings &settings()
return settings; return settings;
} }
static FilePath evaluateLatestQmlls() using namespace LanguageClient;
{
// find latest qmlls, i.e. vals
if (!QtVersionManager::isLoaded())
return {};
const QtVersions versions = QtVersionManager::versions();
FilePath latestQmlls;
QVersionNumber latestVersion;
FilePath latestQmakeFilePath;
int latestUniqueId = std::numeric_limits<int>::min();
for (QtVersion *v : versions) {
// check if we find qmlls
QVersionNumber vNow = v->qtVersion();
FilePath qmllsNow = QmlJS::ModelManagerInterface::qmllsForBinPath(v->hostBinPath(), vNow);
if (!qmllsNow.isExecutableFile())
continue;
if (latestVersion > vNow)
continue;
FilePath qmakeNow = v->qmakeFilePath();
int uniqueIdNow = v->uniqueId();
if (latestVersion == vNow) {
if (latestQmakeFilePath > qmakeNow)
continue;
if (latestQmakeFilePath == qmakeNow && latestUniqueId >= v->uniqueId())
continue;
}
latestVersion = vNow;
latestQmlls = qmllsNow;
latestQmakeFilePath = qmakeNow;
latestUniqueId = uniqueIdNow;
}
return latestQmlls;
}
QmllsSettingsManager *QmllsSettingsManager::instance()
{
static QmllsSettingsManager *manager = new QmllsSettingsManager;
return manager;
}
FilePath QmllsSettingsManager::latestQmlls()
{
QMutexLocker l(&m_mutex);
return m_latestQmlls;
}
void QmllsSettingsManager::setupAutoupdate()
{
QObject::connect(QtVersionManager::instance(),
&QtVersionManager::qtVersionsChanged,
this,
&QmllsSettingsManager::checkForChanges);
if (QtVersionManager::isLoaded())
checkForChanges();
else
QObject::connect(QtVersionManager::instance(),
&QtVersionManager::qtVersionsLoaded,
this,
&QmllsSettingsManager::checkForChanges);
}
void QmllsSettingsManager::checkForChanges()
{
const QmlJsEditingSettings &newSettings = settings();
FilePath newLatest = newSettings.useLatestQmlls() && newSettings.useQmlls()
? evaluateLatestQmlls() : m_latestQmlls;
if (m_useQmlls == newSettings.useQmlls()
&& m_useLatestQmlls == newSettings.useLatestQmlls()
&& m_disableBuiltinCodemodel == newSettings.disableBuiltinCodemodel()
&& m_generateQmllsIniFiles == newSettings.generateQmllsIniFiles()
&& m_enableQmllsSemanticHighlighting == newSettings.enableQmllsSemanticHighlighting()
&& newLatest == m_latestQmlls)
return;
qCDebug(qmllsLog) << "qmlls settings changed:" << newSettings.useQmlls()
<< newSettings.useLatestQmlls() << newLatest;
{
QMutexLocker l(&m_mutex);
m_latestQmlls = newLatest;
m_useQmlls = newSettings.useQmlls();
m_useLatestQmlls = newSettings.useLatestQmlls();
m_disableBuiltinCodemodel = newSettings.disableBuiltinCodemodel();
m_enableQmllsSemanticHighlighting = newSettings.enableQmllsSemanticHighlighting();
m_generateQmllsIniFiles = newSettings.generateQmllsIniFiles();
}
emit settingsChanged();
}
bool QmllsSettingsManager::useLatestQmlls() const
{
return m_useLatestQmlls;
}
bool QmllsSettingsManager::useQmlls(Project* onProject) const
{
if (!onProject)
return m_useQmlls;
// check if disabled via project specific settings
ProjectSettings projectSettings{onProject};
const bool result = projectSettings.useGlobalSettings() ? m_useQmlls
: projectSettings.useQmlls();
return result;
}
static QList<int> defaultDisabledMessages() static QList<int> defaultDisabledMessages()
{ {
@@ -220,10 +117,6 @@ QmlJsEditingSettings::QmlJsEditingSettings()
{ {
const Key group = QmlJSEditor::Constants::SETTINGS_CATEGORY_QML; const Key group = QmlJSEditor::Constants::SETTINGS_CATEGORY_QML;
useQmlls.setSettingsKey(group, USE_QMLLS);
useQmlls.setDefaultValue(true);
useQmlls.setLabelText(Tr::tr("Turn on"));
enableContextPane.setSettingsKey(group, QML_CONTEXTPANE_KEY); enableContextPane.setSettingsKey(group, QML_CONTEXTPANE_KEY);
enableContextPane.setLabelText(Tr::tr("Always show Qt Quick Toolbar")); enableContextPane.setLabelText(Tr::tr("Always show Qt Quick Toolbar"));
@@ -249,27 +142,6 @@ QmlJsEditingSettings::QmlJsEditingSettings()
uiQmlOpenMode.addOption({Tr::tr("Qt Design Studio"), {}, Core::Constants::MODE_DESIGN}); uiQmlOpenMode.addOption({Tr::tr("Qt Design Studio"), {}, Core::Constants::MODE_DESIGN});
uiQmlOpenMode.addOption({Tr::tr("Qt Creator"), {}, Core::Constants::MODE_EDIT}); uiQmlOpenMode.addOption({Tr::tr("Qt Creator"), {}, Core::Constants::MODE_EDIT});
useLatestQmlls.setSettingsKey(group, USE_LATEST_QMLLS);
useLatestQmlls.setLabelText(Tr::tr("Use from latest Qt version"));
disableBuiltinCodemodel.setSettingsKey(group, DISABLE_BUILTIN_CODEMODEL);
disableBuiltinCodemodel.setLabelText(
Tr::tr("Use advanced features (renaming, find usages, and so on) "
"(experimental)"));
generateQmllsIniFiles.setSettingsKey(group, GENERATE_QMLLS_INI_FILES);
generateQmllsIniFiles.setLabelText(
Tr::tr("Create .qmlls.ini files for new projects"));
ignoreMinimumQmllsVersion.setSettingsKey(group, IGNORE_MINIMUM_QMLLS_VERSION);
ignoreMinimumQmllsVersion.setLabelText(
Tr::tr("Allow versions below Qt %1")
.arg(QmlJsEditingSettings::mininumQmllsVersion.toString()));
enableQmllsSemanticHighlighting.setSettingsKey(group, USE_QMLLS_SEMANTIC_HIGHLIGHTING);
enableQmllsSemanticHighlighting.setLabelText(
Tr::tr("Enable semantic highlighting (experimental)"));
useCustomFormatCommand.setSettingsKey(group, CUSTOM_COMMAND); useCustomFormatCommand.setSettingsKey(group, CUSTOM_COMMAND);
useCustomFormatCommand.setLabelText( useCustomFormatCommand.setLabelText(
Tr::tr("Use custom command instead of built-in formatter")); Tr::tr("Use custom command instead of built-in formatter"));
@@ -299,11 +171,6 @@ QmlJsEditingSettings::QmlJsEditingSettings()
readSettings(); readSettings();
autoFormatOnlyCurrentProject.setEnabler(&autoFormatOnSave); autoFormatOnlyCurrentProject.setEnabler(&autoFormatOnSave);
useLatestQmlls.setEnabler(&useQmlls);
disableBuiltinCodemodel.setEnabler(&useQmlls);
generateQmllsIniFiles.setEnabler(&useQmlls);
ignoreMinimumQmllsVersion.setEnabler(&useQmlls);
enableQmllsSemanticHighlighting.setEnabler(&useQmlls);
formatCommand.setEnabler(&useCustomFormatCommand); formatCommand.setEnabler(&useCustomFormatCommand);
formatCommandOptions.setEnabler(&useCustomFormatCommand); formatCommandOptions.setEnabler(&useCustomFormatCommand);
} }
@@ -426,14 +293,7 @@ public:
}, },
Group{ Group{
title(Tr::tr("QML Language Server")), title(Tr::tr("QML Language Server")),
Column { // TODO: link to new settings
s.useQmlls,
s.ignoreMinimumQmllsVersion,
s.disableBuiltinCodemodel,
s.enableQmllsSemanticHighlighting,
s.useLatestQmlls,
s.generateQmllsIniFiles
},
}, },
Group { Group {
title(Tr::tr("Static Analyzer")), title(Tr::tr("Static Analyzer")),
@@ -469,7 +329,6 @@ public:
s.disabledMessages.setValue(disabled); s.disabledMessages.setValue(disabled);
s.disabledMessagesForNonQuickUi.setValue(disabledForNonQuickUi); s.disabledMessagesForNonQuickUi.setValue(disabledForNonQuickUi);
s.writeSettings(); s.writeSettings();
QmllsSettingsManager::instance()->checkForChanges();
} }
private: private:
@@ -544,7 +403,11 @@ void ProjectSettings::save(Project *project)
toMap(map); toMap(map);
project->setNamedSettings(SETTINGS_KEY_MAIN, variantFromStore(map)); project->setNamedSettings(SETTINGS_KEY_MAIN, variantFromStore(map));
emit QmllsSettingsManager::instance()->settingsChanged(); // TODO: this does not do anything for now. Either force re-apply when the functionality
// is available in LanguageClient (tracked in QTCREATORBUG-32015) or remove ProjectSettings
// class completely in favor of the LanguageClient project specific settings implementation
// (tracked in QTCREATORBUG-31987).
LanguageClientManager::applySettings();
} }
class QmlJsEditingProjectSettingsWidget final : public ProjectSettingsWidget class QmlJsEditingProjectSettingsWidget final : public ProjectSettingsWidget

View File

@@ -18,8 +18,6 @@ namespace QmlJSEditor::Internal {
class QmlJsEditingSettings final : public Utils::AspectContainer class QmlJsEditingSettings final : public Utils::AspectContainer
{ {
public: public:
static const inline QVersionNumber mininumQmllsVersion = QVersionNumber(6, 8);
QmlJsEditingSettings(); QmlJsEditingSettings();
QString defaultFormatCommand() const; QString defaultFormatCommand() const;
@@ -31,12 +29,6 @@ public:
Utils::BoolAspect foldAuxData{this}; Utils::BoolAspect foldAuxData{this};
Utils::BoolAspect useCustomFormatCommand{this}; Utils::BoolAspect useCustomFormatCommand{this};
Utils::BoolAspect useCustomAnalyzer{this}; Utils::BoolAspect useCustomAnalyzer{this};
Utils::BoolAspect useQmlls{this};
Utils::BoolAspect useLatestQmlls{this};
Utils::BoolAspect ignoreMinimumQmllsVersion{this};
Utils::BoolAspect enableQmllsSemanticHighlighting{this};
Utils::BoolAspect disableBuiltinCodemodel{this};
Utils::BoolAspect generateQmllsIniFiles{this};
Utils::SelectionAspect uiQmlOpenMode{this}; Utils::SelectionAspect uiQmlOpenMode{this};
Utils::StringAspect formatCommand{this}; Utils::StringAspect formatCommand{this};
Utils::StringAspect formatCommandOptions{this}; Utils::StringAspect formatCommandOptions{this};
@@ -44,34 +36,6 @@ public:
Utils::IntegersAspect disabledMessagesForNonQuickUi{this}; Utils::IntegersAspect disabledMessagesForNonQuickUi{this};
}; };
class QmllsSettingsManager : public QObject
{
Q_OBJECT
public:
static QmllsSettingsManager *instance();
Utils::FilePath latestQmlls();
void setupAutoupdate();
bool useQmlls(ProjectExplorer::Project* project) const;
bool useLatestQmlls() const;
public slots:
void checkForChanges();
signals:
void settingsChanged();
private:
QMutex m_mutex;
bool m_useQmlls = true;
bool m_useLatestQmlls = false;
bool m_disableBuiltinCodemodel = false;
bool m_generateQmllsIniFiles = false;
bool m_enableQmllsSemanticHighlighting = false;
Utils::FilePath m_latestQmlls;
};
QmlJsEditingSettings &settings(); QmlJsEditingSettings &settings();
class QmlJsEditingSettingsPage : public Core::IOptionsPage class QmlJsEditingSettingsPage : public Core::IOptionsPage

View File

@@ -5,8 +5,8 @@
#include "qmljseditor.h" #include "qmljseditor.h"
#include "qmljseditordocument.h" #include "qmljseditordocument.h"
#include "qmljseditorsettings.h"
#include "qmljseditortr.h" #include "qmljseditortr.h"
#include "qmllsclientsettings.h"
#include <coreplugin/icore.h> #include <coreplugin/icore.h>
#include <coreplugin/editormanager/ieditor.h> #include <coreplugin/editormanager/ieditor.h>
@@ -382,7 +382,8 @@ void QmlJSHoverHandler::reset()
void QmlJSHoverHandler::operateTooltip(TextEditorWidget *editorWidget, const QPoint &point) void QmlJSHoverHandler::operateTooltip(TextEditorWidget *editorWidget, const QPoint &point)
{ {
// disable hoverhandling in case qmlls is enabled // disable hoverhandling in case qmlls is enabled
if (settings().useQmlls()) { if (editorWidget->textDocument()
&& qmllsSettings()->isEnabledOnProjectFile(editorWidget->textDocument()->filePath())) {
BaseHoverHandler::operateTooltip(editorWidget, point); BaseHoverHandler::operateTooltip(editorWidget, point);
return; return;
} }

View File

@@ -4,9 +4,8 @@
#include "qmllsclient.h" #include "qmllsclient.h"
#include "qmljseditorconstants.h" #include "qmljseditorconstants.h"
#include "qmljseditortr.h"
#include "qmljseditorsettings.h"
#include "qmljsquickfix.h" #include "qmljsquickfix.h"
#include "qmllsclientsettings.h"
#include <languageclient/languageclientinterface.h> #include <languageclient/languageclientinterface.h>
#include <languageclient/languageclientmanager.h> #include <languageclient/languageclientmanager.h>
@@ -43,37 +42,6 @@ static QHash<FilePath, QmllsClient *> &qmllsClients()
return clients; return clients;
} }
QmllsClient *QmllsClient::clientForQmlls(const FilePath &qmlls)
{
if (auto client = qmllsClients()[qmlls]) {
switch (client->state()) {
case Client::State::Uninitialized:
case Client::State::InitializeRequested:
case Client::State::Initialized:
return client;
case Client::State::FailedToInitialize:
case Client::State::ShutdownRequested:
case Client::State::Shutdown:
case Client::State::Error:
qCDebug(qmllsLog) << "client was stopping or failed, restarting";
break;
}
}
auto interface = new StdIOClientInterface;
interface->setCommandLine(CommandLine(qmlls));
auto client = new QmllsClient(interface);
client->setName(Tr::tr("Qmlls (%1)").arg(qmlls.toUserOutput()));
client->setActivateDocumentAutomatically(true);
LanguageFilter filter;
using namespace Utils::Constants;
filter.mimeTypes = {QML_MIMETYPE, QMLUI_MIMETYPE, QBS_MIMETYPE, QMLPROJECT_MIMETYPE,
QMLTYPES_MIMETYPE, JS_MIMETYPE, JSON_MIMETYPE};
client->setSupportedLanguage(filter);
client->start();
qmllsClients()[qmlls] = client;
return client;
}
QMap<QString, int> QmllsClient::semanticTokenTypesMap() QMap<QString, int> QmllsClient::semanticTokenTypesMap()
{ {
QMap<QString, int> result; QMap<QString, int> result;
@@ -90,7 +58,7 @@ QMap<QString, int> QmllsClient::semanticTokenTypesMap()
void QmllsClient::updateQmllsSemanticHighlightingCapability() void QmllsClient::updateQmllsSemanticHighlightingCapability()
{ {
const QString methodName = QStringLiteral("textDocument/semanticTokens"); const QString methodName = QStringLiteral("textDocument/semanticTokens");
if (!QmlJSEditor::Internal::settings().enableQmllsSemanticHighlighting()) { if (!qmllsSettings()->m_useQmllsSemanticHighlighting) {
LanguageServerProtocol::Unregistration unregister; LanguageServerProtocol::Unregistration unregister;
unregister.setMethod(methodName); unregister.setMethod(methodName);
unregister.setId({}); unregister.setId({});

View File

@@ -54,7 +54,6 @@ public:
~QmllsClient(); ~QmllsClient();
void startImpl() override; void startImpl() override;
static QmllsClient *clientForQmlls(const Utils::FilePath &qmlls);
void updateQmllsSemanticHighlightingCapability(); void updateQmllsSemanticHighlightingCapability();
private: private:
static QMap<QString, int> semanticTokenTypesMap(); static QMap<QString, int> semanticTokenTypesMap();

View File

@@ -0,0 +1,332 @@
// Copyright (C) 2024 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "qmllsclientsettings.h"
#include "qmljseditorconstants.h"
#include "qmljseditortr.h"
#include "qmllsclient.h"
#include <utils/mimeconstants.h>
#include <languageclient/languageclientinterface.h>
#include <languageclient/languageclientmanager.h>
#include <languageclient/languageclientsettings.h>
#include <projectexplorer/buildconfiguration.h>
#include <projectexplorer/kitmanager.h>
#include <projectexplorer/project.h>
#include <projectexplorer/projectmanager.h>
#include <projectexplorer/target.h>
#include <QtWidgets/qcheckbox.h>
#include <qmljs/qmljsmodelmanagerinterface.h>
#include <qtsupport/qtkitaspect.h>
#include <qtsupport/qtversionmanager.h>
using namespace LanguageClient;
using namespace QtSupport;
using namespace Utils;
using namespace ProjectExplorer;
namespace QmlJSEditor {
constexpr char useLatestQmllsKey[] = "useLatestQmlls";
constexpr char disableBuiltinCodemodelKey[] = "disableBuiltinCodemodel";
constexpr char generateQmllsIniFilesKey[] = "generateQmllsIniFiles";
constexpr char ignoreMinimumQmllsVersionKey[] = "ignoreMinimumQmllsVersion";
constexpr char useQmllsSemanticHighlightingKey[] = "enableQmllsSemanticHighlighting";
QmllsClientSettings *qmllsSettings()
{
BaseSettings *qmllsSettings
= Utils::findOrDefault(LanguageClientManager::currentSettings(), [](BaseSettings *setting) {
return setting->m_settingsTypeId == Constants::QMLLS_CLIENT_SETTINGS_ID;
});
return static_cast<QmllsClientSettings *>(qmllsSettings);
}
QmllsClientSettings::QmllsClientSettings()
{
m_name = "QML Language Server";
using namespace Utils::Constants;
m_languageFilter.mimeTypes
= {QML_MIMETYPE,
QMLUI_MIMETYPE,
QBS_MIMETYPE,
QMLPROJECT_MIMETYPE,
QMLTYPES_MIMETYPE,
JS_MIMETYPE,
JSON_MIMETYPE};
m_settingsTypeId = Constants::QMLLS_CLIENT_SETTINGS_ID;
m_startBehavior = RequiresProject;
}
static QtVersion *qtVersionFromProject(const Project *project)
{
if (!project)
return {};
auto *target = project->activeTarget();
if (!target)
return {};
auto *kit = target->kit();
if (!kit)
return {};
auto qtVersion = QtKitAspect::qtVersion(kit);
return qtVersion;
}
static std::pair<FilePath, QVersionNumber> evaluateLatestQmlls()
{
// find latest qmlls, i.e. vals
if (!QtVersionManager::isLoaded())
return {};
const QtVersions versions = QtVersionManager::versions();
FilePath latestQmlls;
QVersionNumber latestVersion;
FilePath latestQmakeFilePath;
int latestUniqueId = std::numeric_limits<int>::min();
for (QtVersion *v : versions) {
// check if we find qmlls
QVersionNumber vNow = v->qtVersion();
FilePath qmllsNow = QmlJS::ModelManagerInterface::qmllsForBinPath(v->hostBinPath(), vNow);
if (!qmllsNow.isExecutableFile())
continue;
if (latestVersion > vNow)
continue;
FilePath qmakeNow = v->qmakeFilePath();
int uniqueIdNow = v->uniqueId();
if (latestVersion == vNow) {
if (latestQmakeFilePath > qmakeNow)
continue;
if (latestQmakeFilePath == qmakeNow && latestUniqueId >= v->uniqueId())
continue;
}
latestVersion = vNow;
latestQmlls = qmllsNow;
latestQmakeFilePath = qmakeNow;
latestUniqueId = uniqueIdNow;
}
return std::make_pair(latestQmlls, latestVersion);
}
static CommandLine commandLineForQmlls(const Project *project)
{
const auto *qtVersion = qtVersionFromProject(project);
if (!qtVersion)
return {};
auto [executable, version]
= qmllsSettings()->m_useLatestQmlls
? evaluateLatestQmlls()
: std::make_pair(qtVersion->binPath() / "qmlls", qtVersion->qtVersion());
CommandLine result{executable, {}};
if (auto *configuration = project->activeTarget()->activeBuildConfiguration())
result.addArgs({"-b", configuration->buildDirectory().path()});
// qmlls 6.8 and later require the import path
if (version >= QVersionNumber(6, 8, 0))
result.addArgs({"-I", qtVersion->qmlPath().path()});
// qmlls 6.8.1 and later require the documentation path
if (version >= QVersionNumber(6, 8, 1))
result.addArgs({"-d", qtVersion->docsPath().path()});
return result;
}
BaseClientInterface *QmllsClientSettings::createInterface(Project *project) const
{
auto interface = new StdIOClientInterface;
interface->setCommandLine(commandLineForQmlls(project));
return interface;
}
Client *QmllsClientSettings::createClient(BaseClientInterface *interface) const
{
return new QmllsClient(static_cast<StdIOClientInterface *>(interface));
}
class QmllsClientSettingsWidget : public QWidget
{
Q_OBJECT
public:
explicit QmllsClientSettingsWidget(
const QmllsClientSettings *settings, QWidget *parent = nullptr);
bool useLatestQmlls() const;
bool disableBuiltinCodemodel() const;
bool generateQmllsIniFiles() const;
bool ignoreMinimumQmllsVersion() const;
bool useQmllsSemanticHighlighting() const;
private:
QCheckBox *m_useLatestQmlls;
QCheckBox *m_disableBuiltinCodemodel;
QCheckBox *m_generateQmllsIniFiles;
QCheckBox *m_ignoreMinimumQmllsVersion;
QCheckBox *m_useQmllsSemanticHighlighting;
};
QWidget *QmllsClientSettings::createSettingsWidget(QWidget *parent) const
{
return new QmllsClientSettingsWidget(this, parent);
}
bool QmllsClientSettings::applyFromSettingsWidget(QWidget *widget)
{
bool changed = BaseSettings::applyFromSettingsWidget(widget);
QmllsClientSettingsWidget *qmllsWidget = qobject_cast<QmllsClientSettingsWidget *>(widget);
if (!qmllsWidget)
return changed;
if (m_useLatestQmlls != qmllsWidget->useLatestQmlls()) {
m_useLatestQmlls = qmllsWidget->useLatestQmlls();
changed = true;
}
if (m_disableBuiltinCodemodel != qmllsWidget->disableBuiltinCodemodel()) {
m_disableBuiltinCodemodel = qmllsWidget->disableBuiltinCodemodel();
changed = true;
}
if (m_generateQmllsIniFiles != qmllsWidget->generateQmllsIniFiles()) {
m_generateQmllsIniFiles = qmllsWidget->generateQmllsIniFiles();
changed = true;
}
if (m_ignoreMinimumQmllsVersion != qmllsWidget->ignoreMinimumQmllsVersion()) {
m_ignoreMinimumQmllsVersion = qmllsWidget->ignoreMinimumQmllsVersion();
changed = true;
}
if (m_useQmllsSemanticHighlighting != qmllsWidget->useQmllsSemanticHighlighting()) {
m_useQmllsSemanticHighlighting = qmllsWidget->useQmllsSemanticHighlighting();
changed = true;
}
return changed;
}
void QmllsClientSettings::toMap(Store &map) const
{
BaseSettings::toMap(map);
map.insert(useLatestQmllsKey, m_useLatestQmlls);
map.insert(disableBuiltinCodemodelKey, m_disableBuiltinCodemodel);
map.insert(generateQmllsIniFilesKey, m_generateQmllsIniFiles);
map.insert(ignoreMinimumQmllsVersionKey, m_ignoreMinimumQmllsVersion);
map.insert(useQmllsSemanticHighlightingKey, m_useQmllsSemanticHighlighting);
}
void QmllsClientSettings::fromMap(const Store &map)
{
BaseSettings::fromMap(map);
m_useLatestQmlls = map[useLatestQmllsKey].toBool();
m_disableBuiltinCodemodel = map[disableBuiltinCodemodelKey].toBool();
m_generateQmllsIniFiles = map[generateQmllsIniFilesKey].toBool();
m_ignoreMinimumQmllsVersion = map[ignoreMinimumQmllsVersionKey].toBool();
m_useQmllsSemanticHighlighting = map[useQmllsSemanticHighlightingKey].toBool();
return;
}
bool QmllsClientSettings::isEnabledOnProjectFile(const Utils::FilePath &file) const
{
Project *project = ProjectManager::projectForFile(file);
return isEnabledOnProject(project);
}
bool QmllsClientSettings::useQmllsWithBuiltinCodemodelOnProject(const Utils::FilePath &file) const
{
if (m_disableBuiltinCodemodel)
return false;
// disableBuitinCodemodel only makes sense when qmlls is enabled
Project *project = ProjectManager::projectForFile(file);
return isEnabledOnProject(project);
}
void setupQmllsClientSettings()
{
using namespace LanguageClient;
QmllsClientSettings *clientSettings = new QmllsClientSettings();
const ClientType type{
Constants::QMLLS_CLIENT_SETTINGS_ID,
clientSettings->m_name,
[]() { return new QmllsClientSettings; },
false};
const QList<Utils::Store> savedSettings = LanguageClientSettings::storesBySettingsType(type.id);
if (!savedSettings.isEmpty())
clientSettings->fromMap(savedSettings.first());
LanguageClientManager::registerClientSettings(clientSettings);
LanguageClientSettings::registerClientType(type);
}
QmllsClientSettingsWidget::QmllsClientSettingsWidget(
const QmllsClientSettings *settings, QWidget *parent)
: QWidget(parent)
, m_useLatestQmlls(new QCheckBox(Tr::tr("Use from latest Qt version"), this))
, m_disableBuiltinCodemodel(new QCheckBox(
Tr::tr("Use advanced features (renaming, find usages, and so on) (experimental)"), this))
, m_generateQmllsIniFiles(
new QCheckBox(Tr::tr("Create .qmlls.ini files for new projects"), this))
, m_ignoreMinimumQmllsVersion(new QCheckBox(
Tr::tr("Allow versions below Qt %1")
.arg(QmllsClientSettings::mininumQmllsVersion.toString()),
this))
, m_useQmllsSemanticHighlighting(
new QCheckBox(Tr::tr("Enable semantic highlighting (experimental)"), this))
{
m_useLatestQmlls->setChecked(settings->m_useLatestQmlls);
m_disableBuiltinCodemodel->setChecked(settings->m_disableBuiltinCodemodel);
m_generateQmllsIniFiles->setChecked(settings->m_generateQmllsIniFiles);
m_ignoreMinimumQmllsVersion->setChecked(settings->m_ignoreMinimumQmllsVersion);
m_useQmllsSemanticHighlighting->setChecked(settings->m_useQmllsSemanticHighlighting);
using namespace Layouting;
// clang-format off
auto form = Form {
m_ignoreMinimumQmllsVersion, br,
m_disableBuiltinCodemodel, br,
m_useQmllsSemanticHighlighting, br,
m_useLatestQmlls, br,
m_generateQmllsIniFiles, br,
};
// clang-format on
form.attachTo(this);
}
bool QmllsClientSettingsWidget::useLatestQmlls() const
{
return m_useLatestQmlls->isChecked();
}
bool QmllsClientSettingsWidget::disableBuiltinCodemodel() const
{
return m_disableBuiltinCodemodel->isChecked();
}
bool QmllsClientSettingsWidget::generateQmllsIniFiles() const
{
return m_generateQmllsIniFiles->isChecked();
}
bool QmllsClientSettingsWidget::ignoreMinimumQmllsVersion() const
{
return m_ignoreMinimumQmllsVersion->isChecked();
}
bool QmllsClientSettingsWidget::useQmllsSemanticHighlighting() const
{
return m_useQmllsSemanticHighlighting->isChecked();
}
} // namespace QmlJSEditor
#include "qmllsclientsettings.moc"

View File

@@ -0,0 +1,46 @@
// Copyright (C) 2024 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#pragma once
#include <languageclient/languageclientsettings.h>
#include <QVersionNumber>
#include <QWidget>
namespace QmlJSEditor {
class QmllsClientSettings : public LanguageClient::BaseSettings
{
public:
static const inline QVersionNumber mininumQmllsVersion = QVersionNumber(6, 8);
QmllsClientSettings();
BaseSettings *copy() const override { return new QmllsClientSettings(*this); }
QWidget *createSettingsWidget(QWidget *parent = nullptr) const override;
bool applyFromSettingsWidget(QWidget *widget) override;
void toMap(Utils::Store &map) const override;
void fromMap(const Utils::Store &map) override;
// helpers:
bool isEnabledOnProjectFile(const Utils::FilePath &file) const;
bool useQmllsWithBuiltinCodemodelOnProject(const Utils::FilePath &file) const;
bool m_useLatestQmlls = false;
bool m_ignoreMinimumQmllsVersion = false;
bool m_useQmllsSemanticHighlighting = false;
bool m_disableBuiltinCodemodel = false;
bool m_generateQmllsIniFiles = false;
protected:
LanguageClient::BaseClientInterface *createInterface(ProjectExplorer::Project *) const override;
LanguageClient::Client *createClient(
LanguageClient::BaseClientInterface *interface) const override;
};
QmllsClientSettings *qmllsSettings();
void setupQmllsClientSettings();
} // namespace QmlJSEditor

View File

@@ -3,7 +3,7 @@
#include "qmltaskmanager.h" #include "qmltaskmanager.h"
#include "qmljseditorconstants.h" #include "qmljseditorconstants.h"
#include "qmljseditorsettings.h" #include "qmllsclientsettings.h"
#include <coreplugin/icore.h> #include <coreplugin/icore.h>
#include <coreplugin/idocument.h> #include <coreplugin/idocument.h>
@@ -122,7 +122,7 @@ void QmlTaskManager::updateSemanticMessagesNow()
const bool isCMake = buildSystem->name() == "cmake"; const bool isCMake = buildSystem->name() == "cmake";
// heuristic: qmllint will output meaningful warnings if qmlls is enabled // heuristic: qmllint will output meaningful warnings if qmlls is enabled
if (isCMake && QmllsSettingsManager::instance()->useQmlls(buildSystem->project())) { if (isCMake && qmllsSettings()->isEnabledOnProject(buildSystem->project())) {
// abort any update that's going on already, and remove old codemodel warnings // abort any update that's going on already, and remove old codemodel warnings
m_messageCollector.cancel(); m_messageCollector.cancel();
removeAllTasks(true); removeAllTasks(true);