diff options
43 files changed, 455 insertions, 311 deletions
diff --git a/.github/workflows/build_cmake.yml b/.github/workflows/build_cmake.yml index 1d2eeb5809..a8ff73315c 100644 --- a/.github/workflows/build_cmake.yml +++ b/.github/workflows/build_cmake.yml @@ -367,7 +367,9 @@ jobs: - name: Install Strip - run: ${{ steps.cmake_and_ninja.outputs.cmake_dir }}/cmake --install build --prefix instdir --strip + run: | + ${{ steps.cmake_and_ninja.outputs.cmake_dir }}/cmake --install build --prefix instdir --strip + ${{ steps.cmake_and_ninja.outputs.cmake_dir }}/cmake --install build --prefix instdir --component Dependencies - name: Install Devel run: ${{ steps.cmake_and_ninja.outputs.cmake_dir }}/cmake --install build --prefix instdir-dev --component Devel diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index 96625d0a12..46d49a1690 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -6,10 +6,7 @@ # # This way we are sure that all the binaries have been installed before. -option(DEPLOY_QTC_DEPENDENCIES - "Deployment of Qt, Clang, C++ Runtime libraries" ON) - -if (CMAKE_VERSION VERSION_GREATER_EQUAL 3.16 AND DEPLOY_QTC_DEPENDENCIES) +if (CMAKE_VERSION VERSION_GREATER_EQUAL 3.16) get_target_property(moc_binary Qt5::moc IMPORTED_LOCATION) get_filename_component(moc_dir "${moc_binary}" DIRECTORY) get_filename_component(QT_BASE_DIR "${moc_dir}/../" ABSOLUTE) @@ -28,6 +25,7 @@ if (CMAKE_VERSION VERSION_GREATER_EQUAL 3.16 AND DEPLOY_QTC_DEPENDENCIES) install( DIRECTORY "${QT_BASE_DIR}/plugins/${plugin}" DESTINATION ${QT_DEST_PLUGIN_PATH} + COMPONENT Dependencies ${exclusion_mask} ) list(APPEND QT_PLUGIN_DIRECTORIES "${QT_DEST_PLUGIN_PATH}/${plugin}") @@ -36,6 +34,7 @@ if (CMAKE_VERSION VERSION_GREATER_EQUAL 3.16 AND DEPLOY_QTC_DEPENDENCIES) install( DIRECTORY "${QT_BASE_DIR}/qml/" DESTINATION ${QT_DEST_QML_PATH} + COMPONENT Dependencies PATTERN "qml/*" ${exclusion_mask} ) @@ -43,7 +42,10 @@ if (CMAKE_VERSION VERSION_GREATER_EQUAL 3.16 AND DEPLOY_QTC_DEPENDENCIES) # Analyze the binaries and install missing dependencies if they are # found the CMAKE_PREFIX_PATH e.g. Qt, Clang configure_file(InstallDependentSharedObjects.cmake.in InstallDependentSharedObjects.cmake @ONLY) - install(SCRIPT ${CMAKE_CURRENT_BINARY_DIR}/InstallDependentSharedObjects.cmake) + install( + SCRIPT ${CMAKE_CURRENT_BINARY_DIR}/InstallDependentSharedObjects.cmake + COMPONENT Dependencies + ) if (MSVC) set(CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_SKIP ON) @@ -51,6 +53,7 @@ if (CMAKE_VERSION VERSION_GREATER_EQUAL 3.16 AND DEPLOY_QTC_DEPENDENCIES) install(PROGRAMS ${CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS} DESTINATION ${IDE_APP_PATH} + COMPONENT Dependencies ) endif() endif() diff --git a/cmake/QtCreatorAPI.cmake b/cmake/QtCreatorAPI.cmake index 902ccc02d0..8ca2a4f27f 100644 --- a/cmake/QtCreatorAPI.cmake +++ b/cmake/QtCreatorAPI.cmake @@ -1045,6 +1045,7 @@ function(add_qtc_executable name) create_qt_conf(\"${_EXECUTABLE_PATH}\" \"${IDE_LIBRARY_BASE_PATH}/Qt\") endif() " + COMPONENT Dependencies ) endif() diff --git a/share/share.qbs b/share/share.qbs index ba7b2a453f..17a680b202 100644 --- a/share/share.qbs +++ b/share/share.qbs @@ -11,6 +11,7 @@ Product { qbs.installSourceBase: "qtcreator" prefix: "qtcreator/" files: [ + "android/**/*", "cplusplus/**/*", "debugger/**/*", "designer/**/*", diff --git a/src/libs/clangsupport/CMakeLists.txt b/src/libs/clangsupport/CMakeLists.txt index a4b6e88660..89cde64d18 100644 --- a/src/libs/clangsupport/CMakeLists.txt +++ b/src/libs/clangsupport/CMakeLists.txt @@ -176,15 +176,17 @@ foreach(executable clang clang-cl clangd clang-tidy clazy-standalone) # For the install directory install(PROGRAMS - "${LLVM_TOOLS_BINARY_DIR}/${executable}${CMAKE_EXECUTABLE_SUFFIX}" - DESTINATION "${IDE_LIBEXEC_PATH}/clang/bin" + "${LLVM_TOOLS_BINARY_DIR}/${executable}${CMAKE_EXECUTABLE_SUFFIX}" + DESTINATION "${IDE_LIBEXEC_PATH}/clang/bin" + COMPONENT Dependencies ) if (IS_SYMLINK "${LLVM_TOOLS_BINARY_DIR}/${executable}${CMAKE_EXECUTABLE_SUFFIX}") file(READ_SYMLINK "${LLVM_TOOLS_BINARY_DIR}/${executable}${CMAKE_EXECUTABLE_SUFFIX}" real_executable) install(PROGRAMS - "${LLVM_TOOLS_BINARY_DIR}/${real_executable}${CMAKE_EXECUTABLE_SUFFIX}" - DESTINATION "${IDE_LIBEXEC_PATH}/clang/bin" + "${LLVM_TOOLS_BINARY_DIR}/${real_executable}${CMAKE_EXECUTABLE_SUFFIX}" + DESTINATION "${IDE_LIBEXEC_PATH}/clang/bin" + COMPONENT Dependencies ) endif() endif() @@ -192,4 +194,5 @@ endforeach() install(DIRECTORY ${LLVM_LIBRARY_DIR}/clang/${CLANG_VERSION}/include DESTINATION "${IDE_LIBEXEC_PATH}/clang/lib/clang/${CLANG_VERSION}" + COMPONENT Dependencies ) diff --git a/src/libs/languageserverprotocol/client.h b/src/libs/languageserverprotocol/client.h index bf2fe5421a..a07d48e94f 100644 --- a/src/libs/languageserverprotocol/client.h +++ b/src/libs/languageserverprotocol/client.h @@ -50,7 +50,7 @@ public: void setRegisterOptions(const QJsonValue ®isterOptions) { insert(registerOptionsKey, registerOptions); } - bool isValid(QStringList *error) const override + bool isValid(ErrorHierarchy *error) const override { return check<QString>(error, idKey) && check<QString>(error, methodKey); } }; @@ -65,7 +65,7 @@ public: void setRegistrations(const QList<Registration> ®istrations) { insertArray(registrationsKey, registrations); } - bool isValid(QStringList *error) const override + bool isValid(ErrorHierarchy *error) const override { return checkArray<Registration>(error, registrationsKey); } }; @@ -89,7 +89,7 @@ public: QString method() const { return typedValue<QString>(methodKey); } void setMethod(const QString &method) { insert(methodKey, method); } - bool isValid(QStringList *error) const override + bool isValid(ErrorHierarchy *error) const override { return check<QString>(error, idKey) && check<QString>(error, methodKey); } }; @@ -103,7 +103,7 @@ public: void setUnregistrations(const QList<Unregistration> &unregistrations) { insertArray(unregistrationsKey, unregistrations); } - bool isValid(QStringList *error) const override + bool isValid(ErrorHierarchy *error) const override { return checkArray<Unregistration>(error, unregistrationsKey); } }; diff --git a/src/libs/languageserverprotocol/clientcapabilities.cpp b/src/libs/languageserverprotocol/clientcapabilities.cpp index 1f79ffae0d..fac2d3f5d7 100644 --- a/src/libs/languageserverprotocol/clientcapabilities.cpp +++ b/src/libs/languageserverprotocol/clientcapabilities.cpp @@ -42,7 +42,7 @@ void SymbolCapabilities::SymbolKindCapabilities::setValueSet(const QList<SymbolK insert(valueSetKey, enumArrayToJsonArray<SymbolKind>(valueSet)); } -bool ClientCapabilities::isValid(QStringList *error) const +bool ClientCapabilities::isValid(ErrorHierarchy *error) const { return checkOptional<WorkspaceClientCapabilities>(error, workspaceKey) && checkOptional<TextDocumentClientCapabilities>(error, textDocumentKey); @@ -53,7 +53,7 @@ WorkspaceClientCapabilities::WorkspaceClientCapabilities() setWorkspaceFolders(true); } -bool WorkspaceClientCapabilities::isValid(QStringList *error) const +bool WorkspaceClientCapabilities::isValid(ErrorHierarchy *error) const { return checkOptional<bool>(error,applyEditKey) && checkOptional<WorkspaceEditCapabilities>(error,workspaceEditKey) @@ -65,7 +65,7 @@ bool WorkspaceClientCapabilities::isValid(QStringList *error) const && checkOptional<bool>(error,configurationKey); } -bool TextDocumentClientCapabilities::SynchronizationCapabilities::isValid(QStringList *error) const +bool TextDocumentClientCapabilities::SynchronizationCapabilities::isValid(ErrorHierarchy *error) const { return DynamicRegistrationCapabilities::isValid(error) && checkOptional<bool>(error, willSaveKey) @@ -73,7 +73,7 @@ bool TextDocumentClientCapabilities::SynchronizationCapabilities::isValid(QStrin && checkOptional<bool>(error, didSaveKey); } -bool TextDocumentClientCapabilities::isValid(QStringList *error) const +bool TextDocumentClientCapabilities::isValid(ErrorHierarchy *error) const { return checkOptional<SynchronizationCapabilities>(error, synchronizationKey) && checkOptional<CompletionCapabilities>(error, completionKey) @@ -96,13 +96,13 @@ bool TextDocumentClientCapabilities::isValid(QStringList *error) const && checkOptional<SemanticHighlightingCapabilities>(error, semanticHighlightingCapabilitiesKey); } -bool SymbolCapabilities::isValid(QStringList *error) const +bool SymbolCapabilities::isValid(ErrorHierarchy *error) const { return DynamicRegistrationCapabilities::isValid(error) && checkOptional<SymbolKindCapabilities>(error, symbolKindKey); } -bool TextDocumentClientCapabilities::CompletionCapabilities::isValid(QStringList *error) const +bool TextDocumentClientCapabilities::CompletionCapabilities::isValid(ErrorHierarchy *error) const { return DynamicRegistrationCapabilities::isValid(error) && checkOptional<CompletionItemCapbilities>(error, completionItemKey) @@ -110,19 +110,19 @@ bool TextDocumentClientCapabilities::CompletionCapabilities::isValid(QStringList && checkOptional<bool>(error, contextSupportKey); } -bool TextDocumentClientCapabilities::HoverCapabilities::isValid(QStringList *error) const +bool TextDocumentClientCapabilities::HoverCapabilities::isValid(ErrorHierarchy *error) const { return DynamicRegistrationCapabilities::isValid(error) && checkOptionalArray<int>(error, contentFormatKey); } -bool TextDocumentClientCapabilities::SignatureHelpCapabilities::isValid(QStringList *error) const +bool TextDocumentClientCapabilities::SignatureHelpCapabilities::isValid(ErrorHierarchy *error) const { return DynamicRegistrationCapabilities::isValid(error) && checkOptional<SignatureHelpCapabilities>(error, signatureInformationKey); } -bool TextDocumentClientCapabilities::CodeActionCapabilities::isValid(QStringList *errorHierarchy) const +bool TextDocumentClientCapabilities::CodeActionCapabilities::isValid(ErrorHierarchy *errorHierarchy) const { return DynamicRegistrationCapabilities::isValid(errorHierarchy) && checkOptional<CodeActionLiteralSupport>(errorHierarchy, codeActionLiteralSupportKey); diff --git a/src/libs/languageserverprotocol/clientcapabilities.h b/src/libs/languageserverprotocol/clientcapabilities.h index ec1bdd25b5..76462fa15b 100644 --- a/src/libs/languageserverprotocol/clientcapabilities.h +++ b/src/libs/languageserverprotocol/clientcapabilities.h @@ -39,7 +39,7 @@ public: void setDynamicRegistration(bool dynamicRegistration) { insert(dynamicRegistrationKey, dynamicRegistration); } void clearDynamicRegistration() { remove(dynamicRegistrationKey); } - bool isValid(QStringList *error) const override + bool isValid(ErrorHierarchy *error) const override { return checkOptional<bool>(error, dynamicRegistrationKey); } }; @@ -67,7 +67,7 @@ public: void setValueSet(const QList<SymbolKind> &valueSet); void clearValueSet() { remove(valueSetKey); } - bool isValid(QStringList *error) const override + bool isValid(ErrorHierarchy *error) const override { return checkOptionalArray<int>(error, valueSetKey); } }; @@ -77,7 +77,7 @@ public: void setSymbolKind(const SymbolKindCapabilities &symbolKind) { insert(symbolKindKey, symbolKind); } void clearSymbolKind() { remove(symbolKindKey); } - bool isValid(QStringList *error) const override; + bool isValid(ErrorHierarchy *error) const override; }; class LANGUAGESERVERPROTOCOL_EXPORT TextDocumentClientCapabilities : public JsonObject @@ -111,7 +111,7 @@ public: void setDidSave(bool didSave) { insert(didSaveKey, didSave); } void clearDidSave() { remove(didSaveKey); } - bool isValid(QStringList *error) const override; + bool isValid(ErrorHierarchy *error) const override; }; Utils::optional<SynchronizationCapabilities> synchronization() const @@ -129,7 +129,7 @@ public: void setSemanticHighlighting(bool semanticHighlighting) { insert(semanticHighlightingKey, semanticHighlighting); } - bool isValid(QStringList *error) const override + bool isValid(ErrorHierarchy *error) const override { return check<bool>(error, semanticHighlightingKey); } }; @@ -179,7 +179,7 @@ public: void setDocumentationFormat(const QList<MarkupKind> &documentationFormat); void clearDocumentationFormat() { remove(documentationFormatKey); } - bool isValid(QStringList *error) const override + bool isValid(ErrorHierarchy *error) const override { return checkOptional<bool>(error, snippetSupportKey) && checkOptional<bool>(error, commitCharacterSupportKey) @@ -213,7 +213,7 @@ public: void setValueSet(const QList<CompletionItemKind::Kind> &valueSet); void clearValueSet() { remove(valueSetKey); } - bool isValid(QStringList *error) const override + bool isValid(ErrorHierarchy *error) const override { return checkOptionalArray<int>(error, valueSetKey); } }; @@ -231,7 +231,7 @@ public: void setContextSupport(bool contextSupport) { insert(contextSupportKey, contextSupport); } void clearContextSupport() { remove(contextSupportKey); } - bool isValid(QStringList *error) const override; + bool isValid(ErrorHierarchy *error) const override; }; // Capabilities specific to the `textDocument/completion` @@ -253,7 +253,7 @@ public: void setContentFormat(const QList<MarkupKind> &contentFormat); void clearContentFormat() { remove(contentFormatKey); } - bool isValid(QStringList *error) const override; + bool isValid(ErrorHierarchy *error) const override; }; Utils::optional<HoverCapabilities> hover() const { return optionalValue<HoverCapabilities>(hoverKey); } @@ -277,7 +277,7 @@ public: void setDocumentationFormat(const QList<MarkupKind> &documentationFormat); void clearDocumentationFormat() { remove(documentationFormatKey); } - bool isValid(QStringList *error) const override + bool isValid(ErrorHierarchy *error) const override { return checkOptionalArray<int>(error, documentationFormatKey); } }; @@ -288,7 +288,7 @@ public: { insert(signatureInformationKey, signatureInformation); } void clearSignatureInformation() { remove(signatureInformationKey); } - bool isValid(QStringList *error) const override; + bool isValid(ErrorHierarchy *error) const override; }; // Capabilities specific to the `textDocument/signatureHelp` @@ -390,7 +390,7 @@ public: void setValueSet(const QList<QString> &valueSet) { insertArray(valueSetKey, valueSet); } - bool isValid(QStringList *errorHierarchy) const override + bool isValid(ErrorHierarchy *errorHierarchy) const override { return checkArray<QString>(errorHierarchy, valueSetKey); } }; @@ -399,7 +399,7 @@ public: void setCodeActionKind(const CodeActionKind &codeActionKind) { insert(codeActionKindKey, codeActionKind); } - bool isValid(QStringList *errorHierarchy) const override + bool isValid(ErrorHierarchy *errorHierarchy) const override { return check<CodeActionKind>(errorHierarchy, codeActionKindKey); } }; @@ -409,7 +409,7 @@ public: { insert(codeActionLiteralSupportKey, codeActionLiteralSupport); } void clearCodeActionLiteralSupport() { remove(codeActionLiteralSupportKey); } - bool isValid(QStringList *errorHierarchy) const override; + bool isValid(ErrorHierarchy *errorHierarchy) const override; }; // Whether code action supports dynamic registration. @@ -451,7 +451,7 @@ public: { insert(renameKey, rename); } void clearRename() { remove(renameKey); } - bool isValid(QStringList *error) const override; + bool isValid(ErrorHierarchy *error) const override; }; class LANGUAGESERVERPROTOCOL_EXPORT WorkspaceClientCapabilities : public JsonObject @@ -480,7 +480,7 @@ public: { insert(documentChangesKey, documentChanges); } void clearDocumentChanges() { remove(documentChangesKey); } - bool isValid(QStringList *error) const override + bool isValid(ErrorHierarchy *error) const override { return checkOptional<bool>(error, documentChangesKey); } }; @@ -530,7 +530,7 @@ public: void setConfiguration(bool configuration) { insert(configurationKey, configuration); } void clearConfiguration() { remove(configurationKey); } - bool isValid(QStringList *error) const override; + bool isValid(ErrorHierarchy *error) const override; }; class LANGUAGESERVERPROTOCOL_EXPORT ClientCapabilities : public JsonObject @@ -557,7 +557,7 @@ public: void setExperimental(const QJsonValue &experimental) { insert(experimentalKey, experimental); } void clearExperimental() { remove(experimentalKey); } - bool isValid(QStringList *error) const override; + bool isValid(ErrorHierarchy *error) const override; }; } diff --git a/src/libs/languageserverprotocol/completion.cpp b/src/libs/languageserverprotocol/completion.cpp index eb5f22cf6a..ca34629805 100644 --- a/src/libs/languageserverprotocol/completion.cpp +++ b/src/libs/languageserverprotocol/completion.cpp @@ -49,7 +49,7 @@ Utils::optional<CompletionItem::InsertTextFormat> CompletionItem::insertTextForm : Utils::make_optional(CompletionItem::InsertTextFormat(value.value())); } -bool CompletionItem::isValid(QStringList *error) const +bool CompletionItem::isValid(ErrorHierarchy *error) const { return check<QString>(error, labelKey) && checkOptional<int>(error, kindKey) @@ -70,14 +70,14 @@ CompletionItemResolveRequest::CompletionItemResolveRequest(const CompletionItem : Request(methodName, params) { } -bool CompletionList::isValid(QStringList *error) const +bool CompletionList::isValid(ErrorHierarchy *error) const { return check<bool>(error, isIncompleteKey) && checkOptionalArray<CompletionItem>(error, itemsKey); } -bool CompletionParams::isValid(QStringList *error) const +bool CompletionParams::isValid(ErrorHierarchy *error) const { return TextDocumentPositionParams::isValid(error) && checkOptional<CompletionContext>(error, contextKey); diff --git a/src/libs/languageserverprotocol/completion.h b/src/libs/languageserverprotocol/completion.h index 3db5be4d70..629f0eb398 100644 --- a/src/libs/languageserverprotocol/completion.h +++ b/src/libs/languageserverprotocol/completion.h @@ -71,7 +71,7 @@ public: { insert(triggerCharacterKey, triggerCharacter); } void clearTriggerCharacter() { remove(triggerCharacterKey); } - bool isValid(QStringList *error) const override + bool isValid(ErrorHierarchy *error) const override { return check<int>(error, triggerKindKey) && checkOptional<QString>(error, triggerCharacterKey); @@ -88,7 +88,7 @@ public: { insert(contextKey, context); } void clearContext() { remove(contextKey); } - bool isValid(QStringList *error) const override; + bool isValid(ErrorHierarchy *error) const override; }; class LANGUAGESERVERPROTOCOL_EXPORT CompletionItem : public JsonObject @@ -220,7 +220,7 @@ public: void setData(const QJsonValue &data) { insert(dataKey, data); } void clearData() { remove(dataKey); } - bool isValid(QStringList *error) const override; + bool isValid(ErrorHierarchy *error) const override; }; class LANGUAGESERVERPROTOCOL_EXPORT CompletionList : public JsonObject @@ -240,7 +240,7 @@ public: void setItems(const QList<CompletionItem> &items) { insertArray(itemsKey, items); } void clearItems() { remove(itemsKey); } - bool isValid(QStringList *error) const override; + bool isValid(ErrorHierarchy *error) const override; }; /// The result of a completion is CompletionItem[] | CompletionList | null diff --git a/src/libs/languageserverprotocol/diagnostics.h b/src/libs/languageserverprotocol/diagnostics.h index 30f5081f07..24c470b2d1 100644 --- a/src/libs/languageserverprotocol/diagnostics.h +++ b/src/libs/languageserverprotocol/diagnostics.h @@ -42,7 +42,7 @@ public: void setDiagnostics(const QList<Diagnostic> &diagnostics) { insertArray(diagnosticsKey, diagnostics); } - bool isValid(QStringList *error) const override + bool isValid(ErrorHierarchy *error) const override { return checkArray<Diagnostic>(error, diagnosticsKey); } }; diff --git a/src/libs/languageserverprotocol/icontent.h b/src/libs/languageserverprotocol/icontent.h index 1b57165b2e..f1c02f5a1a 100644 --- a/src/libs/languageserverprotocol/icontent.h +++ b/src/libs/languageserverprotocol/icontent.h @@ -26,6 +26,7 @@ #pragma once #include "basemessage.h" +#include "lsputils.h" #include <utils/mimetypes/mimetype.h> #include <utils/qtcassert.h> @@ -69,12 +70,12 @@ public: return QJsonValue(); } - bool isValid(QStringList *error = nullptr) const + bool isValid(ErrorHierarchy *error = nullptr) const { if (Utils::holds_alternative<int>(*this) || Utils::holds_alternative<QString>(*this)) return true; if (error) - error->append("Expected int or string as MessageId"); + error->setError("Expected int or string as MessageId"); return false; } diff --git a/src/libs/languageserverprotocol/initializemessages.cpp b/src/libs/languageserverprotocol/initializemessages.cpp index 92e82d5107..66e3407fe1 100644 --- a/src/libs/languageserverprotocol/initializemessages.cpp +++ b/src/libs/languageserverprotocol/initializemessages.cpp @@ -140,9 +140,9 @@ Utils::optional<Trace> InitializeParams::trace() const return Utils::make_optional(Trace(traceValue.toString())); } -bool InitializeParams::isValid(QStringList *error) const +bool InitializeParams::isValid(ErrorHierarchy *error) const { - return check<int, std::nullptr_t>(error, processIdKey) + return checkVariant<int, std::nullptr_t>(error, processIdKey) && checkOptional<QString, std::nullptr_t>(error, rootPathKey) && checkOptional<QString, std::nullptr_t>(error, rootUriKey) && check<ClientCapabilities>(error, capabilitiesKey) diff --git a/src/libs/languageserverprotocol/initializemessages.h b/src/libs/languageserverprotocol/initializemessages.h index f0eb83beb3..a79d6e067a 100644 --- a/src/libs/languageserverprotocol/initializemessages.h +++ b/src/libs/languageserverprotocol/initializemessages.h @@ -121,7 +121,7 @@ public: { insert(workSpaceFoldersKey, folders.toJson()); } void clearWorkSpaceFolders() { remove(workSpaceFoldersKey); } - bool isValid(QStringList *error) const override; + bool isValid(ErrorHierarchy *error) const override; }; using InitializedParams = JsonObject; @@ -147,7 +147,7 @@ public: { insert(capabilitiesKey, capabilities); } void clearCapabilities() { remove(capabilitiesKey); } - bool isValid(QStringList *error) const override + bool isValid(ErrorHierarchy *error) const override { return checkOptional<ServerCapabilities>(error, capabilitiesKey); } }; @@ -166,7 +166,7 @@ public: void setRetry(bool retry) { insert(retryKey, retry); } void clearRetry() { remove(retryKey); } - bool isValid(QStringList *error) const override { return checkOptional<bool>(error, retryKey); } + bool isValid(ErrorHierarchy *error) const override { return checkOptional<bool>(error, retryKey); } }; class LANGUAGESERVERPROTOCOL_EXPORT InitializeRequest : public Request< diff --git a/src/libs/languageserverprotocol/jsonobject.cpp b/src/libs/languageserverprotocol/jsonobject.cpp index 0156276a67..7bdf3f8688 100644 --- a/src/libs/languageserverprotocol/jsonobject.cpp +++ b/src/libs/languageserverprotocol/jsonobject.cpp @@ -30,31 +30,31 @@ namespace LanguageServerProtocol { template <> -bool JsonObject::checkVal<QString>(QStringList *errorHierarchy, const QJsonValue &val) +bool JsonObject::checkVal<QString>(ErrorHierarchy *errorHierarchy, const QJsonValue &val) { return checkType(val.type(), QJsonValue::String, errorHierarchy); } template <> -bool JsonObject::checkVal<int>(QStringList *errorHierarchy, const QJsonValue &val) +bool JsonObject::checkVal<int>(ErrorHierarchy *errorHierarchy, const QJsonValue &val) { return checkType(val.type(), QJsonValue::Double, errorHierarchy); } template <> -bool JsonObject::checkVal<double>(QStringList *errorHierarchy, const QJsonValue &val) +bool JsonObject::checkVal<double>(ErrorHierarchy *errorHierarchy, const QJsonValue &val) { return checkType(val.type(), QJsonValue::Double, errorHierarchy); } template <> -bool JsonObject::checkVal<bool>(QStringList *errorHierarchy, const QJsonValue &val) +bool JsonObject::checkVal<bool>(ErrorHierarchy *errorHierarchy, const QJsonValue &val) { return checkType(val.type(), QJsonValue::Bool, errorHierarchy); } template <> -bool JsonObject::checkVal<std::nullptr_t>(QStringList *errorHierarchy, const QJsonValue &val) +bool JsonObject::checkVal<std::nullptr_t>(ErrorHierarchy *errorHierarchy, const QJsonValue &val) { return checkType(val.type(), QJsonValue::Null, errorHierarchy); } template<> -bool JsonObject::checkVal<QJsonArray>(QStringList *errorHierarchy, const QJsonValue &val) +bool JsonObject::checkVal<QJsonArray>(ErrorHierarchy *errorHierarchy, const QJsonValue &val) { return checkType(val.type(), QJsonValue::Array, errorHierarchy); } template<> -bool JsonObject::checkVal<QJsonValue>(QStringList * /*errorHierarchy*/, const QJsonValue &/*val*/) +bool JsonObject::checkVal<QJsonValue>(ErrorHierarchy * /*errorHierarchy*/, const QJsonValue &/*val*/) { return true; } JsonObject &JsonObject::operator=(const JsonObject &other) = default; @@ -75,12 +75,12 @@ QJsonObject::iterator JsonObject::insert(const QString &key, const QJsonValue &v return m_jsonObject.insert(key, value); } -bool JsonObject::checkKey(QStringList *errorHierarchy, const QString &key, +bool JsonObject::checkKey(ErrorHierarchy *errorHierarchy, const QString &key, const std::function<bool (const QJsonValue &)> &predicate) const { const bool valid = predicate(m_jsonObject.value(key)); if (!valid && errorHierarchy) - errorHierarchy->append(key); + errorHierarchy->prependMember(key); return valid; } @@ -106,11 +106,11 @@ QString JsonObject::errorString(QJsonValue::Type expected, QJsonValue::Type actu bool JsonObject::checkType(QJsonValue::Type type, QJsonValue::Type expectedType, - QStringList *errorHierarchy) + ErrorHierarchy *errorHierarchy) { const bool ret = type == expectedType; if (!ret && errorHierarchy) - errorHierarchy->append(errorString(expectedType, type)); + errorHierarchy->setError(errorString(expectedType, type)); return ret; } diff --git a/src/libs/languageserverprotocol/jsonobject.h b/src/libs/languageserverprotocol/jsonobject.h index 3b7329881b..828a116b91 100644 --- a/src/libs/languageserverprotocol/jsonobject.h +++ b/src/libs/languageserverprotocol/jsonobject.h @@ -58,7 +58,7 @@ public: operator const QJsonObject&() const { return m_jsonObject; } - virtual bool isValid(QStringList * /*errorHierarchy*/) const { return true; } + virtual bool isValid(ErrorHierarchy * /*errorHierarchy*/) const { return true; } protected: using iterator = QJsonObject::iterator; @@ -100,27 +100,29 @@ protected: void insertArray(const QString &key, const QList<JsonObject> &array); // value checking - bool checkKey(QStringList *errorHierarchy, const QString &key, + bool checkKey(ErrorHierarchy *errorHierarchy, const QString &key, const std::function<bool(const QJsonValue &val)> &predicate) const; static QString valueTypeString(QJsonValue::Type type); static QString errorString(QJsonValue::Type expected, QJsonValue::Type type2); static bool checkType(QJsonValue::Type type, QJsonValue::Type expectedType, - QStringList *errorHierarchy); + ErrorHierarchy *errorHierarchy); template <typename T> - static bool checkVal(QStringList *errorHierarchy, const QJsonValue &val); + static bool checkVal(ErrorHierarchy *errorHierarchy, const QJsonValue &val); + template <typename T> + bool check(ErrorHierarchy *errorHierarchy, const QString &key) const; template <typename T1, typename T2, typename... Args> - bool check(QStringList *errorHierarchy, const QString &key) const; + bool checkVariant(ErrorHierarchy *errorHierarchy, const QString &key) const; template <typename T> - bool check(QStringList *errorHierarchy, const QString &key) const; + bool checkVariant(ErrorHierarchy *errorHierarchy, const QString &key) const; template <typename T> - bool checkArray(QStringList *errorHierarchy, const QString &key) const; + bool checkArray(ErrorHierarchy *errorHierarchy, const QString &key) const; template <typename T1, typename T2, typename... Args> - bool checkOptional(QStringList *errorHierarchy, const QString &key) const; + bool checkOptional(ErrorHierarchy *errorHierarchy, const QString &key) const; template <typename T> - bool checkOptional(QStringList *errorHierarchy, const QString &key) const; + bool checkOptional(ErrorHierarchy *errorHierarchy, const QString &key) const; template <typename T> - bool checkOptionalArray(QStringList *errorHierarchy, const QString &key) const; + bool checkOptionalArray(ErrorHierarchy *errorHierarchy, const QString &key) const; private: QJsonObject m_jsonObject; @@ -198,35 +200,51 @@ void JsonObject::insertArray(const QString &key, const QList<JsonObject> &array) } template <typename T> -bool JsonObject::checkVal(QStringList *errorHierarchy, const QJsonValue &val) +bool JsonObject::checkVal(ErrorHierarchy *errorHierarchy, const QJsonValue &val) { return checkType(val.type(), QJsonValue::Object, errorHierarchy) && T(val).isValid(errorHierarchy); } +template <typename T> +bool JsonObject::check(ErrorHierarchy *errorHierarchy, const QString &key) const +{ + return checkKey(errorHierarchy, key, [errorHierarchy](const QJsonValue &val) { + return checkVal<T>(errorHierarchy, val); + }); +} + template <typename T1, typename T2, typename... Args> -bool JsonObject::check(QStringList *errorHierarchy, const QString &key) const +bool JsonObject::checkVariant(ErrorHierarchy *errorHierarchy, const QString &key) const { - const QStringList errorBackUp = errorHierarchy ? *errorHierarchy : QStringList(); - if (check<T1>(errorHierarchy, key)) + if (checkVariant<T1>(errorHierarchy, key)) return true; - const bool ret = check<T2, Args...>(errorHierarchy, key); - if (ret && errorHierarchy) - *errorHierarchy = errorBackUp; - return ret; + if (checkVariant<T2, Args...>(errorHierarchy, key)) { + if (errorHierarchy) + errorHierarchy->clear(); + return true; + } + errorHierarchy->setError( + QCoreApplication::translate("LanguageServerProtocol::JsonObject", + "None of the following variants could be correctly parsed:")); + return false; } template <typename T> -bool JsonObject::check(QStringList *errorHierarchy, const QString &key) const +bool JsonObject::checkVariant(ErrorHierarchy *errorHierarchy, const QString &key) const { - return checkKey(errorHierarchy, key, [errorHierarchy](const QJsonValue &val){ - return checkVal<T>(errorHierarchy, val); - }); + if (!errorHierarchy) + return check<T>(nullptr, key); + ErrorHierarchy subError; + if (check<T>(&subError, key)) + return true; + errorHierarchy->addVariantHierachy(subError); + return false; } template <typename T> -bool JsonObject::checkArray(QStringList *errorHierarchy, const QString &key) const +bool JsonObject::checkArray(ErrorHierarchy *errorHierarchy, const QString &key) const { return checkKey(errorHierarchy, key, [errorHierarchy](const QJsonValue &val){ return val.isArray() && Utils::allOf(val.toArray(), [&errorHierarchy](const QJsonValue &value){ @@ -236,20 +254,27 @@ bool JsonObject::checkArray(QStringList *errorHierarchy, const QString &key) con } template <typename T1, typename T2, typename... Args> -bool JsonObject::checkOptional(QStringList *errorHierarchy, const QString &key) const +bool JsonObject::checkOptional(ErrorHierarchy *errorHierarchy, const QString &key) const { - const QStringList errorBackUp = errorHierarchy ? *errorHierarchy : QStringList(); - if (checkOptional<T1>(errorHierarchy, key)) + if (!contains(key)) return true; - const bool ret = checkOptional<T2, Args...>(errorHierarchy, key); - if (ret && errorHierarchy) - *errorHierarchy = errorBackUp; - return ret; + if (checkVariant<T1>(errorHierarchy, key)) + return true; + + if (checkVariant<T2, Args...>(errorHierarchy, key)) { + if (errorHierarchy) + errorHierarchy->clear(); + return true; + } + errorHierarchy->setError( + QCoreApplication::translate("LanguageServerProtocol::JsonObject", + "None of the following variants could be correctly parsed:")); + return false; } template <typename T> -bool JsonObject::checkOptional(QStringList *errorHierarchy, const QString &key) const +bool JsonObject::checkOptional(ErrorHierarchy *errorHierarchy, const QString &key) const { if (contains(key)) return check<T>(errorHierarchy, key); @@ -257,7 +282,7 @@ bool JsonObject::checkOptional(QStringList *errorHierarchy, const QString &key) } template <typename T> -bool JsonObject::checkOptionalArray(QStringList *errorHierarchy, const QString &key) const +bool JsonObject::checkOptionalArray(ErrorHierarchy *errorHierarchy, const QString &key) const { if (contains(key)) return checkArray<T>(errorHierarchy, key); @@ -265,31 +290,31 @@ bool JsonObject::checkOptionalArray(QStringList *errorHierarchy, const QString & } template <> -LANGUAGESERVERPROTOCOL_EXPORT bool JsonObject::checkVal<QString>(QStringList *errorHierarchy, +LANGUAGESERVERPROTOCOL_EXPORT bool JsonObject::checkVal<QString>(ErrorHierarchy *errorHierarchy, const QJsonValue &val); template <> -LANGUAGESERVERPROTOCOL_EXPORT bool JsonObject::checkVal<int>(QStringList *errorHierarchy, +LANGUAGESERVERPROTOCOL_EXPORT bool JsonObject::checkVal<int>(ErrorHierarchy *errorHierarchy, const QJsonValue &val); template <> -LANGUAGESERVERPROTOCOL_EXPORT bool JsonObject::checkVal<double>(QStringList *errorHierarchy, +LANGUAGESERVERPROTOCOL_EXPORT bool JsonObject::checkVal<double>(ErrorHierarchy *errorHierarchy, const QJsonValue &val); template <> -LANGUAGESERVERPROTOCOL_EXPORT bool JsonObject::checkVal<bool>(QStringList *errorHierarchy, +LANGUAGESERVERPROTOCOL_EXPORT bool JsonObject::checkVal<bool>(ErrorHierarchy *errorHierarchy, const QJsonValue &val); template <> -LANGUAGESERVERPROTOCOL_EXPORT bool JsonObject::checkVal<std::nullptr_t>(QStringList *errorHierarchy, +LANGUAGESERVERPROTOCOL_EXPORT bool JsonObject::checkVal<std::nullptr_t>(ErrorHierarchy *errorHierarchy, const QJsonValue &val); template<> -LANGUAGESERVERPROTOCOL_EXPORT bool JsonObject::checkVal<QJsonArray>(QStringList *errorHierarchy, +LANGUAGESERVERPROTOCOL_EXPORT bool JsonObject::checkVal<QJsonArray>(ErrorHierarchy *errorHierarchy, const QJsonValue &val); template<> -LANGUAGESERVERPROTOCOL_EXPORT bool JsonObject::checkVal<QJsonValue>(QStringList *errorHierarchy, +LANGUAGESERVERPROTOCOL_EXPORT bool JsonObject::checkVal<QJsonValue>(ErrorHierarchy *errorHierarchy, const QJsonValue &val); } // namespace LanguageServerProtocol diff --git a/src/libs/languageserverprotocol/jsonrpcmessages.h b/src/libs/languageserverprotocol/jsonrpcmessages.h index 473c9fe580..4dd4f7f900 100644 --- a/src/libs/languageserverprotocol/jsonrpcmessages.h +++ b/src/libs/languageserverprotocol/jsonrpcmessages.h @@ -119,10 +119,8 @@ public: virtual bool parametersAreValid(QString *errorMessage) const { - if (auto parameter = params()) { - QStringList error; - return parameter.value().isValid(&error); - } + if (auto parameter = params()) + return parameter.value().isValid(nullptr); if (errorMessage) *errorMessage = QCoreApplication::translate("LanguageServerProtocol::Notification", "No parameters in \"%1\".").arg(method()); @@ -180,7 +178,7 @@ public: void setData(const Error &data) { insert(dataKey, data); } void clearData() { remove(dataKey); } - bool isValid(QStringList *error) const override + bool isValid(ErrorHierarchy *error) const override { return check<int>(error, codeKey) && check<QString>(error, messageKey) @@ -332,12 +330,12 @@ public: MessageId id() const { return MessageId(value(idKey)); } void setId(const MessageId &id) { insert(idKey, id.toJson()); } - bool isValid(QStringList *error) const override + bool isValid(ErrorHierarchy *error) const override { if (MessageId(value(idKey)).isValid(error)) return true; if (error) - error->append(idKey); + error->prependMember(idKey); return false; } }; diff --git a/src/libs/languageserverprotocol/languagefeatures.cpp b/src/libs/languageserverprotocol/languagefeatures.cpp index 0af50c6fc5..d76f03f0b6 100644 --- a/src/libs/languageserverprotocol/languagefeatures.cpp +++ b/src/libs/languageserverprotocol/languagefeatures.cpp @@ -79,7 +79,7 @@ Utils::optional<MarkupOrString> ParameterInformation::documentation() const return MarkupOrString(documentation); } -bool SignatureHelp::isValid(QStringList *error) const +bool SignatureHelp::isValid(ErrorHierarchy *error) const { return checkArray<SignatureInformation>(error, signaturesKey); } @@ -118,12 +118,12 @@ void CodeActionParams::CodeActionContext::setOnly(const QList<CodeActionKind> &o insertArray(onlyKey, only); } -bool CodeActionParams::CodeActionContext::isValid(QStringList *error) const +bool CodeActionParams::CodeActionContext::isValid(ErrorHierarchy *error) const { return checkArray<Diagnostic>(error, diagnosticsKey); } -bool CodeActionParams::isValid(QStringList *error) const +bool CodeActionParams::isValid(ErrorHierarchy *error) const { return check<TextDocumentIdentifier>(error, textDocumentKey) && check<Range>(error, rangeKey) @@ -154,7 +154,7 @@ DocumentColorRequest::DocumentColorRequest(const DocumentColorParams ¶ms) : Request(methodName, params) { } -bool Color::isValid(QStringList *error) const +bool Color::isValid(ErrorHierarchy *error) const { return check<int>(error, redKey) && check<int>(error, greenKey) @@ -162,7 +162,7 @@ bool Color::isValid(QStringList *error) const && check<int>(error, alphaKey); } -bool ColorPresentationParams::isValid(QStringList *error) const +bool ColorPresentationParams::isValid(ErrorHierarchy *error) const { return check<TextDocumentIdentifier>(error, textDocumentKey) && check<Color>(error, colorInfoKey) @@ -201,7 +201,7 @@ void FormattingOptions::setProperty(const QString &key, const DocumentFormatting insert(key, *val); } -bool FormattingOptions::isValid(QStringList *error) const +bool FormattingOptions::isValid(ErrorHierarchy *error) const { return Utils::allOf(keys(), [this, &error](auto key){ return (key == tabSizeKey && this->check<int>(error, key)) @@ -210,7 +210,7 @@ bool FormattingOptions::isValid(QStringList *error) const }); } -bool DocumentFormattingParams::isValid(QStringList *error) const +bool DocumentFormattingParams::isValid(ErrorHierarchy *error) const { return check<TextDocumentIdentifier>(error, textDocumentKey) && check<FormattingOptions>(error, optionsKey); @@ -220,7 +220,7 @@ DocumentFormattingRequest::DocumentFormattingRequest(const DocumentFormattingPar : Request(methodName, params) { } -bool DocumentRangeFormattingParams::isValid(QStringList *error) const +bool DocumentRangeFormattingParams::isValid(ErrorHierarchy *error) const { return check<TextDocumentIdentifier>(error, textDocumentKey) && check<Range>(error, rangeKey) @@ -232,7 +232,7 @@ DocumentRangeFormattingRequest::DocumentRangeFormattingRequest( : Request(methodName, params) { } -bool DocumentOnTypeFormattingParams::isValid(QStringList *error) const +bool DocumentOnTypeFormattingParams::isValid(ErrorHierarchy *error) const { return check<TextDocumentIdentifier>(error, textDocumentKey) && check<Position>(error, positionKey) @@ -245,7 +245,7 @@ DocumentOnTypeFormattingRequest::DocumentOnTypeFormattingRequest( : Request(methodName, params) { } -bool RenameParams::isValid(QStringList *error) const +bool RenameParams::isValid(ErrorHierarchy *error) const { return check<TextDocumentIdentifier>(error, textDocumentKey) && check<Position>(error, positionKey) @@ -369,7 +369,7 @@ HoverContent::HoverContent(const QJsonValue &value) } } -bool HoverContent::isValid(QStringList *errorHierarchy) const +bool HoverContent::isValid(ErrorHierarchy *errorHierarchy) const { if (Utils::holds_alternative<MarkedString>(*this) || Utils::holds_alternative<MarkupContent>(*this) @@ -377,10 +377,10 @@ bool HoverContent::isValid(QStringList *errorHierarchy) const return true; } if (errorHierarchy) { - *errorHierarchy << QCoreApplication::translate( - "LanguageServerProtocol::HoverContent", - "HoverContent should be either MarkedString, " - "MarkupContent, or QList<MarkedString>."); + errorHierarchy->setError( + QCoreApplication::translate("LanguageServerProtocol::HoverContent", + "HoverContent should be either MarkedString, " + "MarkupContent, or QList<MarkedString>.")); } return false; } @@ -395,7 +395,7 @@ DocumentFormattingProperty::DocumentFormattingProperty(const QJsonValue &value) *this = value.toString(); } -bool DocumentFormattingProperty::isValid(QStringList *error) const +bool DocumentFormattingProperty::isValid(ErrorHierarchy *error) const { if (Utils::holds_alternative<bool>(*this) || Utils::holds_alternative<double>(*this) @@ -403,9 +403,9 @@ bool DocumentFormattingProperty::isValid(QStringList *error) const return true; } if (error) { - *error << QCoreApplication::translate( - "LanguageServerProtocol::MarkedString", - "DocumentFormattingProperty should be either bool, double, or QString."); + error->setError(QCoreApplication::translate( + "LanguageServerProtocol::MarkedString", + "DocumentFormattingProperty should be either bool, double, or QString.")); } return false; } @@ -433,7 +433,7 @@ CodeActionResult::CodeActionResult(const QJsonValue &val) emplace<std::nullptr_t>(nullptr); } -bool CodeAction::isValid(QStringList *error) const +bool CodeAction::isValid(ErrorHierarchy *error) const { return check<QString>(error, titleKey) && checkOptional<CodeActionKind>(error, codeActionKindKey) @@ -491,7 +491,7 @@ void SemanticHighlightToken::appendToByteArray(QByteArray &byteArray) const byteArray.append(char((scope & 0x00ff))); } -bool SemanticHighlightingParams::isValid(QStringList *error) const +bool SemanticHighlightingParams::isValid(ErrorHierarchy *error) const { return check<VersionedTextDocumentIdentifier>(error, textDocumentKey) && checkArray<SemanticHighlightingInformation>(error, linesKey); diff --git a/src/libs/languageserverprotocol/languagefeatures.h b/src/libs/languageserverprotocol/languagefeatures.h index bba54c48be..bee7cbd04f 100644 --- a/src/libs/languageserverprotocol/languagefeatures.h +++ b/src/libs/languageserverprotocol/languagefeatures.h @@ -54,7 +54,7 @@ public: QString value() const { return typedValue<QString>(valueKey); } void setValue(const QString &value) { insert(valueKey, value); } - bool isValid(QStringList *error) const override + bool isValid(ErrorHierarchy *error) const override { return check<QString>(error, languageKey) && check<QString>(error, valueKey); } }; @@ -83,7 +83,7 @@ public: explicit HoverContent(const QList<MarkedString> &other) : variant(other) {} explicit HoverContent(const MarkupContent &other) : variant(other) {} explicit HoverContent(const QJsonValue &value); - bool isValid(QStringList *errorHierarchy) const; + bool isValid(ErrorHierarchy *errorHierarchy) const; }; class LANGUAGESERVERPROTOCOL_EXPORT Hover : public JsonObject @@ -98,7 +98,7 @@ public: void setRange(const Range &range) { insert(rangeKey, range); } void clearRange() { remove(rangeKey); } - bool isValid(QStringList *error) const override + bool isValid(ErrorHierarchy *error) const override { return check<HoverContent>(error, contentsKey) && checkOptional<Range>(error, rangeKey); } }; @@ -128,7 +128,7 @@ public: { insert(documentationKey, documentation.toJson()); } void clearDocumentation() { remove(documentationKey); } - bool isValid(QStringList *error) const override + bool isValid(ErrorHierarchy *error) const override { return check<QString>(error, labelKey) && checkOptional<MarkupOrString>(error, documentationKey); @@ -194,7 +194,7 @@ public: void setActiveParameter(int activeParameter) { insert(activeParameterKey, activeParameter); } void clearActiveParameter() { remove(activeParameterKey); } - bool isValid(QStringList *error) const override; + bool isValid(ErrorHierarchy *error) const override; }; class LANGUAGESERVERPROTOCOL_EXPORT SignatureHelpRequest @@ -260,14 +260,14 @@ public: void setIncludeDeclaration(bool includeDeclaration) { insert(includeDeclarationKey, includeDeclaration); } - bool isValid(QStringList *error) const override + bool isValid(ErrorHierarchy *error) const override { return check<bool>(error, includeDeclarationKey); } }; ReferenceContext context() const { return typedValue<ReferenceContext>(contextKey); } void setContext(const ReferenceContext &context) { insert(contextKey, context); } - bool isValid(QStringList *error) const override + bool isValid(ErrorHierarchy *error) const override { return TextDocumentPositionParams::isValid(error) && check<ReferenceContext>(error, contextKey); } @@ -300,7 +300,7 @@ public: void setKind(int kind) { insert(kindKey, kind); } void clearKind() { remove(kindKey); } - bool isValid(QStringList *error) const override + bool isValid(ErrorHierarchy *error) const override { return check<Range>(error, rangeKey) && checkOptional<int>(error, kindKey); } }; @@ -336,7 +336,7 @@ public: void setTextDocument(const TextDocumentIdentifier &textDocument) { insert(textDocumentKey, textDocument); } - bool isValid(QStringList *error) const override + bool isValid(ErrorHierarchy *error) const override { return check<TextDocumentIdentifier>(error, textDocumentKey); } }; @@ -418,7 +418,7 @@ public: void setOnly(const QList<CodeActionKind> &only); void clearOnly() { remove(onlyKey); } - bool isValid(QStringList *error) const override; + bool isValid(ErrorHierarchy *error) const override; }; TextDocumentIdentifier textDocument() const @@ -432,7 +432,7 @@ public: CodeActionContext context() const { return typedValue<CodeActionContext>(contextKey); } void setContext(const CodeActionContext &context) { insert(contextKey, context); } - bool isValid(QStringList *error) const override; + bool isValid(ErrorHierarchy *error) const override; }; class LANGUAGESERVERPROTOCOL_EXPORT CodeAction : public JsonObject @@ -461,7 +461,7 @@ public: void setCommand(const Command &command) { insert(commandKey, command); } void clearCommand() { remove(commandKey); } - bool isValid(QStringList *) const override; + bool isValid(ErrorHierarchy *) const override; }; class LANGUAGESERVERPROTOCOL_EXPORT CodeActionResult @@ -499,7 +499,7 @@ public: void setData(const QJsonValue &data) { insert(dataKey, data); } void clearData() { remove(dataKey); } - bool isValid(QStringList *error) const override + bool isValid(ErrorHierarchy *error) const override { return check<Range>(error, rangeKey) && checkOptional<Command>(error, commandKey); } }; @@ -537,7 +537,7 @@ public: void setData(const QJsonValue &data) { insert(dataKey, data); } void clearData() { remove(dataKey); } - bool isValid(QStringList *error) const override + bool isValid(ErrorHierarchy *error) const override { return check<Range>(error, rangeKey) && checkOptional<QString>(error, targetKey); } }; @@ -580,7 +580,7 @@ public: double alpha() const { return typedValue<double>(alphaKey); } void setAlpha(double alpha) { insert(alphaKey, alpha); } - bool isValid(QStringList *error) const override; + bool isValid(ErrorHierarchy *error) const override; }; class LANGUAGESERVERPROTOCOL_EXPORT ColorInformation : public JsonObject @@ -594,7 +594,7 @@ public: Color color() const { return typedValue<Color>(colorKey); } void setColor(const Color &color) { insert(colorKey, color); } - bool isValid(QStringList *error) const override + bool isValid(ErrorHierarchy *error) const override { return check<Range>(error, rangeKey) && check<Color>(error, colorKey); } }; @@ -623,7 +623,7 @@ public: Range range() const { return typedValue<Range>(rangeKey); } void setRange(const Range &range) { insert(rangeKey, range); } - bool isValid(QStringList *error) const override; + bool isValid(ErrorHierarchy *error) const override; }; class LANGUAGESERVERPROTOCOL_EXPORT ColorPresentation : public JsonObject @@ -644,7 +644,7 @@ public: { insertArray(additionalTextEditsKey, additionalTextEdits); } void clearAdditionalTextEdits() { remove(additionalTextEditsKey); } - bool isValid(QStringList *error) const override + bool isValid(ErrorHierarchy *error) const override { return check<QString>(error, labelKey) && checkOptional<TextEdit>(error, textEditKey) @@ -672,7 +672,7 @@ public: using variant::variant; using variant::operator=; - bool isValid(QStringList *error) const; + bool isValid(ErrorHierarchy *error) const; }; class LANGUAGESERVERPROTOCOL_EXPORT FormattingOptions : public JsonObject @@ -690,7 +690,7 @@ public: void setProperty(const QString &key, const DocumentFormattingProperty &property); void removeProperty(const QString &key) { remove(key); } - bool isValid(QStringList *error) const override; + bool isValid(ErrorHierarchy *error) const override; }; class LANGUAGESERVERPROTOCOL_EXPORT DocumentFormattingParams : public JsonObject @@ -706,7 +706,7 @@ public: FormattingOptions options() const { return typedValue<FormattingOptions>(optionsKey); } void setOptions(const FormattingOptions &options) { insert(optionsKey, options); } - bool isValid(QStringList *error) const override; + bool isValid(ErrorHierarchy *error) const override; }; class LANGUAGESERVERPROTOCOL_EXPORT DocumentFormattingRequest : public Request< @@ -734,7 +734,7 @@ public: FormattingOptions options() const { return typedValue<FormattingOptions>(optionsKey); } void setOptions(const FormattingOptions &options) { insert(optionsKey, options); } - bool isValid(QStringList *error) const override; + bool isValid(ErrorHierarchy *error) const override; }; class LANGUAGESERVERPROTOCOL_EXPORT DocumentRangeFormattingRequest : public Request< @@ -765,7 +765,7 @@ public: FormattingOptions options() const { return typedValue<FormattingOptions>(optionsKey); } void setOptions(const FormattingOptions &options) { insert(optionsKey, options); } - bool isValid(QStringList *error) const override; + bool isValid(ErrorHierarchy *error) const override; }; class LANGUAGESERVERPROTOCOL_EXPORT DocumentOnTypeFormattingRequest : public Request< @@ -794,7 +794,7 @@ public: QString newName() const { return typedValue<QString>(newNameKey); } void setNewName(const QString &newName) { insert(newNameKey, newName); } - bool isValid(QStringList *error) const override; + bool isValid(ErrorHierarchy *error) const override; }; class LANGUAGESERVERPROTOCOL_EXPORT RenameRequest : public Request< @@ -832,7 +832,7 @@ public: void setTokens(const QList<SemanticHighlightToken> &tokens); void clearTokens() { remove(tokensKey); } - bool isValid(QStringList *error) const override + bool isValid(ErrorHierarchy *error) const override { return check<int>(error, lineKey) && checkOptional<QString>(error, tokensKey); } }; @@ -851,7 +851,7 @@ public: void setLines(const QList<SemanticHighlightingInformation> &lines) { insertArray(linesKey, lines); } - bool isValid(QStringList *error) const override; + bool isValid(ErrorHierarchy *error) const override; }; class LANGUAGESERVERPROTOCOL_EXPORT SemanticHighlightNotification diff --git a/src/libs/languageserverprotocol/lsptypes.cpp b/src/libs/languageserverprotocol/lsptypes.cpp index ac5c4224dd..2a34a53fc6 100644 --- a/src/libs/languageserverprotocol/lsptypes.cpp +++ b/src/libs/languageserverprotocol/lsptypes.cpp @@ -67,7 +67,7 @@ void Diagnostic::setCode(const Diagnostic::Code &code) insert(codeKey, *val); } -bool Diagnostic::isValid(QStringList *error) const +bool Diagnostic::isValid(ErrorHierarchy *error) const { return check<Range>(error, rangeKey) && checkOptional<int>(error, severityKey) @@ -130,13 +130,14 @@ MarkupOrString::MarkupOrString(const QJsonValue &val) } } -bool MarkupOrString::isValid(QStringList *error) const +bool MarkupOrString::isValid(ErrorHierarchy *error) const { if (Utils::holds_alternative<MarkupContent>(*this) || Utils::holds_alternative<QString>(*this)) return true; if (error) { - *error << QCoreApplication::translate("LanguageServerProtocoll::MarkupOrString", - "Expected a string or MarkupContent in MarkupOrString."); + error->setError( + QCoreApplication::translate("LanguageServerProtocoll::MarkupOrString", + "Expected a string or MarkupContent in MarkupOrString.")); } return false; } @@ -150,7 +151,7 @@ QJsonValue MarkupOrString::toJson() const return {}; } -bool SymbolInformation::isValid(QStringList *error) const +bool SymbolInformation::isValid(ErrorHierarchy *error) const { return check<QString>(error, nameKey) && check<int>(error, kindKey) @@ -158,13 +159,13 @@ bool SymbolInformation::isValid(QStringList *error) const && checkOptional<QString>(error, containerNameKey); } -bool TextDocumentEdit::isValid(QStringList *error) const +bool TextDocumentEdit::isValid(ErrorHierarchy *error) const { return check<VersionedTextDocumentIdentifier>(error, idKey) && checkArray<TextEdit>(error, editsKey); } -bool TextDocumentItem::isValid(QStringList *error) const +bool TextDocumentItem::isValid(ErrorHierarchy *error) const { return check<QString>(error, uriKey) && check<QString>(error, languageIdKey) @@ -305,7 +306,7 @@ TextDocumentPositionParams::TextDocumentPositionParams( setPosition(position); } -bool TextDocumentPositionParams::isValid(QStringList *error) const +bool TextDocumentPositionParams::isValid(ErrorHierarchy *error) const { return check<TextDocumentIdentifier>(error, textDocumentKey) && check<Position>(error, positionKey); @@ -387,7 +388,7 @@ bool DocumentFilter::applies(const Utils::FilePath &fileName, const Utils::MimeT return !contains(schemeKey) && !contains(languageKey) && !contains(patternKey); } -bool DocumentFilter::isValid(QStringList *error) const +bool DocumentFilter::isValid(ErrorHierarchy *error) const { return Utils::allOf(QStringList{languageKey, schemeKey, patternKey}, [this, &error](auto key){ return this->checkOptional<QString>(error, key); diff --git a/src/libs/languageserverprotocol/lsptypes.h b/src/libs/languageserverprotocol/lsptypes.h index 7910f26642..fa01862d8b 100644 --- a/src/libs/languageserverprotocol/lsptypes.h +++ b/src/libs/languageserverprotocol/lsptypes.h @@ -83,7 +83,7 @@ public: int character() const { return typedValue<int>(characterKey); } void setCharacter(int character) { insert(characterKey, character); } - bool isValid(QStringList *error) const override + bool isValid(ErrorHierarchy *error) const override { return check<int>(error, lineKey) && check<int>(error, characterKey); } int toPositionInDocument(QTextDocument *doc) const; @@ -115,7 +115,7 @@ public: bool contains(const Position &pos) const { return start() <= pos && pos <= end(); } bool overlaps(const Range &range) const; - bool isValid(QStringList *error) const override + bool isValid(ErrorHierarchy *error) const override { return check<Position>(error, startKey) && check<Position>(error, endKey); } }; @@ -133,7 +133,7 @@ public: Utils::Link toLink() const; - bool isValid(QStringList *error) const override + bool isValid(ErrorHierarchy *error) const override { return check<QString>(error, uriKey) && check<Range>(error, rangeKey); } }; @@ -180,7 +180,7 @@ public: { return typedValue<QString>(messageKey); } void setMessage(const QString &message) { insert(messageKey, message); } - bool isValid(QStringList *error) const override; + bool isValid(ErrorHierarchy *error) const override; }; class LANGUAGESERVERPROTOCOL_EXPORT Command : public JsonObject @@ -203,7 +203,7 @@ public: void setArguments(const QJsonArray &arguments) { insert(argumentsKey, arguments); } void clearArguments() { remove(argumentsKey); } - bool isValid(QStringList *error) const override + bool isValid(ErrorHierarchy *error) const override { return check<QString>(error, titleKey) && check<QString>(error, commandKey) && checkOptional<QJsonArray>(error, argumentsKey); } @@ -225,7 +225,7 @@ public: Utils::Text::Replacement toReplacement(QTextDocument *document) const; - bool isValid(QStringList *error) const override + bool isValid(ErrorHierarchy *error) const override { return check<Range>(error, rangeKey) && check<QString>(error, newTextKey); } }; @@ -240,7 +240,7 @@ public: DocumentUri uri() const { return DocumentUri::fromProtocol(typedValue<QString>(uriKey)); } void setUri(const DocumentUri &uri) { insert(uriKey, uri); } - bool isValid(QStringList *error) const override { return check<QString>(error, uriKey); } + bool isValid(ErrorHierarchy *error) const override { return check<QString>(error, uriKey); } }; class LANGUAGESERVERPROTOCOL_EXPORT VersionedTextDocumentIdentifier : public TextDocumentIdentifier @@ -258,8 +258,11 @@ public: LanguageClientValue<int> version() const { return clientValue<int>(versionKey); } void setVersion(LanguageClientValue<int> version) { insert(versionKey, version); } - bool isValid(QStringList *error) const override - { return TextDocumentIdentifier::isValid(error) && check<int, std::nullptr_t>(error, versionKey); } + bool isValid(ErrorHierarchy *error) const override + { + return TextDocumentIdentifier::isValid(error) + && checkVariant<int, std::nullptr_t>(error, versionKey); + } }; class LANGUAGESERVERPROTOCOL_EXPORT TextDocumentEdit : public JsonObject @@ -276,7 +279,7 @@ public: QList<TextEdit> edits() const { return array<TextEdit>(editsKey); } void setEdits(const QList<TextEdit> edits) { insertArray(editsKey, edits); } - bool isValid(QStringList *error) const override; + bool isValid(ErrorHierarchy *error) const override; }; class LANGUAGESERVERPROTOCOL_EXPORT WorkspaceEdit : public JsonObject @@ -303,7 +306,7 @@ public: void setDocumentChanges(const QList<TextDocumentEdit> &changes) { insertArray(changesKey, changes); } - bool isValid(QStringList *error) const override + bool isValid(ErrorHierarchy *error) const override { return checkOptionalArray<TextDocumentEdit>(error, documentChangesKey); } }; @@ -330,7 +333,7 @@ public: QString text() const { return typedValue<QString>(textKey); } void setText(const QString &text) { insert(textKey, text); } - bool isValid(QStringList *error) const override; + bool isValid(ErrorHierarchy *error) const override; static QString mimeTypeToLanguageId(const Utils::MimeType &mimeType); static QString mimeTypeToLanguageId(const QString &mimeTypeName); @@ -352,7 +355,7 @@ public: Position position() const { return typedValue<Position>(positionKey); } void setPosition(const Position &position) { insert(positionKey, position); } - bool isValid(QStringList *error) const override; + bool isValid(ErrorHierarchy *error) const override; }; class LANGUAGESERVERPROTOCOL_EXPORT DocumentFilter : public JsonObject @@ -378,7 +381,7 @@ public: bool applies(const Utils::FilePath &fileName, const Utils::MimeType &mimeType = Utils::MimeType()) const; - bool isValid(QStringList *error) const override; + bool isValid(ErrorHierarchy *error) const override; }; class LANGUAGESERVERPROTOCOL_EXPORT MarkupKind @@ -414,7 +417,7 @@ public: QString content() const { return typedValue<QString>(contentKey); } void setContent(const QString &content) { insert(contentKey, content); } - bool isValid(QStringList *error) const override + bool isValid(ErrorHierarchy *error) const override { return check<MarkupKind>(error, kindKey) && check<QString>(error, contentKey); } }; @@ -427,7 +430,7 @@ public: explicit MarkupOrString(const MarkupContent &val); MarkupOrString(const QJsonValue &val); - bool isValid(QStringList *error) const; + bool isValid(ErrorHierarchy *error) const; QJsonValue toJson() const; }; @@ -447,7 +450,7 @@ public: QString name() const { return typedValue<QString>(nameKey); } void setName(const QString &name) { insert(nameKey, name); } - bool isValid(QStringList *error) const override + bool isValid(ErrorHierarchy *error) const override { return check<QString>(error, uriKey) && check<QString>(error, nameKey); } }; @@ -474,7 +477,7 @@ public: void setContainerName(const QString &containerName) { insert(containerNameKey, containerName); } void clearContainerName() { remove(containerNameKey); } - bool isValid(QStringList *error) const override; + bool isValid(ErrorHierarchy *error) const override; }; class LANGUAGESERVERPROTOCOL_EXPORT DocumentSymbol : public JsonObject diff --git a/src/libs/languageserverprotocol/lsputils.cpp b/src/libs/languageserverprotocol/lsputils.cpp index aceeed7392..ecb78129cc 100644 --- a/src/libs/languageserverprotocol/lsputils.cpp +++ b/src/libs/languageserverprotocol/lsputils.cpp @@ -75,4 +75,34 @@ QJsonArray fromJsonValue<QJsonArray>(const QJsonValue &value) return value.toArray(); } +void ErrorHierarchy::clear() +{ + m_hierarchy.clear(); + m_children.clear(); + m_error.clear(); +} + +bool ErrorHierarchy::isEmpty() const +{ + return m_hierarchy.isEmpty() && m_children.isEmpty() && m_error.isEmpty(); +} + +QString ErrorHierarchy::toString() const +{ + if (m_error.isEmpty() && m_hierarchy.isEmpty()) + return {}; + QString error = m_hierarchy.join(" > ") + ": " + m_error; + if (!m_children.isEmpty()) { + error.append("\n\t"); + error.append(Utils::transform(m_children, &ErrorHierarchy::toString).join("\n\t")); + } + return error; +} + +bool ErrorHierarchy::operator==(const ErrorHierarchy &other) const +{ + return m_hierarchy == other.m_hierarchy && m_children == other.m_children + && m_error == other.m_error; +} + } // namespace LanguageServerProtocol diff --git a/src/libs/languageserverprotocol/lsputils.h b/src/libs/languageserverprotocol/lsputils.h index 4646f181e9..8da5fdd93a 100644 --- a/src/libs/languageserverprotocol/lsputils.h +++ b/src/libs/languageserverprotocol/lsputils.h @@ -165,4 +165,24 @@ QList<T> jsonArrayToList(const QJsonArray &array) return list; } +class LANGUAGESERVERPROTOCOL_EXPORT ErrorHierarchy +{ +public: + ErrorHierarchy() = default; + + void setError(const QString &error) { m_error = error; } + void prependMember(const QString &member) { m_hierarchy.prepend(member); } + void addVariantHierachy(const ErrorHierarchy &subError) { m_children.append(subError); } + void clear(); + + bool isEmpty() const; + QString toString() const; + + bool operator==(const ErrorHierarchy &other) const; +private: + QStringList m_hierarchy; + QList<ErrorHierarchy> m_children; + QString m_error; +}; + } // namespace LanguageClient diff --git a/src/libs/languageserverprotocol/messages.cpp b/src/libs/languageserverprotocol/messages.cpp index 6e02e5180e..149428b01a 100644 --- a/src/libs/languageserverprotocol/messages.cpp +++ b/src/libs/languageserverprotocol/messages.cpp @@ -50,7 +50,7 @@ TelemetryNotification::TelemetryNotification() : Notification(methodName) { } -bool ShowMessageRequestParams::isValid(QStringList *error) const +bool ShowMessageRequestParams::isValid(ErrorHierarchy *error) const { return ShowMessageParams::isValid(error) && checkOptionalArray<MessageActionItem>(error, actionsKey); diff --git a/src/libs/languageserverprotocol/messages.h b/src/libs/languageserverprotocol/messages.h index 1285ea82a9..0672ad2cc7 100644 --- a/src/libs/languageserverprotocol/messages.h +++ b/src/libs/languageserverprotocol/messages.h @@ -49,7 +49,7 @@ public: QString toString() const; - bool isValid(QStringList *error) const override + bool isValid(ErrorHierarchy *error) const override { return check<int>(error, typeKey) && check<QString>(error, messageKey); } }; @@ -70,7 +70,7 @@ public: QString title() const { return typedValue<QString>(titleKey); } void setTitle(QString title) { insert(titleKey, title); } - bool isValid(QStringList *error) const override { return check<QString>(error, titleKey); } + bool isValid(ErrorHierarchy *error) const override { return check<QString>(error, titleKey); } }; class LANGUAGESERVERPROTOCOL_EXPORT ShowMessageRequestParams : public ShowMessageParams @@ -83,7 +83,7 @@ public: void setActions(const QList<MessageActionItem> &actions) { insertArray(actionsKey, actions); } void clearActions() { remove(actionsKey); } - bool isValid(QStringList *error) const override; + bool isValid(ErrorHierarchy *error) const override; }; class LANGUAGESERVERPROTOCOL_EXPORT ShowMessageRequest : public Request< diff --git a/src/libs/languageserverprotocol/servercapabilities.cpp b/src/libs/languageserverprotocol/servercapabilities.cpp index a000ad2c89..5d4574e64b 100644 --- a/src/libs/languageserverprotocol/servercapabilities.cpp +++ b/src/libs/languageserverprotocol/servercapabilities.cpp @@ -149,7 +149,7 @@ void ServerCapabilities::setColorProvider(Utils::variant<bool, JsonObject> color insert(renameProviderKey, Utils::get<JsonObject>(colorProvider)); } -bool ServerCapabilities::isValid(QStringList *error) const +bool ServerCapabilities::isValid(ErrorHierarchy *error) const { return checkOptional<TextDocumentSyncOptions, int>(error, textDocumentSyncKey) && checkOptional<bool>(error, hoverProviderKey) @@ -194,7 +194,7 @@ void ServerCapabilities::WorkspaceServerCapabilities::WorkspaceFoldersCapabiliti insert(changeNotificationsKey, *val); } -bool ServerCapabilities::WorkspaceServerCapabilities::WorkspaceFoldersCapabilities::isValid(QStringList *error) const +bool ServerCapabilities::WorkspaceServerCapabilities::WorkspaceFoldersCapabilities::isValid(ErrorHierarchy *error) const { return checkOptional<bool>(error, supportedKey) && checkOptional<QString, bool>(error, changeNotificationsKey); @@ -211,7 +211,7 @@ bool TextDocumentRegistrationOptions::filterApplies(const Utils::FilePath &fileN }); } -bool TextDocumentSyncOptions::isValid(QStringList *error) const +bool TextDocumentSyncOptions::isValid(ErrorHierarchy *error) const { return checkOptional<bool>(error, openCloseKey) && checkOptional<int>(error, changeKey) @@ -252,7 +252,7 @@ void ServerCapabilities::SemanticHighlightingServerCapabilities::setScopes( insert(scopesKey, jsonScopes); } -bool ServerCapabilities::SemanticHighlightingServerCapabilities::isValid(QStringList *) const +bool ServerCapabilities::SemanticHighlightingServerCapabilities::isValid(ErrorHierarchy *) const { return contains(scopesKey) && value(scopesKey).isArray() && Utils::allOf(value(scopesKey).toArray(), [](const QJsonValue &array) { diff --git a/src/libs/languageserverprotocol/servercapabilities.h b/src/libs/languageserverprotocol/servercapabilities.h index 7365449b0f..5e7d67ea91 100644 --- a/src/libs/languageserverprotocol/servercapabilities.h +++ b/src/libs/languageserverprotocol/servercapabilities.h @@ -38,7 +38,7 @@ public: void setResolveProvider(bool resolveProvider) { insert(resolveProviderKey, resolveProvider); } void clearResolveProvider() { remove(resolveProviderKey); } - bool isValid(QStringList *error) const override + bool isValid(ErrorHierarchy *error) const override { return checkOptional<bool>(error, resolveProviderKey); } }; @@ -55,7 +55,7 @@ public: bool filterApplies(const Utils::FilePath &fileName, const Utils::MimeType &mimeType = Utils::MimeType()) const; - bool isValid(QStringList *error) const override + bool isValid(ErrorHierarchy *error) const override { return checkArray<DocumentFilter>(error, documentSelectorKey); } }; @@ -69,7 +69,7 @@ public: void setIncludeText(bool includeText) { insert(includeTextKey, includeText); } void clearIncludeText() { remove(includeTextKey); } - bool isValid(QStringList *error) const override + bool isValid(ErrorHierarchy *error) const override { return checkOptional<bool>(error, includeTextKey); } }; @@ -106,7 +106,7 @@ public: void setSave(const SaveOptions &save) { insert(saveKey, save); } void clearSave() { remove(saveKey); } - bool isValid(QStringList *error) const override; + bool isValid(ErrorHierarchy *error) const override; }; enum class TextDocumentSyncKind @@ -129,7 +129,7 @@ public: void setCodeActionKinds(const QList<QString> &codeActionKinds) { insertArray(codeActionKindsKey, codeActionKinds); } - bool isValid(QStringList *error) const override + bool isValid(ErrorHierarchy *error) const override { return checkArray<QString>(error, codeActionKindsKey); } }; @@ -152,7 +152,7 @@ public: { insertArray(triggerCharactersKey, triggerCharacters); } void clearTriggerCharacters() { remove(triggerCharactersKey); } - bool isValid(QStringList *error) const override + bool isValid(ErrorHierarchy *error) const override { return checkOptionalArray<QString>(error, triggerCharactersKey); } }; @@ -188,7 +188,7 @@ public: { insertArray(moreTriggerCharacterKey, moreTriggerCharacter); } void clearMoreTriggerCharacter() { remove(moreTriggerCharacterKey); } - bool isValid(QStringList *error) const override + bool isValid(ErrorHierarchy *error) const override { return check<QString>(error, firstTriggerCharacterKey) && checkOptionalArray<QString>(error, moreTriggerCharacterKey); @@ -205,7 +205,7 @@ public: QList<QString> commands() const { return array<QString>(commandsKey); } void setCommands(const QList<QString> &commands) { insertArray(commandsKey, commands); } - bool isValid(QStringList *error) const override + bool isValid(ErrorHierarchy *error) const override { return checkArray<QString>(error, commandsKey); } }; @@ -231,7 +231,7 @@ public: Utils::optional<QList<QList<QString>>> scopes() const; void setScopes(const QList<QList<QString>> &scopes); - bool isValid(QStringList *) const override; + bool isValid(ErrorHierarchy *) const override; }; // Defines how text documents are synced. Is either a detailed structure defining each @@ -288,7 +288,7 @@ public: void setId(const QString &id) { insert(idKey, id); } void clearId() { remove(idKey); } - bool isValid(QStringList *error) const override + bool isValid(ErrorHierarchy *error) const override { return checkArray<DocumentFilter>(error, documentSelectorKey) && checkOptional<bool>(error, idKey); } }; @@ -367,7 +367,7 @@ public: void setPrepareProvider(bool prepareProvider) { insert(prepareProviderKey, prepareProvider); } void clearPrepareProvider() { remove(prepareProviderKey); } - bool isValid(QStringList * error) const override + bool isValid(ErrorHierarchy * error) const override { return checkOptional<bool>(error, prepareProviderKey); } }; @@ -414,7 +414,7 @@ public: void setChangeNotifications(Utils::variant<QString, bool> changeNotifications); void clearChangeNotifications() { remove(changeNotificationsKey); } - bool isValid(QStringList *error) const override; + bool isValid(ErrorHierarchy *error) const override; }; Utils::optional<WorkspaceFoldersCapabilities> workspaceFolders() const @@ -440,7 +440,7 @@ public: { insert(semanticHighlightingKey, semanticHighlighting); } void clearSemanticHighlighting() { remove(semanticHighlightingKey); } - bool isValid(QStringList *error) const override; + bool isValid(ErrorHierarchy *error) const override; }; } // namespace LanguageClient diff --git a/src/libs/languageserverprotocol/textsynchronization.cpp b/src/libs/languageserverprotocol/textsynchronization.cpp index e352921fba..a8760eeae5 100644 --- a/src/libs/languageserverprotocol/textsynchronization.cpp +++ b/src/libs/languageserverprotocol/textsynchronization.cpp @@ -74,7 +74,7 @@ DidChangeTextDocumentParams::DidChangeTextDocumentParams( setContentChanges({text}); } -bool DidChangeTextDocumentParams::isValid(QStringList *error) const +bool DidChangeTextDocumentParams::isValid(ErrorHierarchy *error) const { return check<VersionedTextDocumentIdentifier>(error, textDocumentKey) && checkArray<TextDocumentContentChangeEvent>(error, contentChangesKey); @@ -96,7 +96,7 @@ DidChangeTextDocumentParams::TextDocumentContentChangeEvent::TextDocumentContent setText(text); } -bool DidChangeTextDocumentParams::TextDocumentContentChangeEvent::isValid(QStringList *error) const +bool DidChangeTextDocumentParams::TextDocumentContentChangeEvent::isValid(ErrorHierarchy *error) const { return checkOptional<Range>(error, rangeKey) && checkOptional<int>(error, rangeLengthKey) @@ -108,7 +108,7 @@ DidSaveTextDocumentParams::DidSaveTextDocumentParams(const TextDocumentIdentifie setTextDocument(document); } -bool DidSaveTextDocumentParams::isValid(QStringList *error) const +bool DidSaveTextDocumentParams::isValid(ErrorHierarchy *error) const { return check<TextDocumentIdentifier>(error, textDocumentKey) && checkOptional<QString>(error, textKey); @@ -122,13 +122,13 @@ WillSaveTextDocumentParams::WillSaveTextDocumentParams( setReason(reason); } -bool WillSaveTextDocumentParams::isValid(QStringList *error) const +bool WillSaveTextDocumentParams::isValid(ErrorHierarchy *error) const { return check<TextDocumentIdentifier>(error, textDocumentKey) && check<int>(error, reasonKey); } -bool TextDocumentSaveRegistrationOptions::isValid(QStringList *error) const +bool TextDocumentSaveRegistrationOptions::isValid(ErrorHierarchy *error) const { return TextDocumentRegistrationOptions::isValid(error) && checkOptional<bool>(error, includeTextKey); diff --git a/src/libs/languageserverprotocol/textsynchronization.h b/src/libs/languageserverprotocol/textsynchronization.h index fa81cae51a..dbb3311ad9 100644 --- a/src/libs/languageserverprotocol/textsynchronization.h +++ b/src/libs/languageserverprotocol/textsynchronization.h @@ -40,7 +40,7 @@ public: TextDocumentItem textDocument() const { return typedValue<TextDocumentItem>(textDocumentKey); } void setTextDocument(TextDocumentItem textDocument) { insert(textDocumentKey, textDocument); } - bool isValid(QStringList *error) const override + bool isValid(ErrorHierarchy *error) const override { return check<TextDocumentItem>(error, textDocumentKey); } }; @@ -67,7 +67,7 @@ public: void setSyncKind(TextDocumentSyncKind syncKind) { insert(syncKindKey, static_cast<int>(syncKind)); } - bool isValid(QStringList *error) const override { return check<int>(error, syncKindKey); } + bool isValid(ErrorHierarchy *error) const override { return check<int>(error, syncKindKey); } }; class LANGUAGESERVERPROTOCOL_EXPORT DidChangeTextDocumentParams : public JsonObject @@ -108,7 +108,7 @@ public: QString text() const { return typedValue<QString>(textKey); } void setText(const QString &text) { insert(textKey, text); } - bool isValid(QStringList *error) const override; + bool isValid(ErrorHierarchy *error) const override; }; QList<TextDocumentContentChangeEvent> contentChanges() const @@ -116,7 +116,7 @@ public: void setContentChanges(const QList<TextDocumentContentChangeEvent> &contentChanges) { insertArray(contentChangesKey, contentChanges); } - bool isValid(QStringList *error) const override; + bool isValid(ErrorHierarchy *error) const override; }; class LANGUAGESERVERPROTOCOL_EXPORT DidChangeTextDocumentNotification : public Notification< @@ -151,7 +151,7 @@ public: { return static_cast<TextDocumentSaveReason>(typedValue<int>(reasonKey)); } void setReason(TextDocumentSaveReason reason) { insert(reasonKey, static_cast<int>(reason)); } - bool isValid(QStringList *error) const override; + bool isValid(ErrorHierarchy *error) const override; }; class LANGUAGESERVERPROTOCOL_EXPORT WillSaveTextDocumentNotification : public Notification< @@ -184,7 +184,7 @@ public: void setIncludeText(bool includeText) { insert(includeTextKey, includeText); } void clearIncludeText() { remove(includeTextKey); } - bool isValid(QStringList *error) const override; + bool isValid(ErrorHierarchy *error) const override; }; class LANGUAGESERVERPROTOCOL_EXPORT DidSaveTextDocumentParams : public JsonObject @@ -203,7 +203,7 @@ public: void setText(const QString &text) { insert(textKey, text); } void clearText() { remove(textKey); } - bool isValid(QStringList *error) const override; + bool isValid(ErrorHierarchy *error) const override; }; class LANGUAGESERVERPROTOCOL_EXPORT DidSaveTextDocumentNotification : public Notification< @@ -228,7 +228,7 @@ public: void setTextDocument(const TextDocumentIdentifier &textDocument) { insert(textDocumentKey, textDocument); } - bool isValid(QStringList *error) const override + bool isValid(ErrorHierarchy *error) const override { return check<TextDocumentIdentifier>(error, textDocumentKey); } }; diff --git a/src/libs/languageserverprotocol/workspace.cpp b/src/libs/languageserverprotocol/workspace.cpp index e411878877..28af2cbafc 100644 --- a/src/libs/languageserverprotocol/workspace.cpp +++ b/src/libs/languageserverprotocol/workspace.cpp @@ -66,23 +66,24 @@ ApplyWorkspaceEditRequest::ApplyWorkspaceEditRequest(const ApplyWorkspaceEditPar : Request(methodName, params) { } -bool WorkspaceFoldersChangeEvent::isValid(QStringList *error) const +bool WorkspaceFoldersChangeEvent::isValid(ErrorHierarchy *error) const { return checkArray<WorkSpaceFolder>(error, addedKey) && checkArray<WorkSpaceFolder>(error, removedKey); } -bool ConfigurationParams::ConfigureationItem::isValid(QStringList *error) const +bool ConfigurationParams::ConfigureationItem::isValid(ErrorHierarchy *error) const { return checkOptional<QString>(error, scopeUriKey) && checkOptional<QString>(error, sectionKey); } -bool DidChangeConfigurationParams::isValid(QStringList *error) const +bool DidChangeConfigurationParams::isValid(ErrorHierarchy *error) const { if (contains(settingsKey)) return true; - *error << settingsKey; + if (error) + error->prependMember(settingsKey); return false; } diff --git a/src/libs/languageserverprotocol/workspace.h b/src/libs/languageserverprotocol/workspace.h index bf6a1b9096..dccd0c361a 100644 --- a/src/libs/languageserverprotocol/workspace.h +++ b/src/libs/languageserverprotocol/workspace.h @@ -60,7 +60,7 @@ public: QList<WorkSpaceFolder> removed() const { return array<WorkSpaceFolder>(removedKey); } void setRemoved(const QList<WorkSpaceFolder> &removed) { insertArray(removedKey, removed); } - bool isValid(QStringList *error) const override; + bool isValid(ErrorHierarchy *error) const override; }; class LANGUAGESERVERPROTOCOL_EXPORT DidChangeWorkspaceFoldersParams : public JsonObject @@ -72,7 +72,7 @@ public: { return typedValue<WorkspaceFoldersChangeEvent>(eventKey); } void setEvent(const WorkspaceFoldersChangeEvent &event) { insert(eventKey, event); } - bool isValid(QStringList *error) const override + bool isValid(ErrorHierarchy *error) const override { return check<WorkspaceFoldersChangeEvent>(error, eventKey); } }; @@ -94,7 +94,7 @@ public: QJsonValue settings() const { return typedValue<QJsonValue>(settingsKey); } void setSettings(QJsonValue settings) { insert(settingsKey, settings); } - bool isValid(QStringList *error) const override; + bool isValid(ErrorHierarchy *error) const override; }; class LANGUAGESERVERPROTOCOL_EXPORT DidChangeConfigurationNotification : public Notification< @@ -124,13 +124,13 @@ public: void setSection(const QString §ion) { insert(sectionKey, section); } void clearSection() { remove(sectionKey); } - bool isValid(QStringList *error) const override; + bool isValid(ErrorHierarchy *error) const override; }; QList<ConfigureationItem> items() const { return array<ConfigureationItem>(itemsKey); } void setItems(const QList<ConfigureationItem> &items) { insertArray(itemsKey, items); } - bool isValid(QStringList *error) const override + bool isValid(ErrorHierarchy *error) const override { return checkArray<ConfigureationItem>(error, itemsKey); } }; @@ -165,14 +165,14 @@ public: Deleted = 3 }; - bool isValid(QStringList *error) const override + bool isValid(ErrorHierarchy *error) const override { return check<QString>(error, uriKey) && check<int>(error, typeKey); } }; QList<FileEvent> changes() const { return array<FileEvent>(changesKey); } void setChanges(const QList<FileEvent> &changes) { insertArray(changesKey, changes); } - bool isValid(QStringList *error) const override + bool isValid(ErrorHierarchy *error) const override { return checkArray<FileEvent>(error, changesKey); } }; @@ -193,7 +193,7 @@ public: QString query() const { return typedValue<QString>(queryKey); } void setQuery(const QString &query) { insert(queryKey, query); } - bool isValid(QStringList *error) const override { return check<QString>(error, queryKey); } + bool isValid(ErrorHierarchy *error) const override { return check<QString>(error, queryKey); } }; class LANGUAGESERVERPROTOCOL_EXPORT WorkspaceSymbolRequest : public Request< @@ -220,7 +220,7 @@ public: void setArguments(const QJsonArray &arguments) { insert(argumentsKey, arguments); } void clearArguments() { remove(argumentsKey); } - bool isValid(QStringList *error) const override + bool isValid(ErrorHierarchy *error) const override { return check<QString>(error, commandKey) && checkOptionalArray<QJsonValue>(error, argumentsKey); @@ -248,7 +248,7 @@ public: WorkspaceEdit edit() const { return typedValue<WorkspaceEdit>(editKey); } void setEdit(const WorkspaceEdit &edit) { insert(editKey, edit); } - bool isValid(QStringList *error) const override + bool isValid(ErrorHierarchy *error) const override { return check<WorkspaceEdit>(error, editKey) && checkOptional<QString>(error, labelKey); } }; @@ -260,7 +260,7 @@ public: bool applied() const { return typedValue<bool>(appliedKey); } void setApplied(bool applied) { insert(appliedKey, applied); } - bool isValid(QStringList *error) const override { return check<bool>(error, appliedKey); } + bool isValid(ErrorHierarchy *error) const override { return check<bool>(error, appliedKey); } }; class LANGUAGESERVERPROTOCOL_EXPORT ApplyWorkspaceEditRequest : public Request< diff --git a/src/plugins/android/android.qbs b/src/plugins/android/android.qbs index b7cbfb2cce..0162ed096d 100644 --- a/src/plugins/android/android.qbs +++ b/src/plugins/android/android.qbs @@ -78,6 +78,8 @@ Project { "androidrunner.h", "androidrunnerworker.cpp", "androidrunnerworker.h", + "androidsdkdownloader.cpp", + "androidsdkdownloader.h", "androidsdkmanager.cpp", "androidsdkmanager.h", "androidsdkmanagerwidget.cpp", diff --git a/src/plugins/languageclient/client.cpp b/src/plugins/languageclient/client.cpp index 50e743f71a..cafad5f89c 100644 --- a/src/plugins/languageclient/client.cpp +++ b/src/plugins/languageclient/client.cpp @@ -1054,33 +1054,41 @@ void Client::handleResponse(const MessageId &id, const QByteArray &content, QTex void Client::handleMethod(const QString &method, MessageId id, const IContent *content) { - QStringList error; - bool paramsValid = true; + ErrorHierarchy error; + auto logError = [&](const JsonObject &content) { + log(QJsonDocument(content).toJson(QJsonDocument::Indented) + '\n' + + tr("Invalid parameter in \"%1\": %2").arg(method, error.toString()), + Core::MessageManager::Flash); + }; + if (method == PublishDiagnosticsNotification::methodName) { auto params = dynamic_cast<const PublishDiagnosticsNotification *>(content)->params().value_or(PublishDiagnosticsParams()); - paramsValid = params.isValid(&error); - if (paramsValid) + if (params.isValid(&error)) handleDiagnostics(params); + else + logError(params); } else if (method == LogMessageNotification::methodName) { auto params = dynamic_cast<const LogMessageNotification *>(content)->params().value_or(LogMessageParams()); - paramsValid = params.isValid(&error); - if (paramsValid) + if (params.isValid(&error)) log(params, Core::MessageManager::Flash); + else + logError(params); } else if (method == SemanticHighlightNotification::methodName) { auto params = dynamic_cast<const SemanticHighlightNotification *>(content)->params().value_or(SemanticHighlightingParams()); - paramsValid = params.isValid(&error); - if (paramsValid) + if (params.isValid(&error)) handleSemanticHighlight(params); + else + logError(params); } else if (method == ShowMessageNotification::methodName) { auto params = dynamic_cast<const ShowMessageNotification *>(content)->params().value_or(ShowMessageParams()); - paramsValid = params.isValid(&error); - if (paramsValid) + if (params.isValid(&error)) log(params); + else + logError(params); } else if (method == ShowMessageRequest::methodName) { auto request = dynamic_cast<const ShowMessageRequest *>(content); auto params = request->params().value_or(ShowMessageRequestParams()); - paramsValid = params.isValid(&error); - if (paramsValid) { + if (params.isValid(&error)) { showMessageBox(params, request->id()); } else { ShowMessageRequest::Response response(request->id()); @@ -1095,19 +1103,22 @@ void Client::handleMethod(const QString &method, MessageId id, const IContent *c } } else if (method == RegisterCapabilityRequest::methodName) { auto params = dynamic_cast<const RegisterCapabilityRequest *>(content)->params().value_or(RegistrationParams()); - paramsValid = params.isValid(&error); - if (paramsValid) + if (params.isValid(&error)) m_dynamicCapabilities.registerCapability(params.registrations()); + else + logError(params); } else if (method == UnregisterCapabilityRequest::methodName) { auto params = dynamic_cast<const UnregisterCapabilityRequest *>(content)->params().value_or(UnregistrationParams()); - paramsValid = params.isValid(&error); - if (paramsValid) + if (params.isValid(&error)) m_dynamicCapabilities.unregisterCapability(params.unregistrations()); + else + logError(params); } else if (method == ApplyWorkspaceEditRequest::methodName) { auto params = dynamic_cast<const ApplyWorkspaceEditRequest *>(content)->params().value_or(ApplyWorkspaceEditParams()); - paramsValid = params.isValid(&error); - if (paramsValid) + if (params.isValid(&error)) applyWorkspaceEdit(params.edit()); + else + logError(params); } else if (method == WorkSpaceFolderRequest::methodName) { WorkSpaceFolderRequest::Response response(dynamic_cast<const WorkSpaceFolderRequest *>(content)->id()); const QList<ProjectExplorer::Project *> projects @@ -1130,11 +1141,6 @@ void Client::handleMethod(const QString &method, MessageId id, const IContent *c response.setError(error); sendContent(response); } - std::reverse(error.begin(), error.end()); - if (!paramsValid) { - log(tr("Invalid parameter in \"%1\": %2").arg(method, error.join("->")), - Core::MessageManager::Flash); - } delete content; } @@ -1210,10 +1216,10 @@ void Client::initializeCallback(const InitializeRequest::Response &initResponse) log(tr("No initialize result.")); } else { const InitializeResult &result = _result.value(); - QStringList error; + ErrorHierarchy error; if (!result.isValid(&error)) { // continue on ill formed result - std::reverse(error.begin(), error.end()); - log(tr("Initialize result is not valid: ") + error.join("->")); + log(QJsonDocument(result).toJson(QJsonDocument::Indented) + '\n' + + tr("Initialize result is not valid: ") + error.toString()); } m_serverCapabilities = result.capabilities().value_or(ServerCapabilities()); diff --git a/src/plugins/mcusupport/mcusupportrunconfiguration.cpp b/src/plugins/mcusupport/mcusupportrunconfiguration.cpp index a52217e6bf..5ea78779eb 100644 --- a/src/plugins/mcusupport/mcusupportrunconfiguration.cpp +++ b/src/plugins/mcusupport/mcusupportrunconfiguration.cpp @@ -62,22 +62,28 @@ static QStringList flashAndRunArgs(const Target *target) return {"--build", ".", "--target", targetName}; } -FlashAndRunConfiguration::FlashAndRunConfiguration(Target *target, Core::Id id) - : RunConfiguration(target, id) +class FlashAndRunConfiguration final : public RunConfiguration { - auto flashAndRunParameters = addAspect<BaseStringAspect>(); - flashAndRunParameters->setLabelText("Flash and run CMake parameters:"); - flashAndRunParameters->setDisplayStyle(BaseStringAspect::TextEditDisplay); - flashAndRunParameters->setSettingsKey("FlashAndRunConfiguration.Parameters"); + Q_DECLARE_TR_FUNCTIONS(McuSupport::Internal::FlashAndRunConfiguration) - setUpdater([target, flashAndRunParameters] { - flashAndRunParameters->setValue(flashAndRunArgs(target).join(' ')); - }); +public: + FlashAndRunConfiguration(Target *target, Core::Id id) + : RunConfiguration(target, id) + { + auto flashAndRunParameters = addAspect<BaseStringAspect>(); + flashAndRunParameters->setLabelText(tr("Flash and run CMake parameters:")); + flashAndRunParameters->setDisplayStyle(BaseStringAspect::TextEditDisplay); + flashAndRunParameters->setSettingsKey("FlashAndRunConfiguration.Parameters"); - update(); + setUpdater([target, flashAndRunParameters] { + flashAndRunParameters->setValue(flashAndRunArgs(target).join(' ')); + }); - connect(target->project(), &Project::displayNameChanged, this, &RunConfiguration::update); -} + update(); + + connect(target->project(), &Project::displayNameChanged, this, &RunConfiguration::update); + } +}; class FlashAndRunWorker : public SimpleTargetRunner { diff --git a/src/plugins/mcusupport/mcusupportrunconfiguration.h b/src/plugins/mcusupport/mcusupportrunconfiguration.h index 704c8c9c90..3b0a138e0a 100644 --- a/src/plugins/mcusupport/mcusupportrunconfiguration.h +++ b/src/plugins/mcusupport/mcusupportrunconfiguration.h @@ -31,20 +31,12 @@ namespace McuSupport { namespace Internal { -class McuSupportRunConfigurationFactory : public ProjectExplorer::FixedRunConfigurationFactory +class McuSupportRunConfigurationFactory final : public ProjectExplorer::FixedRunConfigurationFactory { public: McuSupportRunConfigurationFactory(); }; -class FlashAndRunConfiguration : public ProjectExplorer::RunConfiguration -{ - Q_OBJECT - -public: - FlashAndRunConfiguration(ProjectExplorer::Target *target, Core::Id id); -}; - ProjectExplorer::RunWorkerFactory::WorkerCreator makeFlashAndRunWorker(); } // namespace Internal diff --git a/src/plugins/python/pythoneditor.cpp b/src/plugins/python/pythoneditor.cpp index eea74c1786..cfd8623363 100644 --- a/src/plugins/python/pythoneditor.cpp +++ b/src/plugins/python/pythoneditor.cpp @@ -53,9 +53,6 @@ PythonEditorFactory::PythonEditorFactory() setCommentDefinition(Utils::CommentDefinition::HashStyle); setParenthesesMatchingEnabled(true); setCodeFoldingSupported(true); - - connect(Core::EditorManager::instance(), &Core::EditorManager::documentOpened, - this, &PyLSConfigureAssistant::documentOpened); } } // namespace Internal diff --git a/src/plugins/python/pythonplugin.cpp b/src/plugins/python/pythonplugin.cpp index 63d7c663c2..cfc195acb2 100644 --- a/src/plugins/python/pythonplugin.cpp +++ b/src/plugins/python/pythonplugin.cpp @@ -29,6 +29,7 @@ #include "pythonproject.h" #include "pythonsettings.h" #include "pythonrunconfiguration.h" +#include "pythonutils.h" #include <coreplugin/fileiconprovider.h> @@ -105,6 +106,9 @@ void PythonPlugin::extensionsInitialized() Core::FileIconProvider::registerIconOverlayForSuffix(imageFile, "py"); TaskHub::addCategory(PythonErrorTaskCategory, "Python", true); + + connect(Core::EditorManager::instance(), &Core::EditorManager::documentOpened, + this, &PyLSConfigureAssistant::documentOpened); } } // namespace Internal diff --git a/src/plugins/python/pythonutils.cpp b/src/plugins/python/pythonutils.cpp index 72ca189cf3..bc0309a302 100644 --- a/src/plugins/python/pythonutils.cpp +++ b/src/plugins/python/pythonutils.cpp @@ -444,6 +444,7 @@ PyLSConfigureAssistant::PyLSConfigureAssistant(QObject *parent) : QObject(parent) { Core::EditorManager::instance(); + connect(Core::EditorManager::instance(), &Core::EditorManager::documentClosed, this, diff --git a/src/plugins/qmldesigner/components/formeditor/formeditorview.cpp b/src/plugins/qmldesigner/components/formeditor/formeditorview.cpp index 8b4b0dc221..c6e0516e13 100644 --- a/src/plugins/qmldesigner/components/formeditor/formeditorview.cpp +++ b/src/plugins/qmldesigner/components/formeditor/formeditorview.cpp @@ -661,6 +661,9 @@ void FormEditorView::toggle3DViewEnabled(bool enabled) QTC_ASSERT(model(), return); QTC_ASSERT(rootModelNode().isValid(), return); + if (enabled == rootModelNode().hasAuxiliaryData("3d-view")) + return; + if (enabled) rootModelNode().setAuxiliaryData("3d-view", true); else diff --git a/src/plugins/qtsupport/qtkitinformation.cpp b/src/plugins/qtsupport/qtkitinformation.cpp index 7d8ada6480..1e4037c447 100644 --- a/src/plugins/qtsupport/qtkitinformation.cpp +++ b/src/plugins/qtsupport/qtkitinformation.cpp @@ -35,6 +35,8 @@ #include <coreplugin/icore.h> #include <projectexplorer/projectexplorerconstants.h> #include <projectexplorer/task.h> +#include <projectexplorer/toolchain.h> +#include <projectexplorer/toolchainmanager.h> #include <utils/algorithm.h> #include <utils/buildablehelperlibrary.h> #include <utils/macroexpander.h> @@ -207,9 +209,43 @@ void QtKitAspect::fix(ProjectExplorer::Kit *k) { QTC_ASSERT(QtVersionManager::isLoaded(), return); BaseQtVersion *version = qtVersion(k); - if (!version && qtVersionId(k) >= 0) { - qWarning("Qt version is no longer known, removing from kit \"%s\".", qPrintable(k->displayName())); - setQtVersionId(k, -1); + if (!version) { + if (qtVersionId(k) >= 0) { + qWarning("Qt version is no longer known, removing from kit \"%s\".", + qPrintable(k->displayName())); + setQtVersionId(k, -1); + } + return; + } + + // Set a matching toolchain if we don't have one. + if (ToolChainKitAspect::toolChain(k, ProjectExplorer::Constants::CXX_LANGUAGE_ID)) + return; + const QString spec = version->mkspec(); + const QList<ToolChain *> possibleTcs = ToolChainManager::toolChains( + [version](const ToolChain *t) { + return t->isValid() + && t->language() == Core::Id(ProjectExplorer::Constants::CXX_LANGUAGE_ID) + && version->qtAbis().contains(t->targetAbi()); + }); + if (!possibleTcs.isEmpty()) { + const QList<ToolChain *> goodTcs = Utils::filtered(possibleTcs, + [&spec](const ToolChain *t) { + return t->suggestedMkspecList().contains(spec); + }); + // Hack to prefer a tool chain from PATH (e.g. autodetected) over other matches. + // This improves the situation a bit if a cross-compilation tool chain has the + // same ABI as the host. + const Environment systemEnvironment = Environment::systemEnvironment(); + ToolChain *bestTc = Utils::findOrDefault(goodTcs, + [&systemEnvironment](const ToolChain *t) { + return systemEnvironment.path().contains(t->compilerCommand().parentDir()); + }); + if (!bestTc) { + bestTc = goodTcs.isEmpty() ? possibleTcs.last() : goodTcs.last(); + } + if (bestTc) + ToolChainKitAspect::setAllToolChainsToMatch(k, bestTc); } } diff --git a/src/plugins/vcsbase/basevcssubmiteditorfactory.cpp b/src/plugins/vcsbase/basevcssubmiteditorfactory.cpp index 704b43d2f5..b285f6453d 100644 --- a/src/plugins/vcsbase/basevcssubmiteditorfactory.cpp +++ b/src/plugins/vcsbase/basevcssubmiteditorfactory.cpp @@ -31,8 +31,6 @@ #include <coreplugin/actionmanager/actionmanager.h> #include <utils/qtcassert.h> -#include <QAction> - using namespace Core; namespace VcsBase { @@ -52,26 +50,28 @@ VcsSubmitEditorFactory::VcsSubmitEditorFactory setEditorCreator([this, editorCreator, parameters] { VcsBaseSubmitEditor *editor = editorCreator(); editor->setParameters(parameters); - editor->registerActions(m_undoAction, m_redoAction, m_submitAction, m_diffAction); + editor->registerActions(&m_undoAction, &m_redoAction, &m_submitAction, &m_diffAction); return editor; }); Context context(parameters.id); - m_undoAction = new QAction(tr("&Undo"), this); - ActionManager::registerAction(m_undoAction, Core::Constants::UNDO, context); + m_undoAction.setText(tr("&Undo")); + ActionManager::registerAction(&m_undoAction, Core::Constants::UNDO, context); - m_redoAction = new QAction(tr("&Redo"), this); - ActionManager::registerAction(m_redoAction, Core::Constants::REDO, context); + m_redoAction.setText(tr("&Redo")); + ActionManager::registerAction(&m_redoAction, Core::Constants::REDO, context); QTC_ASSERT(plugin, return); - m_submitAction = new QAction(VcsBaseSubmitEditor::submitIcon(), - plugin->commitDisplayName(), this); - Command *command = ActionManager::registerAction(m_submitAction, SUBMIT, context); + m_submitAction.setIcon(VcsBaseSubmitEditor::submitIcon()); + m_submitAction.setText(plugin->commitDisplayName()); + + Command *command = ActionManager::registerAction(&m_submitAction, SUBMIT, context); command->setAttribute(Command::CA_UpdateText); - connect(m_submitAction, &QAction::triggered, plugin, &VcsBasePluginPrivate::commitFromEditor); + QObject::connect(&m_submitAction, &QAction::triggered, plugin, &VcsBasePluginPrivate::commitFromEditor); - m_diffAction = new QAction(VcsBaseSubmitEditor::diffIcon(), tr("Diff &Selected Files"), this); - ActionManager::registerAction(m_diffAction, DIFF_SELECTED, context); + m_diffAction.setIcon(VcsBaseSubmitEditor::diffIcon()); + m_diffAction.setText(tr("Diff &Selected Files")); + ActionManager::registerAction(&m_diffAction, DIFF_SELECTED, context); } } // namespace VcsBase diff --git a/src/plugins/vcsbase/basevcssubmiteditorfactory.h b/src/plugins/vcsbase/basevcssubmiteditorfactory.h index 133d9fd0ff..f71d61bbbb 100644 --- a/src/plugins/vcsbase/basevcssubmiteditorfactory.h +++ b/src/plugins/vcsbase/basevcssubmiteditorfactory.h @@ -30,7 +30,8 @@ #include <coreplugin/editormanager/ieditorfactory.h> #include <functional> -QT_FORWARD_DECLARE_CLASS(QAction); +#include <QAction> +#include <QCoreApplication> namespace VcsBase { @@ -40,9 +41,10 @@ class VcsBasePluginPrivate; // Parametrizable base class for editor factories creating instances of // VcsBaseSubmitEditor subclasses. + class VCSBASE_EXPORT VcsSubmitEditorFactory : public Core::IEditorFactory { - Q_OBJECT + Q_DECLARE_TR_FUNCTIONS(VcsBase::VcsSubmitEditorFactory) public: typedef std::function<VcsBaseSubmitEditor *()> EditorCreator; @@ -52,10 +54,10 @@ public: VcsBasePluginPrivate *plugin); private: - QAction *m_submitAction = nullptr; - QAction *m_diffAction = nullptr; - QAction *m_undoAction = nullptr; - QAction *m_redoAction = nullptr; + QAction m_submitAction; + QAction m_diffAction; + QAction m_undoAction; + QAction m_redoAction; }; } // namespace VcsBase diff --git a/tests/auto/languageserverprotocol/tst_languageserverprotocol.cpp b/tests/auto/languageserverprotocol/tst_languageserverprotocol.cpp index 4efbacce88..cd2bdfd0d5 100644 --- a/tests/auto/languageserverprotocol/tst_languageserverprotocol.cpp +++ b/tests/auto/languageserverprotocol/tst_languageserverprotocol.cpp @@ -570,13 +570,19 @@ void tst_LanguageServerProtocol::jsonObject() QCOMPARE(obj.optionalClientArray<QString>("strings").value().toList(), QList<QString>({"foo", "bar"})); - QStringList errorHierarchy; + ErrorHierarchy errorHierarchy; QVERIFY(!obj.check<int>(&errorHierarchy, "doesNotExist")); - QCOMPARE(errorHierarchy, QStringList({obj.errorString(QJsonValue::Double, QJsonValue::Undefined), "doesNotExist"})); + ErrorHierarchy errorDoesNotExists; + errorDoesNotExists.setError(obj.errorString(QJsonValue::Double, QJsonValue::Undefined)); + errorDoesNotExists.prependMember("doesNotExist"); + QCOMPARE(errorHierarchy, errorDoesNotExists); errorHierarchy.clear(); QVERIFY(!obj.check<int>(&errorHierarchy, "bool")); - QCOMPARE(errorHierarchy, QStringList({obj.errorString(QJsonValue::Double, QJsonValue::Bool), "bool"})); + ErrorHierarchy errorWrongType; + errorWrongType.setError(obj.errorString(QJsonValue::Double, QJsonValue::Bool)); + errorWrongType.prependMember("bool"); + QCOMPARE(errorHierarchy, errorWrongType); errorHierarchy.clear(); QVERIFY(obj.check<int>(&errorHierarchy, "integer")); |