diff --git a/.github/workflows/build_cmake.yml b/.github/workflows/build_cmake.yml index d0c9124fb00..6f0223b578b 100644 --- a/.github/workflows/build_cmake.yml +++ b/.github/workflows/build_cmake.yml @@ -9,7 +9,7 @@ on: env: QT_VERSION: 6.7.1 MACOS_DEPLOYMENT_TARGET: 11.0 - CLANG_VERSION: 18.1.5 + CLANG_VERSION: 18.1.7 ELFUTILS_VERSION: 0.175 CMAKE_VERSION: 3.21.1 NINJA_VERSION: 1.10.2 diff --git a/cmake/QtCreatorAPI.cmake b/cmake/QtCreatorAPI.cmake index 786e2d85533..c0f61301111 100644 --- a/cmake/QtCreatorAPI.cmake +++ b/cmake/QtCreatorAPI.cmake @@ -1129,7 +1129,7 @@ function (add_qtc_lua_plugin name) qtc_copy_to_builddir(${name} FILES ${_arg_SOURCES} - DESTINATION ${IDE_PLUGIN_PATH}/lua-plugins + DESTINATION ${IDE_PLUGIN_PATH} ) if (NOT _arg_EXCLUDE_FROM_INSTALL) @@ -1138,7 +1138,7 @@ function (add_qtc_lua_plugin name) install( FILES ${CMAKE_CURRENT_SOURCE_DIR}/${SOURCE} - DESTINATION ${IDE_PLUGIN_PATH}/lua-plugins/${SOURCE_DIR} + DESTINATION ${IDE_PLUGIN_PATH}/${SOURCE_DIR} ) endforeach() endif() diff --git a/coin/instructions/common_environment.yaml b/coin/instructions/common_environment.yaml index 1410fa79e7e..bed851d11ed 100644 --- a/coin/instructions/common_environment.yaml +++ b/coin/instructions/common_environment.yaml @@ -7,7 +7,7 @@ instructions: variableValue: "RelWithDebInfo" - type: EnvironmentVariable variableName: LLVM_BASE_URL - variableValue: https://ci-files02-hki.ci.qt.io/packages/jenkins/qtcreator_libclang/libclang-release_18.1.5-based + variableValue: https://ci-files02-hki.ci.qt.io/packages/jenkins/qtcreator_libclang/libclang-release_18.1.7-based - type: EnvironmentVariable variableName: QTC_QT_BASE_URL variableValue: "https://ci-files02-hki.ci.qt.io/packages/jenkins/archive/qt/6.7/6.7.1-released/Qt" diff --git a/dist/changelog/changes-14.0.0.md b/dist/changelog/changes-14.0.0.md index 00ba593c720..03ca70c6284 100644 --- a/dist/changelog/changes-14.0.0.md +++ b/dist/changelog/changes-14.0.0.md @@ -13,6 +13,8 @@ the public Git repository. For example: General ------- +* Started work on supporting Lua based plugins (registering language servers, + actions, preferences, and wizards) * Added `Clear` and `Save Contents` to context menus of all output views * Locator * Added the option to show results relative to project root @@ -54,17 +56,22 @@ Editing ([QTCREATORBUG-10279](https://bugreports.qt.io/browse/QTCREATORBUG-10279)) * Clangd * Increased the minimum version to LLVM 17 - * Added an option for the index location + * Added the `Per-project index location` and `Per-session index location` + options in `Preferences` > `C++` > `Clangd` for setting the index location + for a project or session ([QTCREATORBUG-27346](https://bugreports.qt.io/browse/QTCREATORBUG-27346)) - * Made reparsing source files while editing header files optional + * Added the `Update dependent sources` option to make re-parsing source files + while editing header files optional ([QTCREATORBUG-29943](https://bugreports.qt.io/browse/QTCREATORBUG-29943)) * Fixed the handling of system headers ([QTCREATORBUG-30474](https://bugreports.qt.io/browse/QTCREATORBUG-30474)) * Built-in - * Added the option to disable the built-in indexer + * Added the `Enable indexing` option in `Preferences` > `C++` > `Code Model` + to turn off the built-in indexer ([QTCREATORBUG-29147](https://bugreports.qt.io/browse/QTCREATORBUG-29147)) - * Added an option for "statement macros" that are interpreted by the indenter - as complete statements that don't require a semicolon at the end + * Added the `Statement Macros` field in `Preferences` > `C++` > `Code Style` + for macros that the indenter interprets as complete statements that don't + require a semicolon at the end ([QTCREATORBUG-13640](https://bugreports.qt.io/browse/QTCREATORBUG-13640), [QTCREATORBUG-15069](https://bugreports.qt.io/browse/QTCREATORBUG-15069), [QTCREATORBUG-18789](https://bugreports.qt.io/browse/QTCREATORBUG-18789)) diff --git a/doc/qtcreator/images/qtcreator-code-style-built-in-indenter.webp b/doc/qtcreator/images/qtcreator-code-style-built-in-indenter.webp index f8eaa1dac52..eb85b20033f 100644 Binary files a/doc/qtcreator/images/qtcreator-code-style-built-in-indenter.webp and b/doc/qtcreator/images/qtcreator-code-style-built-in-indenter.webp differ diff --git a/doc/qtcreator/images/qtcreator-move-class-to-separate-files.webp b/doc/qtcreator/images/qtcreator-move-class-to-separate-files.webp new file mode 100644 index 00000000000..5a9540c25e9 Binary files /dev/null and b/doc/qtcreator/images/qtcreator-move-class-to-separate-files.webp differ diff --git a/doc/qtcreator/images/qtcreator-preferences-clangd.webp b/doc/qtcreator/images/qtcreator-preferences-clangd.webp index 6d363c02f93..26a205ae505 100644 Binary files a/doc/qtcreator/images/qtcreator-preferences-clangd.webp and b/doc/qtcreator/images/qtcreator-preferences-clangd.webp differ diff --git a/doc/qtcreator/images/qtcreator-preferences-code-model.webp b/doc/qtcreator/images/qtcreator-preferences-code-model.webp index 9cd9458fe57..2fa62d4fb6d 100644 Binary files a/doc/qtcreator/images/qtcreator-preferences-code-model.webp and b/doc/qtcreator/images/qtcreator-preferences-code-model.webp differ diff --git a/doc/qtcreator/images/qtcreator-projects-settings-clangd.webp b/doc/qtcreator/images/qtcreator-projects-settings-clangd.webp index d49b9403e01..2590e9c4e9d 100644 Binary files a/doc/qtcreator/images/qtcreator-projects-settings-clangd.webp and b/doc/qtcreator/images/qtcreator-projects-settings-clangd.webp differ diff --git a/doc/qtcreator/src/editors/creator-only/creator-clang-codemodel.qdoc b/doc/qtcreator/src/editors/creator-only/creator-clang-codemodel.qdoc index d8bba6edf62..ae81bdc3abd 100644 --- a/doc/qtcreator/src/editors/creator-only/creator-clang-codemodel.qdoc +++ b/doc/qtcreator/src/editors/creator-only/creator-clang-codemodel.qdoc @@ -162,7 +162,7 @@ \title Code Model - \brief Sets global preferences for the code model. + \brief Sets global preferences for the C++ code model. The code model offers services such as code completion, syntactic and semantic highlighting, and diagnostics. @@ -189,6 +189,10 @@ \li \uicontrol {Use built-in preprocessor to show pre-processed files} \li Uses the built-in preprocessor to show the pre-processed source file in the editor. + \row + \li \uicontrol {Enable indexing} + \li Turns on the built-in indexer. Clearing this checkbox severely limits + the capabilities of the code model. \row \li \uicontrol {Do not index files greater than} \li To avoid out-of-memory crashes caused by indexing huge source files @@ -243,9 +247,14 @@ version 14, or later. \li In the \uicontrol {Background indexing} field, select \uicontrol Off to use a faster, but less accurate built-in indexer than the one used - by default. You can set the indexing priority depending on whether + by default. Set the indexing priority depending on whether the accuracy of results or speed is more important to you during global symbol searches. + \li In \uicontrol {Per-project index location}, select the folder to + store the index files for each project. The \c {compile-commands.json} + file is also stored in this folder. + \li In \uicontrol {Per-session index location}, select the folder to + store the index files for each session. \li In \uicontrol {Header/source switch mode}, select the C/C++ backend for switching between header and source files. While the clangd implementation has more capabilities than the built-in @@ -254,6 +263,13 @@ \li By default, clangd attempts to use all unused cores. You can set a fixed number of cores to use in \uicontrol {Worker thread count}. Background indexing also uses this many worker threads. + \li Select \uicontrol {Insert header files on completion} to insert + header files when completing symbols. + \li Select \uicontrol {Update dependent sources} to re-parse all source + files that include a header file when editing the header file. This + can cause a heavy CPU load if the header file is included in many + source files. Clear this option to only re-parse the source files + when saving the header file. \li Set the number of \uicontrol {Completion results} if you regularly miss important results during code completion. Set it to 0 to remove the limit on the number of completion results. Setting this to 0 or a diff --git a/doc/qtcreator/src/editors/creator-only/creator-cpp-quick-fixes.qdoc b/doc/qtcreator/src/editors/creator-only/creator-cpp-quick-fixes.qdoc index b3bab5c7feb..1a38c359292 100644 --- a/doc/qtcreator/src/editors/creator-only/creator-cpp-quick-fixes.qdoc +++ b/doc/qtcreator/src/editors/creator-only/creator-cpp-quick-fixes.qdoc @@ -103,15 +103,182 @@ \li Create function declarations and definitions \endlist - The following table summarizes the quick fixes for C++ code. The - fix is available when the cursor is in the position described in the - Activation column. + The following tables summarize the quick fixes available for C++ code, + according to the cursor position. + + \section1 Block of Code Selected + + \table + \header + \li Quick Fix + \li Description + \row + \li Assign to Local Variable + \li Adds a local variable which stores the return value of a + function call or a new expression. For example, rewrites: + + \code + QString s; + s.toLatin1(); + \endcode + + as + + \code + QString s; + QByteArray latin1 = s.toLatin1(); + \endcode + + and + + \code + new Foo; + \endcode + + as + + \code + Foo * localFoo = new Foo; + \endcode + + By default, \QC uses the \c auto variable type when creating the + variable. To label the variable with its actual type, select + \preferences > \uicontrol C++ > \uicontrol {Quick Fixes} and + clear \uicontrol {Use type "auto" when creating new variables}. + + Also available for a function call. + \row + \li Extract Function + \li Moves the selected code to a new function and replaces the block + of code with a call to the new function. Enter a name for the + function in the \uicontrol {Extract Function Refactoring} + dialog. + \row + \li Extract Constant as Function Parameter + \li Replaces the selected literal and all its occurrences with the + function parameter \c{newParameter}, which has the original + literal as the default value. + \endtable + + \section1 Class + + The following quick fixes are available when the cursor is on the definition + of a class. + + \table + \header + \li Quick Fix + \li Description + \row + \li Create Implementations for Member Functions + \li Creates implementations for all member functions in one go. + In the \uicontrol {Member Function Implementations} dialog, + specify whether the member functions are generated + inline or outside the class. + \row + \li Generate Constructor + \li Creates a constructor for a class. + \row + \li Generate Missing Q_PROPERTY Members + \li Adds missing members to a \c Q_PROPERTY: + \list + \li \c read function + \li \c write function, if there is a WRITE + \li \c {onChanged} signal, if there is a NOTIFY + \li data member with the name \c {m_} + \endlist + \row + \li Insert Virtual Functions of Base Classes + \li Inserts declarations and the corresponding definitions inside or + outside the class or in an implementation file (if it exists). + For more information, see \l{Insert virtual functions}. + \row + \li Move All Function Definitions + \li Moves all function definitions to the implementation file or + outside the class. For example, rewrites: + \code + class Foo + { + void bar() + { + // do stuff here + } + void baz() + { + // do stuff here + } + }; + \endcode + + as + + \code + class Foo + { + void bar(); + void baz(); + }; + + void Foo::bar() { + // do stuff here + } + + void Foo::baz() { + // do stuff here + } + \endcode + \row + \li Move Class to a Dedicated Set of Source Files + \li Moves a class to separate header and source files. For more + information, see \l{Move classes to separate files}. + \row + \li Re-order Member Function Definitions According to Declaration Order + \li Re-orders method definitions in a .cpp file to follow the order of + method declarations in the corresponding .h file. + \endtable + + \section1 Class Member + + The following quick fixes are available when the cursor is on a member + variable in a class definition. + + \table + \header + \li Quick Fix + \li Description + \row + \li Generate Constant Q_PROPERTY and Missing Members + \li Generates a constant Q_PROPERTY and adds missing members + to it. + \row + \li Generate Getter + \li Creates a getter member function for a member variable. + \row + \li Generate Getter and Setter + \li Creates getter and setter member functions for a member + variable. + \row + \li Create Getter and Setter Member Functions + \li Creates either both getter and setter member functions for + member variables or only a getter or setter. + \row + \li Generate Q_PROPERTY and Missing Members + \li Generates a Q_PROPERTY and adds missing members to it. + \row + \li Generate Q_PROPERTY and Missing Members with Reset Function + \li Generates a Q_PROPERTY and adds missing members to it, with an + additional \c reset function. + \row + \li Generate Setter + \li Creates a setter member function for a member variable. + \endtable + + \section1 Control Statement \table \header \li Quick Fix \li Description - \li Activation \row \li Add Curly Braces \li Adds curly braces to an if statement that does not have a @@ -129,7 +296,10 @@ b; } \endcode - \li \c if + \row + \li Complete Switch Statement + \li Adds all possible cases to a switch statement of the type + \c enum. \row \li Move Declaration out of Condition \li Moves a declaration out of an if or while condition to simplify @@ -145,7 +315,192 @@ Type name = foo; if (name) {} \endcode - \li Name of the introduced variable + \row + \li Optimize for-Loop + \li Rewrites post-increment operators as pre-increment operators and + post-decrement operators as pre-decrement operators. It also + moves other than string or numeric literals and id expressions + from the condition of a for loop to its initializer. For + example, rewrites: + + \code + for (int i = 0; i < 3 * 2; i++) + \endcode + + as + + \code + for (int i = 0, total = 3 * 2; i < total; ++i) + \endcode + \endtable + + \section1 Function Declaration or Definition + + \table + \header + \li Quick Fix + \li Description + \row + \li Add Definition ... + \li Inserts a definition stub for a function declaration either in + the header file (inside or outside the class) or in the + implementation file. For free functions, inserts the definition + after the declaration of the function or in the implementation + file. Qualified names are minimized when possible, instead of + always being fully expanded. + + For example, rewrites + + \code + Class Foo { + void bar(); + }; + \endcode + + as (inside class) + + \code + Class Foo { + void bar() { + + } + }; + \endcode + + as (outside class) + + \code + Class Foo { + void bar(); + }; + + void Foo::bar() + { + + } + \endcode + + as (in implementation file) + + \code + // Header file + Class Foo { + void bar(); + }; + + // Implementation file + void Foo::bar() + { + + } + \endcode + \row + \li Add \c Function Declaration + \li Inserts the member function declaration that matches the member + function definition into the class declaration. The function can + be \c {public}, \c {protected}, \c {private}, \c {public slot}, + \c {protected slot}, or \c {private slot}. + \row + \li Apply Changes + \li Keeps function declarations and definitions synchronized by + checking for the matching declaration or definition when you + edit a function signature and by applying the changes to the + matching code. + + When this fix is available, a light bulb icon appears: + \inlineimage icons/refactormarker.png + \row + \li Convert Function Call to Qt Meta-Method Invocation + \li Converts a normal function call into a meta method invocation, if + the function is marked as invokable. + \row + \li Move Definition Here + \li Moves an existing function definition to its declaration. + \row + \li Move Function Definition + \li Moves a function definition to the implementation file, outside + the class or back to its declaration. For example, rewrites: + \code + class Foo + { + void bar() + { + // do stuff here + } + }; + \endcode + + as + \code + class Foo + { + void bar(); + }; + + void Foo::bar() { + // do stuff here + } + \endcode + \row + \li Move Function Documentation to Declaration/Definition + \li Moves the documentation comment for a function between its + declaration and definition. + \endtable + + \section1 Identifier + + \table + \header + \li Quick Fix + \li Description + \row + \li Add #include for undeclared or forward declared identifier + \li Adds an \c {#include} directive to the current file to make the + definition of a symbol available. + \row + \li Add Class Member + \li Adds a member declaration for the class member being + initialized if it is not yet declared. If \QC cannot + automatically detect the data type of the member, you + must add it. + \row + \li Add Forward Declaration + \li Adds a forward declaration for an undeclared identifier + operation. + \row + \li Convert to Camel Case + \li Converts a symbol name to camel case, where elements of the name + are joined without delimiter characters and the initial + character of each element is capitalized. For example, rewrites + \c an_example_symbol as \c anExampleSymbol and + \c AN_EXAMPLE_SYMBOL as \c AnExampleSymbol + \endtable + + \section1 Numeric Literal + + \table + \header + \li Quick Fix + \li Description + \row + \li Convert to Decimal + \li Converts an integer literal to decimal representation + \row + \li Convert to Hexadecimal + \li Converts an integer literal to hexadecimal representation + \row + \li Convert to Octal + \li Converts an integer literal to octal representation + \endtable + + \section1 Operator + + \table + \header + \li Quick Fix + \li Description + \li Operator + \row \li Rewrite Condition Using || \li Rewrites the expression according to De Morgan's laws. For @@ -200,21 +555,6 @@ \endlist \li \c {<=}, \c {<}, \c {>}, \c {>=}, \c {==} or \c {!=} - \row - \li Split Declaration - \li Splits a simple declaration into several declarations. For - example, rewrites: - \code - int *a, b; - \endcode - - as - - \code - int *a; - int b; - \endcode - \li Type name or variable name \row \li Split if Statement \li Splits an if statement into several statements. For example, @@ -265,18 +605,14 @@ \endcode \li \c {<=}, \c {<}, \c {>}, \c {>=}, \c {==}, \c {!=}, \c {&&} or \c {||} - \row - \li Convert to Decimal - \li Converts an integer literal to decimal representation - \li Numeric literal - \row - \li Convert to Hexadecimal - \li Converts an integer literal to hexadecimal representation - \li Numeric literal - \row - \li Convert to Octal - \li Converts an integer literal to octal representation - \li Numeric literal + \endtable + + \section1 String Literal + + \table + \header + \li Quick Fix + \li Description \row \li Convert to Objective-C String Literal \li Converts a string literal to an Objective-C string literal if @@ -294,7 +630,18 @@ \code @"abcd" \endcode - \li String literal + \row + \li Enclose in QByteArrayLiteral() + \li Converts a string to a byte array. For example, rewrites + \code + "abcd" + \endcode + + as + + \code + QByteArrayLiteral("abcd") + \endcode \row \li Enclose in QLatin1Char() \li Sets the encoding for a character to Latin-1, unless the @@ -311,7 +658,6 @@ \code QLatin1Char('a') \endcode - \li String literal \row \li Enclose in QLatin1String() \li Sets the encoding for a string to Latin-1, unless the string is @@ -326,22 +672,10 @@ \code QLatin1String("abcd") \endcode - - \li String literal \row - \li Enclose in QByteArrayLiteral() - \li Converts a string to a byte array. For example, rewrites - \code - "abcd" - \endcode - - as - - \code - QByteArrayLiteral("abcd") - \endcode - - \li String literal + \li Escape String Literal as UTF-8 + \li Escapes non-ASCII characters in a string literal to hexadecimal + escape sequences. String Literals are handled as UTF-8. \row \li Mark as Translatable \li Marks a string translatable. For example, rewrites \c "abcd" @@ -353,104 +687,37 @@ QCoreApplication::translate("CONTEXT", "abcd") QT_TRANSLATE_NOOP("GLOBAL", "abcd") \endcode - - \li String literal - \row - \li Add Definition in ... - \li Inserts a definition stub for a function declaration either in - the header file (inside or outside the class) or in the - implementation file. For free functions, inserts the definition - after the declaration of the function or in the implementation - file. Qualified names are minimized when possible, instead of - always being fully expanded. + \li Unescape String Literal as UTF-8 + \li Unescapes octal or hexadecimal escape sequences in a string + literal. String Literals are handled as UTF-8. + \endtable - For example, rewrites + \section1 \c using directive - \code - Class Foo { - void bar(); - }; - \endcode - - as (inside class) - - \code - Class Foo { - void bar() { - - } - }; - \endcode - - as (outside class) - - \code - Class Foo { - void bar(); - }; - - void Foo::bar() - { - - } - \endcode - - as (in implementation file) - - \code - // Header file - Class Foo { - void bar(); - }; - - // Implementation file - void Foo::bar() - { - - } - \endcode - - \li Function name + \table + \header + \li Quick Fix + \li Description + \row + \li Remove All Occurrences of \c {using namespace} in Global Scope + and Adjust Type Names Accordingly + \li Remove all occurrences of \c {using namespace} in the global + scope and adjust type names accordingly. \row - \li Add \c Function Declaration - \li Inserts the member function declaration that matches the member - function definition into the class declaration. The function can - be \c {public}, \c {protected}, \c {private}, \c {public slot}, - \c {protected slot}, or \c {private slot}. - \li Function name - \row - \li Add Class Member - \li Adds a member declaration for the class member being - initialized if it is not yet declared. If \QC cannot - automatically detect the data type of the member, you - must add it. - \li Identifier - \row - \li Create Implementations for Member Functions - \li Creates implementations for all member functions in one go. - In the \uicontrol {Member Function Implementations} dialog, - specify whether the member functions are generated - inline or outside the class. - \li Function name - \row - \li Switch with Next/Previous Parameter - \li Moves a parameter down or up one position in a parameter list. - \li Parameter in the declaration or definition of a function - \row - \li Extract Function - \li Moves the selected code to a new function and replaces the block - of code with a call to the new function. Enter a name for the - function in the \uicontrol {Extract Function Refactoring} - dialog. - \li Block of code selected - \row - \li Extract Constant as Function Parameter - \li Replaces the selected literal and all its occurrences with the - function parameter \c{newParameter}. The parameter - \c{newParameter} will have the original literal as the default - value. - \li Block of code selected + \li Remove \c {using namespace} and Adjust Type Names Accordingly + \li Remove occurrences of \c {using namespace} in the local scope + and adjust type names accordingly. + \endtable + + + \section1 Miscellaneous + + \table + \header + \li Quick Fix + \li Description + \li Activation \row \li Add Local Declaration \li Adds the type of an assignee, if the type of the right-hand @@ -469,63 +736,59 @@ where Type is the return type of \c {foo()} \li Assignee + \row + \li Convert connect() to Qt 5 Style + \li Converts a Qt 4 QObject::connect() to Qt 5 style. + \li QObject::connect() (Qt 4 style) + \row + \li Convert Comment to C/C++ Style + \li Converts C-style comments into C++-style comments, and vice + versa. Tries to preserve \e pretty layout and takes Doxygen and + qdoc formatting into consideration, but you might need to clean + up the results. + \li Code comment + \row + \li Convert to Pointer + \li Converts the selected stack variable to a pointer. For example, + rewrites: + \code + QByteArray foo = "foo"; + foo.append("bar"); + \endcode + + as + + \code + QByteArray *foo = new QByteArray("foo"); + foo->append("bar"); + \endcode + + This operation is limited to work only within function scope. + Also, the coding style for pointers and references is not + respected yet. + \li Stack Variable \row - \li Convert to Camel Case - \li Converts a symbol name to camel case, where elements of the name - are joined without delimiter characters and the initial - character of each element is capitalized. For example, rewrites - \c an_example_symbol as \c anExampleSymbol and - \c AN_EXAMPLE_SYMBOL as \c AnExampleSymbol - \li Identifier - \row - \li Complete Switch Statement - \li Adds all possible cases to a switch statement of the type - \c enum - \li \c switch - \row - \li Generate Missing Q_PROPERTY Members - \li Adds missing members to a \c Q_PROPERTY: - \list - \li \c read function - \li \c write function, if there is a WRITE - \li \c {onChanged} signal, if there is a NOTIFY - \li data member with the name \c {m_} - \endlist - \li \c Q_PROPERTY - \row - \li Generate Q_PROPERTY and Missing Members - \li Generates a Q_PROPERTY and adds missing members to it, as - described above. - \li Class member - \row - \li Generate Constant Q_PROPERTY and Missing Members - \li Generates a constant Q_PROPERTY and adds missing members - to it, as described above. - \li Class member - \row - \li Generate Q_PROPERTY and Missing Members with Reset Function - \li Generates a Q_PROPERTY and adds missing members to it, as - described above, but with an additional \c reset function. - \li Class member - \row - \li Apply Changes - \li Keeps function declarations and definitions synchronized by - checking for the matching declaration or definition when you - edit a function signature and by applying the changes to the - matching code. - \li Function signature. When this fix is available, a light bulb - icon appears: \inlineimage icons/refactormarker.png - \row - \li Add #include for undeclared or forward declared identifier - \li Adds an \c {#include} directive to the current file to make the - definition of a symbol available. - \li Undeclared identifier - \row - \li Add Forward Declaration - \li Adds a forward declaration for an undeclared identifier - operation. - \li Undeclared identifier + \li Convert to Stack Variable + \li Converts the selected pointer to a stack variable. For example, + rewrites: + + \code + QByteArray *foo = new QByteArray("foo"); + foo->append("bar"); + \endcode + + as + + \code + QByteArray foo("foo"); + foo.append("bar"); + \endcode + + This operation is limited to work only within function scope. + Also, the coding style for pointers and references is not + respected yet. + \li Pointer Variable \row \li Reformat Pointers or References \li Reformats declarations with pointers or references according @@ -551,239 +814,24 @@ \li Declarations with pointers or references and selections that have such declarations \row - \li Create Getter and Setter Member Functions - \li Creates either both getter and setter member functions for - member variables or only a getter or setter. - \li Member variable in class definition - \row - \li Generate Getter and Setter - \li Creates getter and setter member functions for a member - variable. - \li Member variable in class definition - \row - \li Generate Getter - \li Creates a getter member function for a member variable. - \li Member variable in class definition - \row - \li Generate Setter - \li Creates a setter member function for a member variable. - \li Member variable in class definition - \row - \li Generate Constructor - \li Creates a constructor for a class. - \li Class definition - \row - \li Move Function Definition - \li Moves a function definition to the implementation file, outside - the class or back to its declaration. For example, rewrites: - \code - class Foo - { - void bar() - { - // do stuff here - } - }; - \endcode - - as - \code - class Foo - { - void bar(); - }; - - void Foo::bar() { - // do stuff here - } - \endcode - - \li Function signature - \row - \li Move All Function Definitions - \li Moves all function definitions to the implementation file or - outside the class. For example, rewrites: - \code - class Foo - { - void bar() - { - // do stuff here - } - void baz() - { - // do stuff here - } - }; - \endcode - - as - - \code - class Foo - { - void bar(); - void baz(); - }; - - void Foo::bar() { - // do stuff here - } - - void Foo::baz() { - // do stuff here - } - \endcode - - \li Class name - \row - \li Move Definition Here - \li Moves an existing function definition to its declaration. - \li Function declaration - \row - \li Assign to Local Variable - \li Adds a local variable which stores the return value of a - function call or a new expression. For example, rewrites: - - \code - QString s; - s.toLatin1(); - \endcode - - as - - \code - QString s; - QByteArray latin1 = s.toLatin1(); - \endcode - - and - - \code - new Foo; - \endcode - - as - - \code - Foo * localFoo = new Foo; - \endcode - - By default, \QC uses the \c auto variable type when creating the - variable. To label the variable with its actual type, select - \preferences > \uicontrol C++ > - \uicontrol {Quick Fixes}, and then deselect the - \uicontrol {Use type "auto" when creating new variables} check - box. - - \li Function call or class name - \row - \li Insert Virtual Functions of Base Classes - \li Inserts declarations and the corresponding definitions inside or - outside the class or in an implementation file (if it exists). - For more information, see \l{Insert virtual functions}. - \li Class or base class name - \row - \li Optimize for-Loop - \li Rewrites post increment operators as pre increment operators and - post decrement operators as pre decrement operators. It also - moves other than string or numeric literals and id expressions - from the condition of a for loop to its initializer. For + \li Split Declaration + \li Splits a simple declaration into several declarations. For example, rewrites: - \code - for (int i = 0; i < 3 * 2; i++) + int *a, b; \endcode as \code - for (int i = 0, total = 3 * 2; i < total; ++i) + int *a; + int b; \endcode - \li \c for - + \li Type name or variable name \row - \li Escape String Literal as UTF-8 - \li Escapes non-ASCII characters in a string literal to hexadecimal - escape sequences. String Literals are handled as UTF-8. - \li String literal - - \row - \li Unescape String Literal as UTF-8 - \li Unescapes octal or hexadecimal escape sequences in a string - literal. String Literals are handled as UTF-8. - \li String literal - - \row - \li Convert to Stack Variable - \li Converts the selected pointer to a stack variable. For example, - rewrites: - - \code - QByteArray *foo = new QByteArray("foo"); - foo->append("bar"); - \endcode - - as - - \code - QByteArray foo("foo"); - foo.append("bar"); - \endcode - - This operation is limited to work only within function scope. - Also, the coding style for pointers and references is not - respected yet. - \li Pointer Variable - - \row - \li Convert to Pointer - \li Converts the selected stack variable to a pointer. For example, - rewrites: - - \code - QByteArray foo = "foo"; - foo.append("bar"); - \endcode - - as - - \code - QByteArray *foo = new QByteArray("foo"); - foo->append("bar"); - \endcode - - This operation is limited to work only within function scope. - Also, the coding style for pointers and references is not - respected yet. - \li Stack Variable - \row - \li Remove \c {using namespace} and Adjust Type Names Accordingly - \li Remove occurrences of \c {using namespace} in the local scope - and adjust type names accordingly. - \li \c using directive - \row - \li Remove All Occurrences of \c {using namespace} in Global Scope - and Adjust Type Names Accordingly - \li Remove all occurrences of \c {using namespace} in the global - scope and adjust type names accordingly. - \li \c using directive - \row - \li Convert connect() to Qt 5 Style - \li Converts a Qt 4 QObject::connect() to Qt 5 style. - \li QObject::connect() (Qt 4 style) - \row - \li Convert Comment to C/C++ Style - \li Converts C-style comments into C++-style comments, and vice - versa. Tries to preserve \e pretty layout and takes Doxygen and - qdoc formatting into consideration, but you might need to clean - up the results. - \li Code comment - \row - \li Move Function Documentation to Declaration/Definition - \li Moves the documentation comment for a function between its - declaration and definition. - \li Documentation comment for a function + \li Switch with Next/Previous Parameter + \li Moves a parameter down or up one position in a parameter list. + \li Parameter in the declaration or definition of a function \endtable \sa {Apply quick fixes}, {Find symbols}, {Rename symbols}, diff --git a/doc/qtcreator/src/editors/creator-only/creator-preferences-cpp-code-style.qdoc b/doc/qtcreator/src/editors/creator-only/creator-preferences-cpp-code-style.qdoc index 56e413b7e93..024b731d3ca 100644 --- a/doc/qtcreator/src/editors/creator-only/creator-preferences-cpp-code-style.qdoc +++ b/doc/qtcreator/src/editors/creator-only/creator-preferences-cpp-code-style.qdoc @@ -54,6 +54,8 @@ \list \li Interpret the \key Tab and \key Backspace key presses. + \li Add macros that the indenter interprets as complete statements that + don't require a semicolon at the end. \li Indent the contents of classes, functions, blocks, and namespaces. \li Indent braces in classes, namespaces, enums, functions, and blocks. \li Control switch statements and their contents. diff --git a/doc/qtcreator/src/editors/creator-quick-fixes.qdoc b/doc/qtcreator/src/editors/creator-quick-fixes.qdoc index 7e02f60c650..6ef8f778737 100644 --- a/doc/qtcreator/src/editors/creator-quick-fixes.qdoc +++ b/doc/qtcreator/src/editors/creator-quick-fixes.qdoc @@ -38,7 +38,7 @@ By default, the refactored files are saved automatically. To turn off this feature, go to \preferences > \uicontrol Environment > - \uicontrol System and select \uicontrol {Auto-save files after refactoring}. + \uicontrol System and clear \uicontrol {Auto-save files after refactoring}. \if defined(qtcreator) \section1 Create functions @@ -94,6 +94,17 @@ {C++ Quick Fixes} \endif + \section1 Move classes to separate files + + Apply the \uicontrol {Move Class to a Dedicated Set of Source Files} quick + fix to move a class to a separate set of header and implementation files. + + \image qtcreator-move-class-to-separate-files.webp {Give names to header and implementation files} + + Specify paths and file names for the header and implementation file. + + To omit the implementation file, select \uicontrol {Header file only}. + \sa {Rename symbols}, {QML Quick Fixes} */ diff --git a/doc/qtcreator/src/projects/creator-only/creator-projects-libraries.qdoc b/doc/qtcreator/src/projects/creator-only/creator-projects-libraries.qdoc index c4f8d905a33..fc66a62e8a7 100644 --- a/doc/qtcreator/src/projects/creator-only/creator-projects-libraries.qdoc +++ b/doc/qtcreator/src/projects/creator-only/creator-projects-libraries.qdoc @@ -91,7 +91,7 @@ For more information about the project file settings, see \l{Declaring Other Libraries}{qmake Manual: Declaring Other Libraries}. - \sa {Adding an Internal Library to a qmake Project}{Tutorial: Adding an Internal Library to a qmake Project}, + \sa {Using an Internal Library in a qmake Project}{Tutorial: Using an Internal Library in a qmake Project}, {Add subprojects to projects}, {Add libraries to CMake projects}, {Use project wizards}, {Creating Projects} */ @@ -103,7 +103,7 @@ \ingroup creator-tutorials - \title Adding an Internal Library to a qmake Project + \title Using an Internal Library in a qmake Project \brief How to create your own library and link your application against it when using qmake as the build system. diff --git a/doc/qtcreatordev/src/lua-extensions.qdoc b/doc/qtcreatordev/src/lua-extensions.qdoc new file mode 100644 index 00000000000..581db2e3922 --- /dev/null +++ b/doc/qtcreatordev/src/lua-extensions.qdoc @@ -0,0 +1,275 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +/*! + \page lua-extensions.html + \title Extending \QC with Lua + + \QC can be extended with Lua scripts. The included Lua engine is based on Lua 5.4.6. + + \section1 Writing Lua Extensions + + To create a new Lua extension, choose \uicontrol {File} > \uicontrol {New Project} > + \uicontrol {Library} > \uicontrol {\QC Lua Plugin}. + + To test your new extension, start your project. Your \uicontrol {Application Output} + should show \e {Hello from Lua!}. + + \section1 Lua Extension Specification + + A Lua extension consists of a Lua script with the same name as the folder it is in. + This is necessary for the extension to be loaded. + + This script defines the specification of the extension, such as its display name, vendor, copyright. + + \code + --- MyExtension.lua + return { + Name = "MyExtension", + Version = "1.0.0", + CompatVersion = "1.0.0", + Vendor = "My Company", + Category = "Tests", + Description = "Describe what your extension does in a sentence.", + LongDescription = [[ + Tell users more about your extension. + ]], + Dependencies = { + { Name = "Core", Version = "13.0.82", Required = true }, + { Name = "Lua", Version = "13.0.82", Required = true } + }, + setup = function() print("Hello from Lua!") end, + printToOutputPane = true, + } --[[@as QtcPlugin]] + \endcode + + \section1 The Setup Function + + The setup function is called when the extension is loaded. This is where you can set up the + functionality of your extension. Since the specification file is parsed with very limited + permissions, you need to require a module where you implement the actual functionality. + + \code + --- MyExtension.lua + return { + Name = "MyExtension", + Version = "1.0.0", + ..., + --- This is the setup function that is called when the extension is loaded. + --- It requires the 'init' module and calls the setup function from the returned table. + setup = function() require 'init'.setup() end, + } + \endcode + + \code + --- init.lua + function setup() + print("Hello from Lua!") + end + + -- Returns a table with a single field 'setup' that points to the setup function. + return { + setup = setup + } + \endcode + + + \section1 Asynchronous Operations + + Some of the built-in operations work asynchronously. To handle this, use the Async module. + + \code + local a = require 'async' + local u = require 'Utils' + + a.sync(function() + print("Lets wait for 5 seconds ...") + a.wait(u.waitms(5000)) + print("... done!") + end) + \endcode + + \section1 Interactive Help + + When you open a .lua file in the editor the first time, you are asked to download the Lua + Language Server. This is extremely useful as it gives you context sensitive help and + auto-completion. + + \section1 \QC API + + The \QC API is available to Lua extensions via a number of modules that you can import + using the \c {require} function. C++ extensions may provide additional modules. One example of that + is the LanguageServer Extension that provides a module for creating Language Server clients. + + You can find the API documentation files for the Lua modules in your \QC installation. + On \macos you can find them in \c{Qt Creator.app/Contents/Resources/lua/meta}. + + \annotatedlist lua-modules + + \section1 Extending the Lua API with C++ + + To add functionality to the Lua Interface, you need to register a new module with the Lua Engine. + + \code + #include + + class MyCppExtension final : public ExtensionSystem::IPlugin + { + Q_OBJECT + Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QtCreatorPlugin" FILE "MyCppExtension.json") + + public: + MyCppExtension() {} + + private: + void initialize() final { + // The registered function will be called when the Lua module 'MyCppExtension' is required. + // The returned table will be returned from the require call in Lua. + ::Lua::LuaEngine::registerProvider("MyCppExtension", [](sol::state_view lua) -> sol::object { + sol::table result = lua.create_table(); + result["myFunction"] = [](int a, int b) { return a + b; }; + return result; + }); + } + }; + \endcode + + You can then access \c{MyCppExtension.myFunction} from your Lua scripts like this: + + \code + local MyCppExtension = require 'MyCppExtension' + --- MyCppExtension is now a table with a single field 'myFunction', as it is returned from the + --- C++ function registered via 'LuaEngine::registerProvider(...)'. + print(MyCppExtension.myFunction(1, 2)) + \endcode + + For more information on how to register C++ functionality, see + \l {https://sol2.readthedocs.io/en/latest/index.html} {sol2}. + + \section1 Examples + + \section2 Language Server + + The \QC LuaLanguageClient Plugin provides support for registering your own Language Server + clients. You can find an example of how to use this in the \QC Extension "Lua Language Server" + and "Rust Language Server". +*/ + +/*! + \page lua-extension-meta-core + \ingroup lua-modules + \title Core.lua + \brief Access and interact with the core functionality of \QC. + + \quotefile ../../../src/plugins/lua/meta/core.lua +*/ + +/*! + \page lua-extension-meta-action + \ingroup lua-modules + \title action.lua + \brief Create user interface actions in \QC. + + \quotefile ../../../src/plugins/lua/meta/action.lua +*/ + +/*! + \page lua-extension-meta-async + \ingroup lua-modules + \title async.lua + \brief Handle asynchronouse operations with the async/await Lua API. + + \quotefile ../../../src/plugins/lua/meta/async.lua +*/ + +/*! + \page lua-extension-meta-fetch + \ingroup lua-modules + \title fetch.lua + \brief Fetch data from the internet. + + \quotefile ../../../src/plugins/lua/meta/fetch.lua +*/ + +/*! + \page lua-extension-meta-gui + \ingroup lua-modules + \title gui.lua + \brief Create user interfaces. + + \quotefile ../../../src/plugins/lua/meta/gui.lua +*/ + +/*! + \page lua-extension-meta-lsp + \ingroup lua-modules + \title lsp.lua + \brief Register Language Server clients. + + \quotefile ../../../src/plugins/lua/meta/lsp.lua +*/ + +/*! + \page lua-extension-meta-messagemanager + \ingroup lua-modules + \title messagemanager.lua + \brief Display messages to the user. + + \quotefile ../../../src/plugins/lua/meta/messagemanager.lua +*/ + +/*! + \page lua-extension-meta-process + \ingroup lua-modules + \title process.lua + \brief Run external processes. + + \quotefile ../../../src/plugins/lua/meta/process.lua +*/ + +/*! + \page lua-extension-meta-qt + \ingroup lua-modules + \title qt.lua + \brief Access Qt functionality. + + \quotefile ../../../src/plugins/lua/meta/qt.lua +*/ + +/*! + \page lua-extension-meta-qtc + \ingroup lua-modules + \title qtc.lua + \brief Access and extend \QC. + + \quotefile ../../../src/plugins/lua/meta/qtc.lua +*/ + +/*! + \page lua-extension-meta-settings + \ingroup lua-modules + \title settings.lua + \brief Read and write settings. + + \quotefile ../../../src/plugins/lua/meta/settings.lua +*/ + +/*! + \page lua-extension-meta-simpletypes + \ingroup lua-modules + \title simpletypes.lua + \brief Access simple types. + + \quotefile ../../../src/plugins/lua/meta/simpletypes.lua +*/ + +/*! + \page lua-extension-meta-utils + \ingroup lua-modules + \title utils.lua + \brief Common utility functions and classes. + + \quotefile ../../../src/plugins/lua/meta/utils.lua +*/ + + diff --git a/doc/qtcreatordev/src/qtcreator-dev.qdoc b/doc/qtcreatordev/src/qtcreator-dev.qdoc index ae68f3f4076..998f040ebf7 100644 --- a/doc/qtcreatordev/src/qtcreator-dev.qdoc +++ b/doc/qtcreatordev/src/qtcreator-dev.qdoc @@ -214,7 +214,16 @@ \li \l{Options Pages} \li \l{Editors} \endomit - \endlist + \endlist + + \section1 Lua Extensions + + If you have more specific needs that are not covered by the above methods but don't need + a full-blown plugin, you can extend \QC with Lua Extensions. + + \list + \li \l{Extending \QC with Lua} + \endlist \section1 All Topics diff --git a/qbs/imports/QtcLuaPlugin.qbs b/qbs/imports/QtcLuaPlugin.qbs index e7976501c34..1684590480c 100644 --- a/qbs/imports/QtcLuaPlugin.qbs +++ b/qbs/imports/QtcLuaPlugin.qbs @@ -7,6 +7,6 @@ Product { prefix: sourceDirectory + '/' + product.name + '/' files: luafiles qbs.install: true - qbs.installDir: qtc.ide_plugin_path + '/lua-plugins/' + product.name + qbs.installDir: qtc.ide_plugin_path + '/' + product.name } } diff --git a/share/qtcreator/debugger/cdbbridge.py b/share/qtcreator/debugger/cdbbridge.py index ce88c903a77..7674a37b710 100644 --- a/share/qtcreator/debugger/cdbbridge.py +++ b/share/qtcreator/debugger/cdbbridge.py @@ -331,8 +331,7 @@ class Dumper(DumperBase): self.qtNamespace = lambda: namespace return namespace - def qtVersion(self): - qtVersion = None + def extractQtVersion(self): try: qtVersion = self.parseAndEvaluate( '((void**)&%s)[2]' % self.qtHookDataSymbolName()).integer() @@ -344,10 +343,7 @@ class Dumper(DumperBase): (major, minor, patch) = version.decode('latin1').split('.') qtVersion = 0x10000 * int(major) + 0x100 * int(minor) + int(patch) except: - pass - if qtVersion is None: - qtVersion = self.fallbackQtVersion - self.qtVersion = lambda: qtVersion + return None return qtVersion def putVtableItem(self, address): diff --git a/src/libs/extensionsystem/pluginspec.cpp b/src/libs/extensionsystem/pluginspec.cpp index f7d72b80420..d2515760493 100644 --- a/src/libs/extensionsystem/pluginspec.cpp +++ b/src/libs/extensionsystem/pluginspec.cpp @@ -559,18 +559,17 @@ QString PluginSpec::errorString() const } /*! - Returns whether this plugin can be used to fill in a dependency of the given - \a pluginName and \a pluginVersion. + Returns whether the plugin \a spec can be used to fill the \a dependency of this plugin. - \sa PluginSpec::dependencies() + \sa PluginSpec::dependencies() */ -bool PluginSpec::provides(const QString &pluginName, const QString &pluginVersion) const +bool PluginSpec::provides(PluginSpec *spec, const PluginDependency &dependency) const { - if (QString::compare(pluginName, name(), Qt::CaseInsensitive) != 0) + if (QString::compare(dependency.name, spec->name(), Qt::CaseInsensitive) != 0) return false; - return (versionCompare(version(), pluginVersion) >= 0) - && (versionCompare(compatVersion(), pluginVersion) <= 0); + return (versionCompare(spec->version(), dependency.version) >= 0) + && (versionCompare(spec->compatVersion(), dependency.version) <= 0); } /*! @@ -1075,8 +1074,8 @@ bool PluginSpec::resolveDependencies(const PluginSpecs &specs) QHash resolvedDependencies; for (const PluginDependency &dependency : d->dependencies) { - PluginSpec *const found = findOrDefault(specs, [&dependency](PluginSpec *spec) { - return spec->provides(dependency.name, dependency.version); + PluginSpec *const found = findOrDefault(specs, [this, &dependency](PluginSpec *spec) { + return provides(spec, dependency); }); if (!found) { if (dependency.type == PluginDependency::Required) { diff --git a/src/libs/extensionsystem/pluginspec.h b/src/libs/extensionsystem/pluginspec.h index 49a972d9149..e9a771d4a99 100644 --- a/src/libs/extensionsystem/pluginspec.h +++ b/src/libs/extensionsystem/pluginspec.h @@ -36,13 +36,14 @@ class PluginView; struct EXTENSIONSYSTEM_EXPORT PluginDependency { - enum Type { - Required, - Optional, - Test - }; + enum Type { Required, Optional, Test }; PluginDependency() : type(Required) {} + PluginDependency(const QString &name, const QString &version, Type type = Required) + : name(name) + , version(version) + , type(type) + {} QString name; QString version; @@ -130,7 +131,7 @@ public: virtual void addArgument(const QString &argument); virtual QHash dependencySpecs() const; - virtual bool provides(const QString &pluginName, const QString &pluginVersion) const; + virtual bool provides(PluginSpec *spec, const PluginDependency &dependency) const; virtual bool requiresAny(const QSet &plugins) const; virtual PluginSpecs enableDependenciesIndirectly(bool enableTestDependencies); virtual bool resolveDependencies(const PluginSpecs &pluginSpecs); diff --git a/src/libs/qmljs/qmljsstaticanalysismessage.cpp b/src/libs/qmljs/qmljsstaticanalysismessage.cpp index 432b97aba72..a58bf43765b 100644 --- a/src/libs/qmljs/qmljsstaticanalysismessage.cpp +++ b/src/libs/qmljs/qmljsstaticanalysismessage.cpp @@ -153,7 +153,7 @@ StaticAnalysisMessages::StaticAnalysisMessages() Tr::tr("Invalid property type \"%1\"."), 1); newMsg(WarnEqualityTypeCoercion, Error, Tr::tr("== and != perform type coercion, use === or !== to avoid it.")); - newMsg(WarnExpectedNewWithUppercaseFunction, Error, + newMsg(WarnExpectedNewWithUppercaseFunction, Warning, Tr::tr("Calls of functions that start with an uppercase letter should use 'new'.")); newMsg(WarnNewWithLowercaseFunction, Error, Tr::tr("Use 'new' only with functions that start with an uppercase letter.")); diff --git a/src/libs/solutions/tasking/tasktree.cpp b/src/libs/solutions/tasking/tasktree.cpp index d923eb31d0e..5c1f65e503f 100644 --- a/src/libs/solutions/tasking/tasktree.cpp +++ b/src/libs/solutions/tasking/tasktree.cpp @@ -1291,6 +1291,12 @@ const void *Loop::valuePtr() const using StoragePtr = void *; +static QString s_activeStorageWarning = + "The referenced storage is not reachable in the running tree. " + "A nullptr will be returned which might lead to a crash in the calling code. " + "It is possible that no storage was added to the tree, " + "or the storage is not reachable from where it is referenced."; + class StorageThreadData { Q_DISABLE_COPY_MOVE(StorageThreadData) @@ -1299,7 +1305,7 @@ public: StorageThreadData() = default; void pushStorage(StoragePtr storagePtr) { - m_activeStorageStack.push_back(storagePtr); + m_activeStorageStack.push_back({storagePtr, activeTaskTree()}); } void popStorage() { @@ -1308,16 +1314,16 @@ public: } StoragePtr activeStorage() const { - QT_ASSERT(m_activeStorageStack.size(), qWarning( - "The referenced storage is not reachable in the running tree. " - "A nullptr will be returned which might lead to a crash in the calling code. " - "It is possible that no storage was added to the tree, " - "or the storage is not reachable from where it is referenced."); return nullptr); - return m_activeStorageStack.last(); + QT_ASSERT(m_activeStorageStack.size(), + qWarning().noquote() << s_activeStorageWarning; return nullptr); + const QPair &top = m_activeStorageStack.last(); + QT_ASSERT(top.second == activeTaskTree(), + qWarning().noquote() << s_activeStorageWarning; return nullptr); + return top.first; } private: - QList m_activeStorageStack; + QList> m_activeStorageStack; }; class StorageData diff --git a/src/libs/utils/icon.cpp b/src/libs/utils/icon.cpp index df880ac67ec..06570e6505a 100644 --- a/src/libs/utils/icon.cpp +++ b/src/libs/utils/icon.cpp @@ -210,11 +210,10 @@ QIcon Icon::sideBarIcon(const Icon &classic, const Icon &flat) return result; } -QIcon Icon::modeIcon(const Icon &classic, const Icon &flat, const Icon &flatActive) +QIcon Icon::modeIcon(const Icon &classic, const Icon &flat, + [[__maybe_unused__]] const Icon &flatActive) { QIcon result = sideBarIcon(classic, flat); - if (creatorTheme()->flag(Theme::FlatSideBarIcons)) - result.addPixmap(flatActive.pixmap(), QIcon::Active); return result; } diff --git a/src/libs/utils/images/debugger_overlay_small.png b/src/libs/utils/images/debugger_overlay_small.png index 809bf347326..440d2b59d28 100644 Binary files a/src/libs/utils/images/debugger_overlay_small.png and b/src/libs/utils/images/debugger_overlay_small.png differ diff --git a/src/libs/utils/images/debugger_overlay_small@2x.png b/src/libs/utils/images/debugger_overlay_small@2x.png index c24c861cbbb..40ea20ed47b 100644 Binary files a/src/libs/utils/images/debugger_overlay_small@2x.png and b/src/libs/utils/images/debugger_overlay_small@2x.png differ diff --git a/src/libs/utils/launcherpackets.cpp b/src/libs/utils/launcherpackets.cpp index 37261224ef5..a770e8865da 100644 --- a/src/libs/utils/launcherpackets.cpp +++ b/src/libs/utils/launcherpackets.cpp @@ -49,7 +49,8 @@ void StartProcessPacket::doSerialize(QDataStream &stream) const << unixTerminalDisabled << useCtrlCStub << reaperTimeout - << createConsoleOnWindows; + << createConsoleOnWindows + << forceDefaultErrorMode; } void StartProcessPacket::doDeserialize(QDataStream &stream) @@ -70,7 +71,8 @@ void StartProcessPacket::doDeserialize(QDataStream &stream) >> unixTerminalDisabled >> useCtrlCStub >> reaperTimeout - >> createConsoleOnWindows; + >> createConsoleOnWindows + >> forceDefaultErrorMode; processMode = Utils::ProcessMode(processModeInt); processChannelMode = QProcess::ProcessChannelMode(processChannelModeInt); } diff --git a/src/libs/utils/launcherpackets.h b/src/libs/utils/launcherpackets.h index 27e98a74e5b..d00169c1f6f 100644 --- a/src/libs/utils/launcherpackets.h +++ b/src/libs/utils/launcherpackets.h @@ -99,6 +99,7 @@ public: bool useCtrlCStub = false; int reaperTimeout = 500; bool createConsoleOnWindows = false; + bool forceDefaultErrorMode = false; private: void doSerialize(QDataStream &stream) const override; diff --git a/src/libs/utils/launchersocket.cpp b/src/libs/utils/launchersocket.cpp index 23b7d39fcd1..61796a2bb3d 100644 --- a/src/libs/utils/launchersocket.cpp +++ b/src/libs/utils/launchersocket.cpp @@ -260,6 +260,7 @@ void CallerHandle::start(const QString &program, const QStringList &arguments) p.useCtrlCStub = m_setup->m_useCtrlCStub; p.reaperTimeout = m_setup->m_reaperTimeout.count(); p.createConsoleOnWindows = m_setup->m_createConsoleOnWindows; + p.forceDefaultErrorMode = m_setup->m_forceDefaultErrorMode; sendPacket(p); } diff --git a/src/libs/utils/processhelper.cpp b/src/libs/utils/processhelper.cpp index 6045b77bec1..7e7f34cf421 100644 --- a/src/libs/utils/processhelper.cpp +++ b/src/libs/utils/processhelper.cpp @@ -55,12 +55,13 @@ void ProcessStartHandler::setNativeArguments(const QString &arguments) #endif // Q_OS_WIN } -void ProcessStartHandler::setWindowsSpecificStartupFlags(bool belowNormalPriority, - bool createConsoleWindow) +void ProcessStartHandler::setWindowsSpecificStartupFlags( + bool belowNormalPriority, bool createConsoleWindow, bool forceDefaultErrorMode) { #ifdef Q_OS_WIN m_process->setCreateProcessArgumentsModifier( - [belowNormalPriority, createConsoleWindow](QProcess::CreateProcessArguments *args) { + [belowNormalPriority, createConsoleWindow, forceDefaultErrorMode]( + QProcess::CreateProcessArguments *args) { if (createConsoleWindow) { args->flags |= CREATE_NEW_CONSOLE; args->startupInfo->dwFlags &= ~STARTF_USESTDHANDLES; @@ -69,11 +70,13 @@ void ProcessStartHandler::setWindowsSpecificStartupFlags(bool belowNormalPriorit if (belowNormalPriority) args->flags |= BELOW_NORMAL_PRIORITY_CLASS; - args->flags |= CREATE_DEFAULT_ERROR_MODE; + if (forceDefaultErrorMode) + args->flags |= CREATE_DEFAULT_ERROR_MODE; }); #else // Q_OS_WIN Q_UNUSED(belowNormalPriority) Q_UNUSED(createConsoleWindow) + Q_UNUSED(forceDefaultErrorMode) #endif } diff --git a/src/libs/utils/processhelper.h b/src/libs/utils/processhelper.h index a4efc17ae51..7c40cb3faa0 100644 --- a/src/libs/utils/processhelper.h +++ b/src/libs/utils/processhelper.h @@ -20,7 +20,8 @@ public: void handleProcessStart(); void handleProcessStarted(); void setNativeArguments(const QString &arguments); - void setWindowsSpecificStartupFlags(bool belowNormalPriority, bool createConsoleWindow); + void setWindowsSpecificStartupFlags( + bool belowNormalPriority, bool createConsoleWindow, bool forceDefaultErrorMode); private: ProcessMode m_processMode = ProcessMode::Reader; diff --git a/src/libs/utils/processinterface.h b/src/libs/utils/processinterface.h index 1e233b88abf..4d230c4ef9e 100644 --- a/src/libs/utils/processinterface.h +++ b/src/libs/utils/processinterface.h @@ -94,6 +94,7 @@ public: bool m_useCtrlCStub = false; bool m_belowNormalPriority = false; // internal, dependent on other fields and specific code path bool m_createConsoleOnWindows = false; + bool m_forceDefaultErrorMode = false; }; class QTCREATOR_UTILS_EXPORT ProcessResultData diff --git a/src/libs/utils/qtcprocess.cpp b/src/libs/utils/qtcprocess.cpp index dca106a7d51..5e0918ed70e 100644 --- a/src/libs/utils/qtcprocess.cpp +++ b/src/libs/utils/qtcprocess.cpp @@ -511,7 +511,8 @@ private: handler->setWriteData(m_setup.m_writeData); handler->setNativeArguments(m_setup.m_nativeArguments); handler->setWindowsSpecificStartupFlags(m_setup.m_belowNormalPriority, - m_setup.m_createConsoleOnWindows); + m_setup.m_createConsoleOnWindows, + m_setup.m_forceDefaultErrorMode); const QProcessEnvironment penv = m_setup.m_environment.toProcessEnvironment(); if (!penv.isEmpty()) @@ -1383,6 +1384,16 @@ bool Process::createConsoleOnWindows() const return d->m_setup.m_createConsoleOnWindows; } +void Process::setForceDefaultErrorModeOnWindows(bool force) +{ + d->m_setup.m_forceDefaultErrorMode = force; +} + +bool Process::forceDefaultErrorModeOnWindows() const +{ + return d->m_setup.m_forceDefaultErrorMode; +} + void Process::setExtraData(const QString &key, const QVariant &value) { d->m_setup.m_extraData.insert(key, value); diff --git a/src/libs/utils/qtcprocess.h b/src/libs/utils/qtcprocess.h index a7e00882a31..3f043214f96 100644 --- a/src/libs/utils/qtcprocess.h +++ b/src/libs/utils/qtcprocess.h @@ -187,6 +187,9 @@ public: void setCreateConsoleOnWindows(bool create); bool createConsoleOnWindows() const; + void setForceDefaultErrorModeOnWindows(bool force); + bool forceDefaultErrorModeOnWindows() const; + signals: void starting(); // On NotRunning -> Starting state transition void started(); // On Starting -> Running state transition diff --git a/src/plugins/appstatisticsmonitor/idataprovider.cpp b/src/plugins/appstatisticsmonitor/idataprovider.cpp index f8cb70fddd6..8b149caf5cd 100644 --- a/src/plugins/appstatisticsmonitor/idataprovider.cpp +++ b/src/plugins/appstatisticsmonitor/idataprovider.cpp @@ -16,8 +16,19 @@ #endif #ifdef Q_OS_WIN -#include #include +#include +#endif + +#ifdef Q_OS_MACOS +#include +#include +#include + +#include +#include +#include +#include #endif using namespace Utils; @@ -258,9 +269,63 @@ public: : IDataProvider(pid, parent) {} - double getMemoryConsumption() { return 0; } + double getCpuConsumption() + { + proc_taskallinfo taskAllInfo = {}; - double getCpuConsumption() { return 0; } + const int result + = proc_pidinfo(m_pid, PROC_PIDTASKALLINFO, 0, &taskAllInfo, sizeof(taskAllInfo)); + if (result == -1) { + return 0; + } + + mach_timebase_info_data_t sTimebase; + mach_timebase_info(&sTimebase); + double timebase_to_ns = (double) sTimebase.numer / (double) sTimebase.denom; + + const double currentTotalCpuTime = ((double) taskAllInfo.ptinfo.pti_total_user + + (double) taskAllInfo.ptinfo.pti_total_system) + * timebase_to_ns / 1e9; + + const double cpuUsageDelta = currentTotalCpuTime - m_prevCpuUsage; + + const auto elapsedTime = std::chrono::steady_clock::now() - m_prevTime; + const double elapsedTimeSeconds + = std::chrono::duration_cast(elapsedTime).count() / 1000.0; + + m_prevCpuUsage = currentTotalCpuTime; + m_prevTime = std::chrono::steady_clock::now(); + + return (cpuUsageDelta / elapsedTimeSeconds) * 100.0; + } + + double getTotalPhysicalMemory() + { + int mib[2]; + size_t length; + long long physicalMemory; + + mib[0] = CTL_HW; + mib[1] = HW_MEMSIZE; + length = sizeof(physicalMemory); + sysctl(mib, 2, &physicalMemory, &length, NULL, 0); + + return physicalMemory; + } + + double getMemoryConsumption() + { + proc_taskinfo taskInfo; + int result = proc_pidinfo(m_pid, PROC_PIDTASKINFO, 0, &taskInfo, sizeof(taskInfo)); + if (result == -1) + return 0; + + return (taskInfo.pti_resident_size / getTotalPhysicalMemory()) * 100.0; + } + +private: + std::chrono::steady_clock::time_point m_prevTime = std::chrono::steady_clock::now(); + double m_prevCpuUsage = 0; }; #endif diff --git a/src/plugins/baremetal/iarewtoolchain.cpp b/src/plugins/baremetal/iarewtoolchain.cpp index ef804b0a8a2..d5029c78788 100644 --- a/src/plugins/baremetal/iarewtoolchain.cpp +++ b/src/plugins/baremetal/iarewtoolchain.cpp @@ -328,12 +328,11 @@ Toolchain::MacroInspectionRunner IarToolchain::createMacroInspectionRunner() con return [env, compiler, extraArgs, macrosCache, languageId] (const QStringList &flags) { - Q_UNUSED(flags) - - Macros macros = dumpPredefinedMacros(compiler, extraArgs, languageId, env); + Macros macros = dumpPredefinedMacros(compiler, extraArgs + flags, languageId, env); macros.append({"__intrinsic", "", MacroType::Define}); macros.append({"__nounwind", "", MacroType::Define}); macros.append({"__noreturn", "", MacroType::Define}); + macros.append({"__no_init", "", MacroType::Define}); macros.append({"__packed", "", MacroType::Define}); macros.append({"__spec_string", "", MacroType::Define}); macros.append({"__constrange(__a,__b)", "", MacroType::Define}); diff --git a/src/plugins/coreplugin/coreconstants.h b/src/plugins/coreplugin/coreconstants.h index d8d2388fb18..049ce35dec5 100644 --- a/src/plugins/coreplugin/coreconstants.h +++ b/src/plugins/coreplugin/coreconstants.h @@ -145,7 +145,8 @@ const char G_HELP[] = "QtCreator.Group.Help"; // File menu groups const char G_FILE_NEW[] = "QtCreator.Group.File.New"; const char G_FILE_OPEN[] = "QtCreator.Group.File.Open"; -const char G_FILE_SESSION[] = "QtCreator.Group.File.Recent"; +const char G_FILE_RECENT[] = "QtCreator.Group.File.Recent"; +const char G_FILE_SESSION[] = "QtCreator.Group.File.Session"; const char G_FILE_PROJECT[] = "QtCreator.Group.File.Project"; const char G_FILE_SAVE[] = "QtCreator.Group.File.Save"; const char G_FILE_EXPORT[] = "QtCreator.Group.File.Export"; diff --git a/src/plugins/coreplugin/dialogs/settingsdialog.cpp b/src/plugins/coreplugin/dialogs/settingsdialog.cpp index b2e4b9e969f..74fe67d8175 100644 --- a/src/plugins/coreplugin/dialogs/settingsdialog.cpp +++ b/src/plugins/coreplugin/dialogs/settingsdialog.cpp @@ -790,7 +790,7 @@ bool SettingsDialog::execDialog() ICore::settings()->setValueWithDefault(kPreferenceDialogSize, size(), initialSize); // make sure that the current "single" instance is deleted // we can't delete right away, since we still access the m_applied member - deleteLater(); + QMetaObject::invokeMethod(this, [this] { deleteLater(); }, Qt::QueuedConnection); }); } diff --git a/src/plugins/coreplugin/icore.cpp b/src/plugins/coreplugin/icore.cpp index a4098963a60..83a0cb3cdc4 100644 --- a/src/plugins/coreplugin/icore.cpp +++ b/src/plugins/coreplugin/icore.cpp @@ -1629,6 +1629,7 @@ void ICorePrivate::registerDefaultContainers() filemenu->menu()->setTitle(Tr::tr("&File")); filemenu->appendGroup(Constants::G_FILE_NEW); filemenu->appendGroup(Constants::G_FILE_OPEN); + filemenu->appendGroup(Constants::G_FILE_RECENT); filemenu->appendGroup(Constants::G_FILE_SESSION); filemenu->appendGroup(Constants::G_FILE_PROJECT); filemenu->appendGroup(Constants::G_FILE_SAVE); @@ -1785,7 +1786,7 @@ void ICorePrivate::registerDefaultActions() // File->Recent Files Menu ActionContainer *ac = ActionManager::createMenu(Constants::M_FILE_RECENTFILES); - mfile->addMenu(ac, Constants::G_FILE_OPEN); + mfile->addMenu(ac, Constants::G_FILE_RECENT); ac->menu()->setTitle(Tr::tr("Recent &Files")); ac->setOnAllDisabledBehavior(ActionContainer::Show); diff --git a/src/plugins/coreplugin/images/mode_design_mask.png b/src/plugins/coreplugin/images/mode_design_mask.png index 42013edf352..c2a82ef8914 100644 Binary files a/src/plugins/coreplugin/images/mode_design_mask.png and b/src/plugins/coreplugin/images/mode_design_mask.png differ diff --git a/src/plugins/coreplugin/images/mode_design_mask@2x.png b/src/plugins/coreplugin/images/mode_design_mask@2x.png index 2aef9018a8a..9a060d74983 100644 Binary files a/src/plugins/coreplugin/images/mode_design_mask@2x.png and b/src/plugins/coreplugin/images/mode_design_mask@2x.png differ diff --git a/src/plugins/coreplugin/images/mode_edit_mask.png b/src/plugins/coreplugin/images/mode_edit_mask.png index 51197249c0a..b2a455b77b2 100644 Binary files a/src/plugins/coreplugin/images/mode_edit_mask.png and b/src/plugins/coreplugin/images/mode_edit_mask.png differ diff --git a/src/plugins/coreplugin/images/mode_edit_mask@2x.png b/src/plugins/coreplugin/images/mode_edit_mask@2x.png index 389ac6dc4e3..28bfd901983 100644 Binary files a/src/plugins/coreplugin/images/mode_edit_mask@2x.png and b/src/plugins/coreplugin/images/mode_edit_mask@2x.png differ diff --git a/src/plugins/coreplugin/plugininstallwizard.cpp b/src/plugins/coreplugin/plugininstallwizard.cpp index 250ed0a31a5..e9f91ffbb8e 100644 --- a/src/plugins/coreplugin/plugininstallwizard.cpp +++ b/src/plugins/coreplugin/plugininstallwizard.cpp @@ -162,7 +162,7 @@ void checkContents(QPromise &promise, const FilePath &tempDir) [coreplugin](const PluginDependency &d) { return d.name == coreplugin->name(); }); if (found == dependencies.constEnd()) return; - if (coreplugin->provides(found->name, found->version)) + if ((*spec)->provides(coreplugin, *found)) return; promise.addResult( ArchiveIssue{Tr::tr("Plugin requires an incompatible version of %1 (%2).") diff --git a/src/plugins/cppeditor/cppfilesettingspage.cpp b/src/plugins/cppeditor/cppfilesettingspage.cpp index a5c01b400b1..70f17e9afe8 100644 --- a/src/plugins/cppeditor/cppfilesettingspage.cpp +++ b/src/plugins/cppeditor/cppfilesettingspage.cpp @@ -744,6 +744,8 @@ void setupCppFileSettings(ExtensionSystem::IPlugin &plugin) #ifdef WITH_TESTS plugin.addTestCreator([] { return new CppFileSettingsTest; }); +#else + Q_UNUSED(plugin) #endif } diff --git a/src/plugins/cppeditor/testcases/move-class/complex/theclass.h_expected b/src/plugins/cppeditor/testcases/move-class/complex/theclass.h_expected index c7db776d277..12df0c76295 100644 --- a/src/plugins/cppeditor/testcases/move-class/complex/theclass.h_expected +++ b/src/plugins/cppeditor/testcases/move-class/complex/theclass.h_expected @@ -1,5 +1,5 @@ -#ifndef PROJECT_INTERNAL_THECLASS_H -#define PROJECT_INTERNAL_THECLASS_H +#ifndef THECLASS_H +#define THECLASS_H namespace Project { namespace Internal { @@ -26,4 +26,4 @@ template T TheClass::defaultValue() const { return T(); } } // namespace Internal } // namespace Project -#endif // PROJECT_INTERNAL_THECLASS_H +#endif // THECLASS_H diff --git a/src/plugins/debugger/CMakeLists.txt b/src/plugins/debugger/CMakeLists.txt index 8f338dd9819..fc405a7fe3a 100644 --- a/src/plugins/debugger/CMakeLists.txt +++ b/src/plugins/debugger/CMakeLists.txt @@ -33,6 +33,7 @@ add_qtc_plugin(Debugger dap/dapclient.cpp dap/dapclient.h dap/dapengine.cpp dap/dapengine.h dap/gdbdapengine.cpp dap/gdbdapengine.h + dap/lldbdapengine.cpp dap/lldbdapengine.h dap/pydapengine.cpp dap/pydapengine.h debugger.qrc debugger_global.h diff --git a/src/plugins/debugger/dap/dapengine.cpp b/src/plugins/debugger/dap/dapengine.cpp index d2f94b9feeb..e311bb36822 100644 --- a/src/plugins/debugger/dap/dapengine.cpp +++ b/src/plugins/debugger/dap/dapengine.cpp @@ -6,6 +6,7 @@ #include "cmakedapengine.h" #include "dapclient.h" #include "gdbdapengine.h" +#include "lldbdapengine.h" #include "pydapengine.h" #include @@ -1058,6 +1059,8 @@ DebuggerEngine *createDapEngine(Utils::Id runMode) return new CMakeDapEngine; if (runMode == ProjectExplorer::Constants::DAP_GDB_DEBUG_RUN_MODE) return new GdbDapEngine; + if (runMode == ProjectExplorer::Constants::DAP_LLDB_DEBUG_RUN_MODE) + return new LldbDapEngine; if (runMode == ProjectExplorer::Constants::DAP_PY_DEBUG_RUN_MODE) return new PyDapEngine; diff --git a/src/plugins/debugger/dap/lldbdapengine.cpp b/src/plugins/debugger/dap/lldbdapengine.cpp new file mode 100644 index 00000000000..32a85c89d41 --- /dev/null +++ b/src/plugins/debugger/dap/lldbdapengine.cpp @@ -0,0 +1,176 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0 + +#include "lldbdapengine.h" + +#include "dapclient.h" + +#include + +#include + +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +using namespace Core; +using namespace Utils; + +namespace Debugger::Internal { + +// TODO: Same class as in gdbdapengine.cpp. Refactor into one place. +class ProcessDataProvider : public IDataProvider +{ +public: + ProcessDataProvider(const DebuggerRunParameters &rp, + const CommandLine &cmd, + QObject *parent = nullptr) + : IDataProvider(parent) + , m_runParameters(rp) + , m_cmd(cmd) + { + connect(&m_proc, &Process::started, this, &IDataProvider::started); + connect(&m_proc, &Process::done, this, &IDataProvider::done); + connect(&m_proc, + &Process::readyReadStandardOutput, + this, + &IDataProvider::readyReadStandardOutput); + connect(&m_proc, + &Process::readyReadStandardError, + this, + &IDataProvider::readyReadStandardError); + } + + ~ProcessDataProvider() + { + m_proc.kill(); + m_proc.waitForFinished(); + } + + void start() override + { + m_proc.setProcessMode(ProcessMode::Writer); + if (m_runParameters.debugger.workingDirectory.isDir()) + m_proc.setWorkingDirectory(m_runParameters.debugger.workingDirectory); + m_proc.setEnvironment(m_runParameters.debugger.environment); + m_proc.setCommand(m_cmd); + m_proc.start(); + } + + bool isRunning() const override { return m_proc.isRunning(); } + void writeRaw(const QByteArray &data) override + { + if (m_proc.state() == QProcess::Running) + m_proc.writeRaw(data); + } + void kill() override { m_proc.kill(); } + QByteArray readAllStandardOutput() override { return m_proc.readAllStandardOutput().toUtf8(); } + QString readAllStandardError() override { return m_proc.readAllStandardError(); } + int exitCode() const override { return m_proc.exitCode(); } + QString executable() const override { return m_proc.commandLine().executable().toUserOutput(); } + + QProcess::ExitStatus exitStatus() const override { return m_proc.exitStatus(); } + QProcess::ProcessError error() const override { return m_proc.error(); } + Utils::ProcessResult result() const override { return m_proc.result(); } + QString exitMessage() const override { return m_proc.exitMessage(); }; + +private: + Utils::Process m_proc; + const DebuggerRunParameters m_runParameters; + const CommandLine m_cmd; +}; + +class LldbDapClient : public DapClient +{ +public: + LldbDapClient(IDataProvider *provider, QObject *parent = nullptr) + : DapClient(provider, parent) + {} + +private: + const QLoggingCategory &logCategory() override + { + static const QLoggingCategory logCategory = QLoggingCategory("qtc.dbg.dapengine.lldb", + QtWarningMsg); + return logCategory; + } +}; + +LldbDapEngine::LldbDapEngine() + : DapEngine() +{ + setObjectName("LldbDapEngine"); + setDebuggerName("LLDB"); + setDebuggerType("DAP"); +} + +void LldbDapEngine::handleDapInitialize() +{ + if (!isLocalAttachEngine()) { + DapEngine::handleDapInitialize(); + return; + } + + QTC_ASSERT(state() == EngineRunRequested, qCDebug(logCategory()) << state()); + m_dapClient->postRequest("attach", QJsonObject{{"__restart", ""}}); + qCDebug(logCategory()) << "handleDapAttach"; +} + +bool LldbDapEngine::isLocalAttachEngine() const +{ + return runParameters().startMode == AttachToLocalProcess; +} + +void LldbDapEngine::handleDapConfigurationDone() +{ + if (!isLocalAttachEngine()) { + DapEngine::handleDapConfigurationDone(); + return; + } + + notifyEngineRunAndInferiorStopOk(); +} + +void LldbDapEngine::setupEngine() +{ + QTC_ASSERT(state() == EngineSetupRequested, qCDebug(logCategory()) << state()); + + const DebuggerRunParameters &rp = runParameters(); + CommandLine cmd{rp.debugger.command.executable()}; + + if (isLocalAttachEngine()) + cmd.addArgs({"--debugger-pid", QString::number(rp.attachPID.pid())}); + + IDataProvider *dataProvider = new ProcessDataProvider(rp, cmd, this); + m_dapClient = new LldbDapClient(dataProvider, this); + + connectDataGeneratorSignals(); + m_dapClient->dataProvider()->start(); +} + +bool LldbDapEngine::acceptsBreakpoint(const BreakpointParameters &bp) const +{ + const auto mimeType = Utils::mimeTypeForFile(bp.fileName); + return mimeType.matchesName(Utils::Constants::C_HEADER_MIMETYPE) + || mimeType.matchesName(Utils::Constants::C_SOURCE_MIMETYPE) + || mimeType.matchesName(Utils::Constants::CPP_HEADER_MIMETYPE) + || mimeType.matchesName(Utils::Constants::CPP_SOURCE_MIMETYPE) + || bp.type == BreakpointByFunction; +} + +const QLoggingCategory &LldbDapEngine::logCategory() +{ + static const QLoggingCategory logCategory = QLoggingCategory("qtc.dbg.dapengine.lldb", + QtWarningMsg); + return logCategory; +} + +} // namespace Debugger::Internal diff --git a/src/plugins/debugger/dap/lldbdapengine.h b/src/plugins/debugger/dap/lldbdapengine.h new file mode 100644 index 00000000000..276714dccd5 --- /dev/null +++ b/src/plugins/debugger/dap/lldbdapengine.h @@ -0,0 +1,26 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0 + +#pragma once + +#include "dapengine.h" + +namespace Debugger::Internal { + +class LldbDapEngine : public DapEngine +{ +public: + LldbDapEngine(); + +private: + void setupEngine() override; + + void handleDapInitialize() override; + void handleDapConfigurationDone() override; + + bool isLocalAttachEngine() const; + bool acceptsBreakpoint(const BreakpointParameters &bp) const override; + const QLoggingCategory &logCategory() override; +}; + +} // Debugger::Internal diff --git a/src/plugins/debugger/debugger.qbs b/src/plugins/debugger/debugger.qbs index 3c5825eb627..ed54252ef72 100644 --- a/src/plugins/debugger/debugger.qbs +++ b/src/plugins/debugger/debugger.qbs @@ -123,6 +123,7 @@ QtcPlugin { "dapclient.cpp", "dapclient.h", "dapengine.cpp", "dapengine.h", "gdbdapengine.cpp", "gdbdapengine.h", + "lldbdapengine.cpp", "lldbdapengine.h", "pydapengine.cpp", "pydapengine.h", ] } diff --git a/src/plugins/debugger/debuggeritem.cpp b/src/plugins/debugger/debuggeritem.cpp index dff784341a7..6cf45ac13e1 100644 --- a/src/plugins/debugger/debuggeritem.cpp +++ b/src/plugins/debugger/debuggeritem.cpp @@ -147,27 +147,16 @@ void DebuggerItem::reinitializeFromFile(QString *error, Utils::Environment *cust Environment env = customEnv ? *customEnv : m_command.deviceEnvironment(); - // Prevent calling lldb on Windows because the lldb from the llvm package is linked against - // python but does not contain a python dll. - const bool isAndroidNdkLldb = DebuggerItem::addAndroidLldbPythonEnv(m_command, env); - const FilePath qtcreatorLldb = Core::ICore::lldbExecutable(CLANG_BINDIR); - if (HostOsInfo::isWindowsHost() && m_command.fileName().startsWith("lldb") && !isAndroidNdkLldb - && qtcreatorLldb != m_command) { - QString errorMessage; - m_version = winGetDLLVersion(WinDLLFileVersion, - m_command.absoluteFilePath().path(), - &errorMessage); - m_engineType = LldbEngineType; - m_abis = Abi::abisOfBinary(m_command); - return; - } - // QNX gdb unconditionally checks whether the QNX_TARGET env variable is // set and bails otherwise, even when it is not used by the specific // codepath triggered by the --version and --configuration arguments. The // hack below tricks it into giving us the information we want. env.set("QNX_TARGET", QString()); + // On Windows, we need to prevent the Windows Error Reporting dialog from + // popping up when a candidate is missing required DLLs. + WindowsCrashDialogBlocker blocker; + Process proc; proc.setEnvironment(env); proc.setCommand({m_command, {version}}); diff --git a/src/plugins/debugger/debuggerplugin.cpp b/src/plugins/debugger/debuggerplugin.cpp index cc3c847b636..527c6649209 100644 --- a/src/plugins/debugger/debuggerplugin.cpp +++ b/src/plugins/debugger/debuggerplugin.cpp @@ -1224,6 +1224,7 @@ void DebuggerPluginPrivate::createDapDebuggerPerspective(QWidget *globalLogWindo ProjectExplorer::Constants::DAP_CMAKE_DEBUG_RUN_MODE, /*forceSkipDeploy=*/true}, DapPerspective{Tr::tr("GDB Preset"), ProjectExplorer::Constants::DAP_GDB_DEBUG_RUN_MODE}, + DapPerspective{Tr::tr("LLDB Preset"), ProjectExplorer::Constants::DAP_LLDB_DEBUG_RUN_MODE}, DapPerspective{Tr::tr("Python Preset"), ProjectExplorer::Constants::DAP_PY_DEBUG_RUN_MODE}, }; diff --git a/src/plugins/debugger/debuggerruncontrol.cpp b/src/plugins/debugger/debuggerruncontrol.cpp index 2f980f7fdc4..b14e9ee30b0 100644 --- a/src/plugins/debugger/debuggerruncontrol.cpp +++ b/src/plugins/debugger/debuggerruncontrol.cpp @@ -1096,6 +1096,7 @@ DebuggerRunWorkerFactory::DebuggerRunWorkerFactory() addSupportedRunMode(ProjectExplorer::Constants::DEBUG_RUN_MODE); addSupportedRunMode(ProjectExplorer::Constants::DAP_CMAKE_DEBUG_RUN_MODE); addSupportedRunMode(ProjectExplorer::Constants::DAP_GDB_DEBUG_RUN_MODE); + addSupportedRunMode(ProjectExplorer::Constants::DAP_LLDB_DEBUG_RUN_MODE); addSupportedDeviceType(ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE); addSupportedDeviceType("DockerDeviceType"); diff --git a/src/plugins/debugger/images/debugger_continue_1_mask.png b/src/plugins/debugger/images/debugger_continue_1_mask.png index 1f5c0c56551..c2196afa953 100644 Binary files a/src/plugins/debugger/images/debugger_continue_1_mask.png and b/src/plugins/debugger/images/debugger_continue_1_mask.png differ diff --git a/src/plugins/debugger/images/debugger_continue_1_mask@2x.png b/src/plugins/debugger/images/debugger_continue_1_mask@2x.png index e3e06daa9d2..c3cb2a62bec 100644 Binary files a/src/plugins/debugger/images/debugger_continue_1_mask@2x.png and b/src/plugins/debugger/images/debugger_continue_1_mask@2x.png differ diff --git a/src/plugins/debugger/images/debugger_continue_2_mask.png b/src/plugins/debugger/images/debugger_continue_2_mask.png index 8b83259ed13..ad34cf8e8ec 100644 Binary files a/src/plugins/debugger/images/debugger_continue_2_mask.png and b/src/plugins/debugger/images/debugger_continue_2_mask.png differ diff --git a/src/plugins/debugger/images/debugger_continue_2_mask@2x.png b/src/plugins/debugger/images/debugger_continue_2_mask@2x.png index 860f76ca187..b0d8ca27baa 100644 Binary files a/src/plugins/debugger/images/debugger_continue_2_mask@2x.png and b/src/plugins/debugger/images/debugger_continue_2_mask@2x.png differ diff --git a/src/plugins/debugger/images/debugger_interrupt_mask.png b/src/plugins/debugger/images/debugger_interrupt_mask.png index 52f4f275b9f..6961370069b 100644 Binary files a/src/plugins/debugger/images/debugger_interrupt_mask.png and b/src/plugins/debugger/images/debugger_interrupt_mask.png differ diff --git a/src/plugins/debugger/images/debugger_interrupt_mask@2x.png b/src/plugins/debugger/images/debugger_interrupt_mask@2x.png index c7794000177..dc4ae99aa0e 100644 Binary files a/src/plugins/debugger/images/debugger_interrupt_mask@2x.png and b/src/plugins/debugger/images/debugger_interrupt_mask@2x.png differ diff --git a/src/plugins/debugger/images/debugger_stop_mask.png b/src/plugins/debugger/images/debugger_stop_mask.png index d56a35f4857..4e0562ea142 100644 Binary files a/src/plugins/debugger/images/debugger_stop_mask.png and b/src/plugins/debugger/images/debugger_stop_mask.png differ diff --git a/src/plugins/debugger/images/debugger_stop_mask@2x.png b/src/plugins/debugger/images/debugger_stop_mask@2x.png index e69d67dfaf8..fb84f3ad793 100644 Binary files a/src/plugins/debugger/images/debugger_stop_mask@2x.png and b/src/plugins/debugger/images/debugger_stop_mask@2x.png differ diff --git a/src/plugins/debugger/images/mode_debug_mask.png b/src/plugins/debugger/images/mode_debug_mask.png index fe7b6819a5b..63954678400 100644 Binary files a/src/plugins/debugger/images/mode_debug_mask.png and b/src/plugins/debugger/images/mode_debug_mask.png differ diff --git a/src/plugins/debugger/images/mode_debug_mask@2x.png b/src/plugins/debugger/images/mode_debug_mask@2x.png index 5340947ec75..83b6893b532 100644 Binary files a/src/plugins/debugger/images/mode_debug_mask@2x.png and b/src/plugins/debugger/images/mode_debug_mask@2x.png differ diff --git a/src/plugins/fakevim/fakevimplugin.cpp b/src/plugins/fakevim/fakevimplugin.cpp index a84598aec00..6909c4d35a7 100644 --- a/src/plugins/fakevim/fakevimplugin.cpp +++ b/src/plugins/fakevim/fakevimplugin.cpp @@ -1502,7 +1502,7 @@ void FakeVimPlugin::editorOpened(IEditor *editor) handler->modeChanged.set([tew, this, editor](bool insertMode) { HandlerAndData &handlerAndData = m_editorToHandler[editor]; - if (!handlerAndData.handler->inFakeVimMode()) + if (!handlerAndData.handler || !handlerAndData.handler->inFakeVimMode()) return; // We don't want to show suggestions unless we are in insert mode. @@ -1651,11 +1651,13 @@ void FakeVimPlugin::editorOpened(IEditor *editor) keepOnlyWindow(); else if (key == "P" || key == "") triggerAction(Core::Constants::GOTO_PREV_SPLIT); - else if (key == "S" || key == "") + else if (key == "S" || key == "") { triggerAction(Core::Constants::SPLIT); - else if (key == "V" || key == "") + updateAllHightLights(); + } else if (key == "V" || key == "") { triggerAction(Core::Constants::SPLIT_SIDE_BY_SIDE); - else if (key == "W" || key == "") + updateAllHightLights(); + } else if (key == "W" || key == "") triggerAction(Core::Constants::GOTO_NEXT_SPLIT); else if (key.contains("RIGHT") || key == "L" || key == "" || key == "") moveSomewhere(handler, &moveRightWeight, key == "" ? -1 : count); diff --git a/src/plugins/help/images/mode_help_mask.png b/src/plugins/help/images/mode_help_mask.png index 144871e8542..a6542695d2d 100644 Binary files a/src/plugins/help/images/mode_help_mask.png and b/src/plugins/help/images/mode_help_mask.png differ diff --git a/src/plugins/help/images/mode_help_mask@2x.png b/src/plugins/help/images/mode_help_mask@2x.png index 50f12d8e117..e50cb34fea4 100644 Binary files a/src/plugins/help/images/mode_help_mask@2x.png and b/src/plugins/help/images/mode_help_mask@2x.png differ diff --git a/src/plugins/ios/devicectlutils.cpp b/src/plugins/ios/devicectlutils.cpp index 7bbed859b27..667f1bc54a9 100644 --- a/src/plugins/ios/devicectlutils.cpp +++ b/src/plugins/ios/devicectlutils.cpp @@ -73,6 +73,7 @@ expected_str> parseDeviceInfo(const QByteArray &rawOutput info[kOsVersion] = QLatin1String("%1 (%2)") .arg(device["deviceProperties"]["osVersionNumber"].toString(), device["deviceProperties"]["osBuildUpdate"].toString()); + info[kProductType] = device["hardwareProperties"]["productType"].toString(); info[kCpuArchitecture] = device["hardwareProperties"]["cpuType"]["name"].toString(); info[kUniqueDeviceId] = udid; return info; diff --git a/src/plugins/ios/devicectlutils.h b/src/plugins/ios/devicectlutils.h index 106fee78a23..cb470cff29a 100644 --- a/src/plugins/ios/devicectlutils.h +++ b/src/plugins/ios/devicectlutils.h @@ -13,6 +13,7 @@ const char kDeviceName[] = "deviceName"; const char kDeveloperStatus[] = "developerStatus"; const char kDeviceConnected[] = "deviceConnected"; const char kOsVersion[] = "osVersion"; +const char kProductType[] = "productType"; const char kCpuArchitecture[] = "cpuArchitecture"; const char kUniqueDeviceId[] = "uniqueDeviceId"; const char vOff[] = "*off*"; diff --git a/src/plugins/ios/iosdevice.cpp b/src/plugins/ios/iosdevice.cpp index e81c263672b..0dd75896e06 100644 --- a/src/plugins/ios/iosdevice.cpp +++ b/src/plugins/ios/iosdevice.cpp @@ -92,8 +92,9 @@ public: Form { Tr::tr("Device name:"), iosDevice->deviceName(), br, Tr::tr("Identifier:"), iosDevice->uniqueInternalDeviceId(), br, + Tr::tr("Product type:"), iosDevice->productType(), br, + Tr::tr("CPU Architecture:"), iosDevice->cpuArchitecture(), br, Tr::tr("OS Version:"), iosDevice->osVersion(), br, - Tr::tr("CPU Architecture:"), iosDevice->cpuArchitecture(), noMargin }.attachTo(this); // clang-format on @@ -193,6 +194,11 @@ QString IosDevice::osVersion() const return m_extraInfo.value(kOsVersion); } +QString IosDevice::productType() const +{ + return m_extraInfo.value(kProductType); +} + QString IosDevice::cpuArchitecture() const { return m_extraInfo.value(kCpuArchitecture); @@ -227,6 +233,7 @@ IosDeviceManager::TranslationMap IosDeviceManager::translationMap() tMap[QLatin1String("NO")] = Tr::tr("no"); tMap[QLatin1String("*unknown*")] = Tr::tr("unknown"); tMap[kOsVersion] = Tr::tr("OS version"); + tMap[kProductType] = Tr::tr("Product type"); translationMap = &tMap; return tMap; } diff --git a/src/plugins/ios/iosdevice.h b/src/plugins/ios/iosdevice.h index 62a7f2bb93a..b8ec2871347 100644 --- a/src/plugins/ios/iosdevice.h +++ b/src/plugins/ios/iosdevice.h @@ -37,6 +37,7 @@ public: QString uniqueDeviceID() const; QString uniqueInternalDeviceId() const; QString osVersion() const; + QString productType() const; QString cpuArchitecture() const; Utils::Port nextPort() const; Handler handler() const; diff --git a/src/plugins/ios/iosrunner.cpp b/src/plugins/ios/iosrunner.cpp index 863a2867b8a..1d4bd33aa11 100644 --- a/src/plugins/ios/iosrunner.cpp +++ b/src/plugins/ios/iosrunner.cpp @@ -813,14 +813,17 @@ void IosDebugSupport::start() setStartMode(AttachToRemoteProcess); setIosPlatform("remote-ios"); const QString osVersion = dev->osVersion(); + const QString productType = dev->productType(); const QString cpuArchitecture = dev->cpuArchitecture(); - const FilePaths symbolsPathCandidates = { - FilePath::fromString(QDir::homePath() + "/Library/Developer/Xcode/iOS DeviceSupport/" - + osVersion + " " + cpuArchitecture + "/Symbols"), - FilePath::fromString(QDir::homePath() + "/Library/Developer/Xcode/iOS DeviceSupport/" - + osVersion + "/Symbols"), - IosConfigurations::developerPath().pathAppended( - "Platforms/iPhoneOS.platform/DeviceSupport/" + osVersion + "/Symbols")}; + const FilePath home = FilePath::fromString(QDir::homePath()); + const FilePaths symbolsPathCandidates + = {home / "Library/Developer/Xcode/iOS DeviceSupport" / (productType + " " + osVersion) + / "Symbols", + home / "Library/Developer/Xcode/iOS DeviceSupport" + / (osVersion + " " + cpuArchitecture) / "Symbols", + home / "Library/Developer/Xcode/iOS DeviceSupport" / osVersion / "Symbols", + IosConfigurations::developerPath() / "Platforms/iPhoneOS.platform/DeviceSupport" + / osVersion / "Symbols"}; const FilePath deviceSdk = Utils::findOrDefault(symbolsPathCandidates, &FilePath::isDir); if (deviceSdk.isEmpty()) { diff --git a/src/plugins/lua/README.md b/src/plugins/lua/README.md index 108420735ed..2607d47f182 100644 --- a/src/plugins/lua/README.md +++ b/src/plugins/lua/README.md @@ -6,7 +6,7 @@ The Lua plugin provides support for writing plugins using the Lua scripting lang ## Usage -The plugin scans the folder `lua-plugins` folder inside the normal plugin folder of Qt Creator +The plugin scans the normal plugin folders of Qt Creator `ExtensionSystem::PluginManager::pluginPaths()`. It loads scripts from any folder that contains a .lua script named the same as the folder. Whether or not the script is enabled is determined by the `disabledByDefault` field in the plugin @@ -17,7 +17,7 @@ table and the settings configured via the "About Plugins" dialog in Qt Creator. A Lua script needs to provide the following table to be considered a plugin: ```lua --- lua-plugins/myluaplugin/myluaplugin.lua +-- myluaplugin/myluaplugin.lua return { name = "MyLuaPlugin", version = "1.0.0", @@ -40,7 +40,7 @@ Can contain newlines. disabledByDefault = false, dependencies = { - { name="Core", version = "12.0.0" } + { name="Core", version = "14.0.0" } }, } --[[@as QtcPlugin]] ``` @@ -50,13 +50,13 @@ It must only return the plugin specification table and not execute or require an Use `require` to load other files from within the setup function. ```lua --- lua-plugins/myluaplugin/myluaplugin.lua +-- myluaplugin/myluaplugin.lua return { -- ... required fields omitted .. setup = function() require 'init'.setup() end, } --[[@as QtcPlugin]] --- lua-plugins/myluaplugin/init.lua +-- myluaplugin/init.lua local function setup() print("Hello from Lua!") end diff --git a/src/plugins/lua/luaplugin.cpp b/src/plugins/lua/luaplugin.cpp index 60505ade850..0290df988c3 100644 --- a/src/plugins/lua/luaplugin.cpp +++ b/src/plugins/lua/luaplugin.cpp @@ -49,24 +49,6 @@ public: } }; -struct Arguments -{ - std::optional loadPlugin; -}; - -Arguments parseArguments(const QStringList &arguments) -{ - Arguments args; - for (int i = 0; i < arguments.size() - 1; ++i) { - if (arguments.at(i) == QLatin1String("-loadluaplugin")) { - const QString path(arguments.at(i + 1)); - args.loadPlugin = FilePath::fromUserInput(path); - i++; // skip the argument - } - } - return args; -} - class LuaPlugin : public IPlugin { Q_OBJECT @@ -74,18 +56,15 @@ class LuaPlugin : public IPlugin private: std::unique_ptr m_luaEngine; - Arguments m_arguments; public: LuaPlugin() {} ~LuaPlugin() override = default; - bool initialize(const QStringList &arguments, QString *) final + void initialize() final { m_luaEngine.reset(new LuaEngine()); - m_arguments = parseArguments(arguments); - addAsyncModule(); addFetchModule(); addActionModule(); @@ -100,27 +79,25 @@ public: addInstallModule(); Core::JsExpander::registerGlobalObject("Lua", [] { return new LuaJsExtension(); }); - - return true; } bool delayedInitialize() final { - scanForPlugins(transform(PluginManager::pluginPaths(), [](const FilePath &path) { - return path / "lua-plugins"; - })); - + scanForPlugins(PluginManager::pluginPaths()); return true; } - void scanForPlugins(const FilePaths &paths) + void scanForPlugins(const FilePaths &pluginPaths) { QSet plugins; - for (const FilePath &path : paths) { + for (const FilePath &path : pluginPaths) { FilePaths folders = path.dirEntries(FileFilter({}, QDir::Dirs | QDir::NoDotAndDotDot)); for (const FilePath &folder : folders) { const FilePath script = folder / (folder.baseName() + ".lua"); + if (!script.exists()) + continue; + const expected_str result = m_luaEngine->loadPlugin(script); if (!result) { @@ -135,23 +112,6 @@ public: } } - if (m_arguments.loadPlugin) { - const FilePath folder = *m_arguments.loadPlugin; - const FilePath script = folder / (folder.baseName() + ".lua"); - const expected_str result = m_luaEngine->loadPlugin(script); - - if (!result) { - qWarning() << "Failed to load plugin" << script << ":" << result.error(); - MessageManager::writeFlashing(tr("Failed to load plugin %1: %2") - .arg(script.toUserOutput()) - .arg(result.error())); - - } else { - (*result)->setEnabledBySettings(true); - plugins.insert(*result); - } - } - PluginManager::addPlugins({plugins.begin(), plugins.end()}); PluginManager::loadPluginsAtRuntime(plugins); } diff --git a/src/plugins/lua/luapluginspec.cpp b/src/plugins/lua/luapluginspec.cpp index c3fcd558a55..4d0e9d76708 100644 --- a/src/plugins/lua/luapluginspec.cpp +++ b/src/plugins/lua/luapluginspec.cpp @@ -9,6 +9,7 @@ #include #include +#include #include #include @@ -76,6 +77,19 @@ ExtensionSystem::IPlugin *LuaPluginSpec::plugin() const return nullptr; } +bool LuaPluginSpec::provides(PluginSpec *spec, const PluginDependency &dependency) const +{ + if (QString::compare(dependency.name, spec->name(), Qt::CaseInsensitive) != 0) + return false; + + // Since we first released the lua support with Qt Creator 14.0.0, but the internal version + // number was still 13.0.82, we needed to special case this version. + if (versionCompare(dependency.version, "14.0.0") <= 0) + return true; + + return (versionCompare(spec->version(), dependency.version) >= 0); +} + // LuaPluginSpec::For internal use {} bool LuaPluginSpec::loadLibrary() { diff --git a/src/plugins/lua/luapluginspec.h b/src/plugins/lua/luapluginspec.h index 7c2ab3318bd..ff042416669 100644 --- a/src/plugins/lua/luapluginspec.h +++ b/src/plugins/lua/luapluginspec.h @@ -44,6 +44,9 @@ public: ExtensionSystem::IPlugin *plugin() const override; + bool provides( + PluginSpec *spec, const ExtensionSystem::PluginDependency &dependency) const override; + // For internal use only bool loadLibrary() override; bool initializePlugin() override; diff --git a/src/plugins/lua/meta/action.lua b/src/plugins/lua/meta/action.lua index 713dbcddb3a..48a1f49594b 100644 --- a/src/plugins/lua/meta/action.lua +++ b/src/plugins/lua/meta/action.lua @@ -4,30 +4,30 @@ local action = {} ---@enum CommandAttributes action.CommandAttribute = { - ---Hide the command from the menu + ---Hide the command from the menu. CA_Hide = 1, - ---Update the text of the command + ---Update the text of the command. CA_UpdateText = 2, - ---Update the icon of the command + ---Update the icon of the command. CA_UpdateIcon = 4, - ---The command cannot be configured + ---The command cannot be configured. CA_NonConfigurable = 8, } ---@class ActionOptions ----@field context? string The context in which the action is available ----@field text? string The text to display for the action ----@field iconText? string The icon text to display for the action ----@field toolTip? string The tooltip to display for the action ----@field onTrigger? function The callback to call when the action is triggered ----@field commandAttributes? CommandAttributes The attributes of the action ----@field commandDescription? string The description of the command ----@field defaultKeySequence? string The default key sequence for the action ----@field defaultKeySequences? string[] The default key sequences for the action +---@field context? string The context in which the action is available. +---@field text? string The text to display for the action. +---@field iconText? string The icon text to display for the action. +---@field toolTip? string The tooltip to display for the action. +---@field onTrigger? function The callback to call when the action is triggered. +---@field commandAttributes? CommandAttributes The attributes of the action. +---@field commandDescription? string The description of the command. +---@field defaultKeySequence? string The default key sequence for the action. +---@field defaultKeySequences? string[] The default key sequences for the action. local ActionOptions = {} ----Creates a new Action ----@param id string The id of the action +---Creates a new Action. +---@param id string The id of the action. ---@param options ActionOptions function action.create(id, options) end diff --git a/src/plugins/lua/meta/async.lua b/src/plugins/lua/meta/async.lua index 8f7232a001a..fee1f1a48f7 100644 --- a/src/plugins/lua/meta/async.lua +++ b/src/plugins/lua/meta/async.lua @@ -20,7 +20,7 @@ local async = {} function async.sync(func) end ---@async ----Calls an async function and waits for it to finish. **Must** be called from async.sync() +---Calls an async function and waits for it to finish. **Must** be called from async.sync(). --- --- Example: --- ```lua @@ -39,7 +39,7 @@ function async.sync(func) end function async.wait(func) end ---@async ----Calls multiple async functions and waits for all of them to finish. **Must** be called from async.sync() +---Calls multiple async functions and waits for all of them to finish. **Must** be called from async.sync(). --- --- Example: --- ```lua diff --git a/src/plugins/lua/meta/core.lua b/src/plugins/lua/meta/core.lua index e30e55e73db..3ad61a2d1dd 100644 --- a/src/plugins/lua/meta/core.lua +++ b/src/plugins/lua/meta/core.lua @@ -16,10 +16,10 @@ Core.GeneratedFile.Attribute = { ---@field filePath FilePath ---@field contents string ---@field isBinary boolean ----@field attributes Attribute A combination of Attribute +---@field attributes Attribute A combination of Attribute. Core.GeneratedFile = {} ----Create a new GeneratedFile +---Create a new GeneratedFile. ---@return GeneratedFile function Core.GeneratedFile.new() end diff --git a/src/plugins/lua/meta/fetch.lua b/src/plugins/lua/meta/fetch.lua index 877f6c99f66..ada2b07d4ae 100644 --- a/src/plugins/lua/meta/fetch.lua +++ b/src/plugins/lua/meta/fetch.lua @@ -1,12 +1,12 @@ ---@meta Fetch local Fetch = {} ----A network reply from fetch +---A network reply from fetch. ---@class QNetworkReply ----@field error integer The error code of the reply or 0 if no error +---@field error integer The error code of the reply or 0 if no error. local QNetworkReply = {} ----Returns the data of the reply +---Returns the data of the reply. ---@return string function QNetworkReply:readAll() end @@ -16,15 +16,15 @@ function QNetworkReply:readAll() end function Fetch.fetch(options) end --@param options FetchOptions ---@param callback function The callback to call when the fetch is done +--@param callback function The callback to call when the fetch is done. function Fetch.fetch_cb(options, callback) end ---@class FetchOptions ----@field url string The url to fetch ----@field method? string The method to use (GET, POST, ...), default is GET ----@field headers? table The headers to send ----@field body? string The body to send ----@field convertToTable? boolean If true, the resulting data will expect JSON and converted it to a table +---@field url string The url to fetch. +---@field method? string The method to use (GET, POST, ...), default is GET. +---@field headers? table The headers to send. +---@field body? string The body to send. +---@field convertToTable? boolean If true, the resulting data will expect JSON and converted it to a table. local FetchOptions = {} return Fetch diff --git a/src/plugins/lua/meta/gui.lua b/src/plugins/lua/meta/gui.lua index 6913e5f1eb1..71f9f20cf65 100644 --- a/src/plugins/lua/meta/gui.lua +++ b/src/plugins/lua/meta/gui.lua @@ -2,11 +2,11 @@ local gui = {} ----The base class of all ui related classes +---The base class of all ui related classes. ---@class Object gui.Object = {} ----The base class of all gui layout classes +---The base class of all gui layout classes. ---@class Layout : Object gui.Layout = {} @@ -26,14 +26,14 @@ local column = {} ---@return Column function gui.Column(children) end ----A group box with a title +---A group box with a title. ---@class Group : Widget local group = {} ---@return Group function gui.Group(children) end ----Row layout +---Row layout. ---@class Row : Layout local row = {} @@ -41,7 +41,7 @@ local row = {} ---@return Row function gui.Row(children) end ----Flow layout +---Flow layout. ---@class Flow : Layout local flow = {} @@ -49,7 +49,7 @@ local flow = {} ---@return Flow function gui.Flow(children) end ----Grid layout +---Grid layout. ---@class Grid : Layout local grid = {} @@ -57,7 +57,7 @@ local grid = {} ---@return Grid function gui.Grid(children) end ----Form layout +---Form layout. ---@class Form : Layout local form = {} @@ -66,7 +66,7 @@ local form = {} function gui.Form(children) end ----A stack of multiple widgets +---A stack of multiple widgets. ---@class Stack : Widget local stack = {} @@ -74,7 +74,7 @@ local stack = {} ---@return Stack function gui.Stack(children) end ----A Tab widget +---A Tab widget. ---@class Tab : Widget local tab = {} @@ -82,7 +82,7 @@ local tab = {} ---@return Tab function gui.Tab(children) end ----A Multiline text edit +---A Multiline text edit. ---@class TextEdit : Widget local textEdit = {} @@ -90,7 +90,6 @@ local textEdit = {} ---@return TextEdit function gui.TextEdit(children) end ----A PushButton ---@class PushButton : Widget local pushButton = {} @@ -98,7 +97,6 @@ local pushButton = {} ---@return PushButton function gui.PushButton(children) end ----A Label ---@class Label : LayoutItem local label = {} @@ -106,7 +104,6 @@ local label = {} ---@return Label function gui.Label(children) end ----A SpinBox ---@class SpinBox : Widget local spinBox = {} @@ -114,7 +111,6 @@ local spinBox = {} ---@return SpinBox function gui.SpinBox(children) end ----A Splitter ---@class Splitter : Widget local splitter = {} @@ -122,7 +118,6 @@ local splitter = {} ---@return Splitter function gui.Splitter(children) end ----A Toolbar ---@class ToolBar : Widget local toolBar = {} @@ -130,7 +125,6 @@ local toolBar = {} ---@return ToolBar function gui.ToolBar(children) end ----A TabWidget ---@class TabWidget : Widget local tabWidget = {} @@ -142,40 +136,40 @@ function gui.TabWidget(children) end ---@param child Layout|string|BaseAspect|function ---@return TabWidget function gui.TabWidget(name, child) end ----A "Line break" in the gui +---A "Line break" in the gui. function gui.br() end ----A "Stretch" in the layout +---A "Stretch" in the layout. function gui.st() end ----An empty grid cell in a grid layout +---An empty grid cell in a grid layout. function gui.empty() end ----A horizontal line in the layout +---A horizontal line in the layout. function gui.hr() end ----Clears the margin of the layout +---Clears the margin of the layout. function gui.noMargin() end ----Sets the margin of the layout to the default value +---Sets the margin of the layout to the default value. function gui.normalMargin() end ----Sets the alignment of a Grid layout according to the Form layout rules +---Sets the alignment of a Grid layout according to the Form layout rules. function gui.withFormAlignment() end ----Sets the size of the parent object if possible +---Sets the size of the parent object if possible. function gui.resize(width, height) end ----Sets the spacing of the gui +---Sets the spacing of the gui. function gui.spacing(spacing) end ----Sets the field growth policy of the gui +---Sets the field growth policy of the gui. function gui.fieldGrowthPolicy(policy) end ----Sets the onClicked handler of the parent object if possible +---Sets the onClicked handler of the parent object if possible. function gui.onClicked(f) end ----Sets the onTextChanged handler of the parent object if possible +---Sets the onTextChanged handler of the parent object if possible. function gui.onTextChanged(f) end return gui diff --git a/src/plugins/lua/meta/install.lua b/src/plugins/lua/meta/install.lua index 17752063740..427c0d51765 100644 --- a/src/plugins/lua/meta/install.lua +++ b/src/plugins/lua/meta/install.lua @@ -3,26 +3,26 @@ local Install = {} ---@class PackageInfo ----@field name string The name of the package ----@field version string The version of the package ----@field path FilePath The path to the package +---@field name string The name of the package. +---@field version string The version of the package. +---@field path FilePath The path to the package. local PackageInfo = {} ---@class InstallOptions ----@field name string The name of the package to install ----@field url string The url to fetch the package from ----@field version string The version of the package to install +---@field name string The name of the package to install. +---@field url string The url to fetch the package from. +---@field version string The version of the package to install. local InstallOptions = {} ---Install something ----@param msg string The message to display to the user asking for permission to install ----@param options InstallOptions|[InstallOptions] The options to install ----@return boolean Result Whether the installation was successful +---@param msg string The message to display to the user asking for permission to install. +---@param options InstallOptions|[InstallOptions] The options to install. +---@return boolean Result Whether the installation was successful. ---@return string Error The error message if the installation failed. function Install.install(msg, options) end ---Get the package info ----@param name any The name of the package +---@param name any The name of the package. ---@return PackageInfo function Install.packageInfo(name) end diff --git a/src/plugins/lua/meta/lsp.lua b/src/plugins/lua/meta/lsp.lua index 1c404c167f6..b0a34e7cd7e 100644 --- a/src/plugins/lua/meta/lsp.lua +++ b/src/plugins/lua/meta/lsp.lua @@ -1,38 +1,38 @@ ----@meta LSP +---@meta LSP. local lsp = {} ---@class ClientOptions ---@field name string The name under which to register the language server. ---@field cmd function|string[] The command to start the language server, or a function returning a string[]. ----@field transport? "stdio"|"localsocket" Defaults to stdio ----@field serverName? string The socket path when transport == "localsocket" ----@field languageFilter LanguageFilter The language filter deciding which files to open with the language server +---@field transport? "stdio"|"localsocket" Defaults to stdio. +---@field serverName? string The socket path when transport == "localsocket". +---@field languageFilter LanguageFilter The language filter deciding which files to open with the language server. ---@field startBehavior? "AlwaysOn"|"RequiresFile"|"RequiresProject" ----@field initializationOptions? table|string The initialization options to pass to the language server, either a json string, or a table +---@field initializationOptions? table|string The initialization options to pass to the language server, either a JSON string, or a table. ---@field settings? AspectContainer ---@field onStartFailed? function This callback is called when client failed to start. local ClientOptions = {} ---@class LanguageFilter ----@field patterns? string[] The file patterns supported by the language server ----@field mimeTypes? string[] The mime types supported by the language server +---@field patterns? string[] The file patterns supported by the language server. +---@field mimeTypes? string[] The mime types supported by the language server. local LanguageFilter = {} ---@class Client ----@field on_instance_start function The callback to call when a language client starts +---@field on_instance_start function The callback to call when a language client starts. lsp.Client = {} ----@param msg string The name of the message to handle ----@param callback function The callback to call when the message is received ----Registers a message handler for the message named 'msg' +---@param msg string The name of the message to handle. +---@param callback function The callback to call when the message is received. +---Registers a message handler for the message named 'msg'. function lsp.Client:registerMessage(msg, callback) end ----@param msg table the message to send ----Sends a message to the language server +---@param msg table the message to send. +---Sends a message to the language server. function lsp.Client:sendMessage(msg, callback) end ----Creates a new Language Client +---Creates a new Language Client. ---@param options ClientOptions ---@return Client function lsp.Client.create(options) end diff --git a/src/plugins/lua/meta/messagemanager.lua b/src/plugins/lua/meta/messagemanager.lua index 61419ee4b71..5bd6d92ed5e 100644 --- a/src/plugins/lua/meta/messagemanager.lua +++ b/src/plugins/lua/meta/messagemanager.lua @@ -2,15 +2,15 @@ local messagemanager = {} ----Writes a message to the Output pane +---Writes a message to the Output pane. ---@param ... any function messagemanager.writeSilently(...) end ----Writes a message to the Output pane and flashes the pane if its not open +---Writes a message to the Output pane and flashes the pane if its not open. ---@param ... any function messagemanager.writeFlashing(...) end ----Writes a message to the Output pane and opens the pane if its not open +---Writes a message to the Output pane and opens the pane if its not open. ---@param ... any function messagemanager.writeDisrupting(...) end diff --git a/src/plugins/lua/meta/process.lua b/src/plugins/lua/meta/process.lua index 53b4f35b7d0..e15d71996ae 100644 --- a/src/plugins/lua/meta/process.lua +++ b/src/plugins/lua/meta/process.lua @@ -4,14 +4,14 @@ local process = {} ---@async ---Runs a command in a terminal, has to be called from a coroutine! ----@param cmd string The command to run ----@return number The exit code of the command +---@param cmd string The command to run. +---@return number exitCode The exit code of the command. function process.runInTerminal(cmd) end ---@async ---Runs a command and returns the output! ----@param cmd string The command to run ----@return string The output of the command +---@param cmd string The command to run. +---@return string output The output of the command. function process.commandOutput(cmd) end return process diff --git a/src/plugins/lua/meta/qtc.lua b/src/plugins/lua/meta/qtc.lua index cc7de85f057..c4b1a10bea0 100644 --- a/src/plugins/lua/meta/qtc.lua +++ b/src/plugins/lua/meta/qtc.lua @@ -29,7 +29,7 @@ QtcPlugin = {} ---@class QtcPluginDependency ---@field Name string The name of the dependency. ---@field Version string The version of the dependency. (`major.minor.patch`) ----@field Required boolean Whether the dependency is required or not. +---@field Required? "required"|"optional"|"test" Whether the dependency is required or not. (Default: "required") QtcPluginDependency = {} diff --git a/src/plugins/lua/meta/settings.lua b/src/plugins/lua/meta/settings.lua index 09af050d924..6cf32d8ef2b 100644 --- a/src/plugins/lua/meta/settings.lua +++ b/src/plugins/lua/meta/settings.lua @@ -8,48 +8,48 @@ local settings = {} ---@class BaseAspect settings.BaseAspect = {} ----Applies the changes from its volatileValue to its value +---Applies the changes from its volatileValue to its value. function settings.BaseAspect:apply() end ---@class AspectCreate ----@field settingsKey? string The settings key of the aspect ----@field displayName? string The display name of the aspect ----@field labelText? string The label text of the aspect ----@field toolTip? string The tool tip of the aspect ----@field enabler? BoolAspect Enable / Disable this aspect based on the state of the `enabler` ----@field onValueChanged? function () Called when the value of the aspect changes ----@field onVolatileValueChanged? function () Called when the volatile value of the aspect changes +---@field settingsKey? string The settings key of the aspect. +---@field displayName? string The display name of the aspect. +---@field labelText? string The label text of the aspect. +---@field toolTip? string The tool tip of the aspect. +---@field enabler? BoolAspect Enable / Disable this aspect based on the state of the `enabler`. +---@field onValueChanged? function () Called when the value of the aspect changes. +---@field onVolatileValueChanged? function () Called when the volatile value of the aspect changes. local AspectCreate = {} ----The base class of most typed aspects +---The base class of most typed aspects. ---@generic T ---@class TypedAspect : BaseAspect ----@field value `T` The value of the aspect ----@field volatileValue `T` The temporary value of the aspect ----@field defaultValue `T` The default value of the aspect +---@field value `T` The value of the aspect. +---@field volatileValue `T` The temporary value of the aspect. +---@field defaultValue `T` The default value of the aspect. local TypedAspect = {} ---@generic T ---@class TypedAspectCreate : AspectCreate ----@field defaultValue `T` The default value of the aspect +---@field defaultValue `T` The default value of the aspect. local TypedAspectCreate = {} ----A container for aspects +---A container for aspects. ---@class AspectContainer : BaseAspect settings.AspectContainer = {} ----Options for creating an AspectContainer +---Options for creating an AspectContainer. ---@class AspectContainerCreate ----@field autoApply? boolean Whether the aspects should be applied automatically or not +---@field autoApply? boolean Whether the aspects should be applied automatically or not. AspectContainerCreate = {} ----Create a new AspectContainer +---Create a new AspectContainer. ---@param options AspectContainerCreate ---@return AspectContainer function settings.AspectContainer.create(options) end ----A aspect containing a boolean value +---A aspect containing a boolean value. ---@class BoolAspect : TypedAspect settings.BoolAspect = {} @@ -63,7 +63,7 @@ settings.LabelPlacement = { ---@field labelPlacement? LabelPlacement: BoolAspectCreate = {} ----Create a new BoolAspect +---Create a new BoolAspect. ---@param options BoolAspectCreate ---@return BoolAspect function settings.BoolAspect.create(options) end @@ -86,15 +86,15 @@ settings.StringDisplayStyle = { }; ---@class StringAspectCreate : TypedAspectCreate ----@field displayStyle? StringDisplayStyle The display type of the aspect ----@field historyId? string The history id of the aspect +---@field displayStyle? StringDisplayStyle The display type of the aspect. +---@field historyId? string The history id of the aspect. ---@field valueAcceptor? function string (oldvalue: string, newValue: string) ---@field showToolTipOnLabel? boolean ---@field displayFilter? function string (value: string) ---@field placeHolderText? string ---@field acceptRichText? boolean ---@field autoApplyOnEditingFinished? boolean ----@field elideMode? Qt.TextElideMode The elide mode of the aspect +---@field elideMode? Qt.TextElideMode The elide mode of the aspect. StringAspectCreate = {} ---@class StringAspect : TypedAspect @@ -116,9 +116,9 @@ settings.Kind = { }; ---@class FilePathAspectCreate ----@field expectedKind? Kind The kind of path we want to select ----@field historyId? string The history id of the aspect ----@field defaultPath? FilePath The default path of the aspect +---@field expectedKind? Kind The kind of path we want to select. +---@field historyId? string The history id of the aspect. +---@field defaultPath? FilePath The default path of the aspect. ---@field promptDialogFilter? string ---@field promptDialogTitle? string ---@field commandVersionArguments? string[] @@ -136,8 +136,8 @@ settings.Kind = { FilePathAspectCreate = {} ---@class FilePathAspect ----@field expandedValue FilePath The expanded value of the aspect ----@field defaultPath FilePath The default path of the aspect +---@field expandedValue FilePath The expanded value of the aspect. +---@field defaultPath FilePath The default path of the aspect. settings.FilePathAspect = {} ---Create a new FilePathAspect @@ -146,7 +146,7 @@ settings.FilePathAspect = {} function settings.FilePathAspect.create(options) end ---Set the value of the aspect ----@param value string|FilePath The value to set +---@param value string|FilePath The value to set. function settings.FilePathAspect:setValue(value) end settings.IntegerAspect = {} @@ -179,7 +179,7 @@ settings.OptionsPage = {} ---@field aspectContainer AspectContainer OptionsPageCreate = {} ----Creates a new OptionsPage +---Creates a new OptionsPage. ---@param options OptionsPageCreate ---@return OptionsPage function settings.OptionsPage.create(options) end diff --git a/src/plugins/lua/meta/simpletypes.lua b/src/plugins/lua/meta/simpletypes.lua index fdb65cf0984..5071efa9119 100644 --- a/src/plugins/lua/meta/simpletypes.lua +++ b/src/plugins/lua/meta/simpletypes.lua @@ -1,36 +1,36 @@ ---@meta ---@class QRect ----@field x integer The x position of the rectangle ----@field y integer The y position of the rectangle ----@field width integer The width of the rectangle ----@field height integer The height of the rectangle +---@field x integer The x position of the rectangle. +---@field y integer The y position of the rectangle. +---@field width integer The width of the rectangle. +---@field height integer The height of the rectangle. QRect = {} ---@class QSize ----@field width integer The width of the size ----@field height integer The height of the size +---@field width integer The width of the size. +---@field height integer The height of the size. QSize = {} ---@class QPoint ----@field x integer The x position of the point ----@field y integer The y position of the point +---@field x integer The x position of the point. +---@field y integer The y position of the point. QPoint = {} ---@class QPointF ----@field x number The x position of the floating point ----@field y number The y position of the floating point +---@field x number The x position of the floating point. +---@field y number The y position of the floating point. QPointF = {} ---@class QSizeF ----@field width number The width of the floating point size ----@field height number The height of the floating point size +---@field width number The width of the floating point size. +---@field height number The height of the floating point size. QSizeF = {} ---@class QRectF ----@field x number The x position of the floating point rectangle ----@field y number The y position of the floating point rectangle ----@field width number The width of the floating point rectangle ----@field height number The height of the floating point rectangle +---@field x number The x position of the floating point rectangle. +---@field y number The y position of the floating point rectangle. +---@field width number The width of the floating point rectangle. +---@field height number The height of the floating point rectangle. QRectF = {} diff --git a/src/plugins/lua/meta/utils.lua b/src/plugins/lua/meta/utils.lua index 409946b711c..51e74ea1033 100644 --- a/src/plugins/lua/meta/utils.lua +++ b/src/plugins/lua/meta/utils.lua @@ -3,99 +3,99 @@ local utils = {} ---Suspends the current coroutine for the given amount of milliseconds. Call `a.wait` on the returned value to get the result. ----@param ms number The amount of milliseconds to wait +---@param ms number The amount of milliseconds to wait. function utils.waitms(ms) end ----Calls the callback after the given amount of milliseconds ----@param ms number The amount of milliseconds to wait ----@param callback function The callback to call +---Calls the callback after the given amount of milliseconds. +---@param ms number The amount of milliseconds to wait. +---@param callback function The callback to call. function utils.waitms_cb(ms, callback) end ---@class FilePath utils.FilePath = {} ----@param path string The path to convert ----@return FilePath The converted path ----Convert and clean a path, returning a FilePath object +---@param path string The path to convert. +---@return FilePath The converted path. +---Convert and clean a path, returning a FilePath object. function utils.FilePath.fromUserInput(path) end ----@return FilePath The new absolute path +---@return FilePath The new absolute path. ---Searches for the path inside the PATH environment variable. Call `a.wait` on the returned value to get the result. function utils.FilePath:searchInPath() end ---@class (exact) DirEntriesOptions ----@field nameFilters? string[] The name filters to use (e.g. "*.lua"), defaults to all files ----@field fileFilters? integer The filters to use (combination of QDir.Filters.*), defaults to QDir.Filters.NoFilter ----@field flags? integer The iterator flags (combination of QDirIterator.Flags.*), defaults to QDirIterator.Flags.NoIteratorFlags +---@field nameFilters? string[] The name filters to use (e.g. "*.lua"), defaults to all files. +---@field fileFilters? integer The filters to use (combination of QDir.Filters.*), defaults to QDir.Filters.NoFilter. +---@field flags? integer The iterator flags (combination of QDirIterator.Flags.*), defaults to QDirIterator.Flags.NoIteratorFlags. ---Returns all entries in the directory. Call `a.wait` on the returned value to get the result. ---@param options DirEntriesOptions ---@return FilePath[] function utils.FilePath:dirEntries(options) end ----Returns the FilePath as it should be displayed to the user +---Returns the FilePath as it should be displayed to the user. ---@return string function utils.FilePath:toUserOutput() end ----Returns whether the target exists +---Returns whether the target exists. ---@return boolean function utils.FilePath:exists() end ----Returns whether the target is a file and executable +---Returns whether the target is a file and executable. ---@return boolean function utils.FilePath:isExecutableFile() end ----Returns the path portion of FilePath as a string in the hosts native format +---Returns the path portion of FilePath as a string in the hosts native format. ---@return string function utils.FilePath:nativePath() end ----Returns the last part of the path +---Returns the last part of the path. ---@return string function utils.FilePath:fileName() end ----Returns the current working path of Qt Creator +---Returns the current working path of Qt Creator. ---@return FilePath function utils.FilePath.currentWorkingPath() end ----Returns a new FilePath with the given tail appended ----@param tail string|FilePath The tail to append +---Returns a new FilePath with the given tail appended. +---@param tail string|FilePath The tail to append. ---@return FilePath function utils.FilePath:resolvePath(tail) end ----Returns the parent directory of the path +---Returns the parent directory of the path. ---@return FilePath function utils.FilePath:parentDir() end ----If the path targets a symlink, this function returns the target of the symlink ----@return FilePath The resolved path +---If the path targets a symlink, this function returns the target of the symlink. +---@return FilePath resolvedPath The resolved path. function utils.FilePath:resolveSymlinks() end ----Returns the suffix of the path (e.g. "test.ui.qml" -> ".qml") +---Returns the suffix of the paths (e.g. "test.ui.qml" -> ".qml"). ---@return string function utils.FilePath:suffix() end ----Returns the complete suffix of the path (e.g. "test.ui.qml" -> "ui.qml") +---Returns the complete suffix of the paths (e.g. "test.ui.qml" -> "ui.qml"). ---@return string function utils.FilePath:completeSuffix() end ----Returns whether the path is absolute +---Returns whether the path is absolute. ---@return boolean function utils.FilePath:isAbsolutePath() end ---@class HostOsInfo ----@field os "mac"|"windows"|"linux" The current host operating system ----@field architecture "unknown"|"x86"|"x86_64"|"itanium"|"arm"|"arm64" The current host architecture +---@field os "mac"|"windows"|"linux" The current host operating system. +---@field architecture "unknown"|"x86"|"x86_64"|"itanium"|"arm"|"arm64" The current host architecture. utils.HostOsInfo = {} ----Returns whether the host operating system is windows +---Returns whether the host operating system is windows. ---@return boolean function utils.HostOsInfo.isWindowsHost() end ----Returns whether the host operating system is mac +---Returns whether the host operating system is mac. ---@return boolean function utils.HostOsInfo.isMacHost() end ----Returns whether the host operating system is linux +---Returns whether the host operating system is linux. ---@return boolean function utils.HostOsInfo.isLinuxHost() end diff --git a/src/plugins/lua/wizards/plugin/plugin.lua.tpl b/src/plugins/lua/wizards/plugin/plugin.lua.tpl index 9675a2a0051..67d6e2966dd 100644 --- a/src/plugins/lua/wizards/plugin/plugin.lua.tpl +++ b/src/plugins/lua/wizards/plugin/plugin.lua.tpl @@ -15,8 +15,7 @@ This plugin provides some functionality. You can describe it more here. ]], Dependencies = { - { Name = "Core", Version = "%{JS: Util.qtCreatorIdeVersion()}", Required = true }, - { Name = "Lua", Version = "%{JS: Util.qtCreatorIdeVersion()}", Required = true }, + { Name = "Lua", Version = "%{JS: Util.qtCreatorIdeVersion()}" }, }, setup = function() require 'init'.setup() diff --git a/src/plugins/lua/wizards/plugin/project.json b/src/plugins/lua/wizards/plugin/project.json index b7879f50d77..b13f0e967ff 100644 --- a/src/plugins/lua/wizards/plugin/project.json +++ b/src/plugins/lua/wizards/plugin/project.json @@ -9,7 +9,7 @@ "-tcs", "-load", "Lua", - "-loadluaplugin", + "-pluginpath", "%\{ActiveProject:ProjectDirectory\}" ] } diff --git a/src/plugins/lua/wizards/plugin/wizard.json b/src/plugins/lua/wizards/plugin/wizard.json index f854a49a3c1..b897f1eb141 100644 --- a/src/plugins/lua/wizards/plugin/wizard.json +++ b/src/plugins/lua/wizards/plugin/wizard.json @@ -19,10 +19,6 @@ "key": "ProjectFile", "value": "%{ProjectDirectory}/.qtcreator/project.json" }, - { - "key": "PluginNameLower", - "value": "%{JS: value('PluginName').toLowerCase()}" - }, { "key": "PluginSpecFile", "value": "%{JS: Util.fileName(value('PluginName').toLowerCase(), Util.preferredSuffix('text/x-lua'))}" @@ -147,14 +143,14 @@ }, { "source": "init.lua.tpl", - "target": "%{SrcFileName}" + "target": "%{PluginName}/%{SrcFileName}" }, { "source": ".luarc.json" }, { "source": "plugin.lua.tpl", - "target": "%{PluginSpecFile}", + "target": "%{PluginName}/%{PluginSpecFile}", "openInEditor": true } ] diff --git a/src/plugins/luals/luals/luals.lua b/src/plugins/luals/luals/luals.lua index 843d18189e4..5a68388dd06 100644 --- a/src/plugins/luals/luals/luals.lua +++ b/src/plugins/luals/luals/luals.lua @@ -14,9 +14,8 @@ This plugin provides the Lua Language Server. It will try to install it if it is not found. ]], Dependencies = { - { Name = "Core", Version = "13.0.82", Required = true }, - { Name = "Lua", Version = "13.0.82", Required = true }, - { Name = "LuaLanguageClient", Version = "13.0.82", Required = true } + { Name = "Lua", Version = "14.0.0" }, + { Name = "LuaLanguageClient", Version = "14.0.0" } }, setup = function() require 'init'.setup() diff --git a/src/plugins/luatests/luatests/luatests.lua b/src/plugins/luatests/luatests/luatests.lua index 4d22738f3bc..e85f0d95278 100644 --- a/src/plugins/luatests/luatests/luatests.lua +++ b/src/plugins/luatests/luatests/luatests.lua @@ -13,8 +13,7 @@ return { It has tests for (almost) all functionality exposed by the API. ]], Dependencies = { - { Name = "Core", Version = "13.0.82", Required = true }, - { Name = "Lua", Version = "13.0.82", Required = true } + { Name = "Lua", Version = "14.0.0" } }, setup = function() require 'tests'.setup() end, printToOutputPane = true, diff --git a/src/plugins/mcusupport/test/unittest.cpp b/src/plugins/mcusupport/test/unittest.cpp index d523d6a4bf1..74e98a0ec41 100644 --- a/src/plugins/mcusupport/test/unittest.cpp +++ b/src/plugins/mcusupport/test/unittest.cpp @@ -75,6 +75,7 @@ using ProjectExplorer::ToolchainManager; using testing::_; using testing::Return; +using testing::Between; namespace { const char empty[]{""}; @@ -506,6 +507,7 @@ void McuSupportTest::init() void McuSupportTest::cleanup() { + QVERIFY(settingsMockPtr.get()); QVERIFY(testing::Mock::VerifyAndClearExpectations(settingsMockPtr.get())); QVERIFY(testing::Mock::VerifyAndClearExpectations(freeRtosPackage)); QVERIFY(testing::Mock::VerifyAndClearExpectations(sdkPackage)); @@ -854,7 +856,7 @@ void McuSupportTest::test_useFallbackPathForToolchainWhenPathFromSettingsIsNotAv McuTargetDescription::Toolchain toolchainDescription{armGcc, {}, compilerDescription, {}}; EXPECT_CALL(*settingsMockPtr, getPath(Key{armGccDirectorySetting}, _, FilePath{fallbackDir})) - .Times(2) + .Times(Between(2,3)) .WillRepeatedly(Return(FilePath{fallbackDir})); McuToolchainPackage *toolchain = targetFactory.createToolchain(toolchainDescription); @@ -1559,7 +1561,7 @@ void McuSupportTest::test_legacy_createThirdPartyPackage() QFETCH(QString, detectionPath); EXPECT_CALL(*settingsMockPtr, getPath(Key{setting}, _, _)) - .Times(2) + .Times(Between(2,3)) .WillRepeatedly(Return(FilePath::fromUserInput(defaultPath))); McuPackagePtr thirdPartyPackage{creator()}; @@ -1644,7 +1646,7 @@ void McuSupportTest::test_createThirdPartyPackage() .WillOnce(Return(FilePath::fromUserInput(defaultPath))); EXPECT_CALL(*settingsMockPtr, getPath(Key{setting}, QSettings::UserScope, _)) - .Times(testing::AtMost(1)) + .Times(testing::AtMost(2)) .WillOnce(Return(FilePath::fromUserInput(path))); auto [targets, packages] = targetFactory.createTargets(targetDescription, sdkPackagePtr); @@ -1668,7 +1670,7 @@ void McuSupportTest::test_createThirdPartyPackage() void McuSupportTest::test_legacy_createCypressProgrammer3rdPartyPackage() { EXPECT_CALL(*settingsMockPtr, getPath(Key{cypressProgrammerSetting}, _, _)) - .Times(2) + .Times(Between(2,3)) .WillRepeatedly(Return(FilePath::fromUserInput(defaultToolPath))); McuPackagePtr thirdPartyPackage{Legacy::createCypressProgrammerPackage(settingsMockPtr)}; @@ -1692,7 +1694,7 @@ void McuSupportTest::test_createJLink3rdPartyPackage() .WillOnce(Return(FilePath::fromUserInput(jlinkPath))); EXPECT_CALL(*settingsMockPtr, getPath(Key{jlinkSetting}, QSettings::UserScope, _)) - .Times(testing::AtMost(1)) + .Times(testing::AtMost(2)) .WillOnce(Return(FilePath::fromUserInput(jlinkPath))); auto [targets, packages] = targetFactory.createTargets(targetDescription, sdkPackagePtr); diff --git a/src/plugins/projectexplorer/images/build_hammer_mask.png b/src/plugins/projectexplorer/images/build_hammer_mask.png new file mode 100644 index 00000000000..c30f933962a Binary files /dev/null and b/src/plugins/projectexplorer/images/build_hammer_mask.png differ diff --git a/src/plugins/projectexplorer/images/build_hammer_mask@2x.png b/src/plugins/projectexplorer/images/build_hammer_mask@2x.png new file mode 100644 index 00000000000..fc679b1d566 Binary files /dev/null and b/src/plugins/projectexplorer/images/build_hammer_mask@2x.png differ diff --git a/src/plugins/projectexplorer/images/build_hammerhandle_mask.png b/src/plugins/projectexplorer/images/build_hammerhandle_mask.png deleted file mode 100644 index 15e318ac4ab..00000000000 Binary files a/src/plugins/projectexplorer/images/build_hammerhandle_mask.png and /dev/null differ diff --git a/src/plugins/projectexplorer/images/build_hammerhandle_mask@2x.png b/src/plugins/projectexplorer/images/build_hammerhandle_mask@2x.png deleted file mode 100644 index 8b2525dbf4e..00000000000 Binary files a/src/plugins/projectexplorer/images/build_hammerhandle_mask@2x.png and /dev/null differ diff --git a/src/plugins/projectexplorer/images/build_hammerhead_mask.png b/src/plugins/projectexplorer/images/build_hammerhead_mask.png deleted file mode 100644 index 98f11810b3c..00000000000 Binary files a/src/plugins/projectexplorer/images/build_hammerhead_mask.png and /dev/null differ diff --git a/src/plugins/projectexplorer/images/build_hammerhead_mask@2x.png b/src/plugins/projectexplorer/images/build_hammerhead_mask@2x.png deleted file mode 100644 index ec7ecd42b0f..00000000000 Binary files a/src/plugins/projectexplorer/images/build_hammerhead_mask@2x.png and /dev/null differ diff --git a/src/plugins/projectexplorer/images/debugger_beetle_mask.png b/src/plugins/projectexplorer/images/debugger_beetle_mask.png index 816aacc3398..9d84f59a1ea 100644 Binary files a/src/plugins/projectexplorer/images/debugger_beetle_mask.png and b/src/plugins/projectexplorer/images/debugger_beetle_mask.png differ diff --git a/src/plugins/projectexplorer/images/debugger_beetle_mask@2x.png b/src/plugins/projectexplorer/images/debugger_beetle_mask@2x.png index c240532d29e..cb870c0b6c9 100644 Binary files a/src/plugins/projectexplorer/images/debugger_beetle_mask@2x.png and b/src/plugins/projectexplorer/images/debugger_beetle_mask@2x.png differ diff --git a/src/plugins/projectexplorer/images/mode_project_mask.png b/src/plugins/projectexplorer/images/mode_project_mask.png index 6e6092b7ad4..5799759f31f 100644 Binary files a/src/plugins/projectexplorer/images/mode_project_mask.png and b/src/plugins/projectexplorer/images/mode_project_mask.png differ diff --git a/src/plugins/projectexplorer/images/mode_project_mask@2x.png b/src/plugins/projectexplorer/images/mode_project_mask@2x.png index 3538453911b..79d0e7a5488 100644 Binary files a/src/plugins/projectexplorer/images/mode_project_mask@2x.png and b/src/plugins/projectexplorer/images/mode_project_mask@2x.png differ diff --git a/src/plugins/projectexplorer/images/run_mask.png b/src/plugins/projectexplorer/images/run_mask.png index d08de1ad5f0..a6f8867950d 100644 Binary files a/src/plugins/projectexplorer/images/run_mask.png and b/src/plugins/projectexplorer/images/run_mask.png differ diff --git a/src/plugins/projectexplorer/images/run_mask@2x.png b/src/plugins/projectexplorer/images/run_mask@2x.png index 72af48223ed..0fb3ec7b51c 100644 Binary files a/src/plugins/projectexplorer/images/run_mask@2x.png and b/src/plugins/projectexplorer/images/run_mask@2x.png differ diff --git a/src/plugins/projectexplorer/projectexplorer.cpp b/src/plugins/projectexplorer/projectexplorer.cpp index d4c5717ce3d..8838a37645b 100644 --- a/src/plugins/projectexplorer/projectexplorer.cpp +++ b/src/plugins/projectexplorer/projectexplorer.cpp @@ -1177,7 +1177,7 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er ActionManager::createMenu(Constants::M_RECENTPROJECTS); mrecent->menu()->setTitle(Tr::tr("Recent P&rojects")); mrecent->setOnAllDisabledBehavior(ActionContainer::Show); - mfile->addMenu(mrecent, Core::Constants::G_FILE_OPEN); + mfile->addMenu(mrecent, Core::Constants::G_FILE_RECENT); connect( m_instance, &ProjectExplorerPlugin::recentProjectsChanged, diff --git a/src/plugins/projectexplorer/projectexplorer.qrc b/src/plugins/projectexplorer/projectexplorer.qrc index 0926397f423..248fe4e591b 100644 --- a/src/plugins/projectexplorer/projectexplorer.qrc +++ b/src/plugins/projectexplorer/projectexplorer.qrc @@ -26,10 +26,8 @@ images/devicestatusindicator@2x.png images/build.png images/build@2x.png - images/build_hammerhandle_mask.png - images/build_hammerhandle_mask@2x.png - images/build_hammerhead_mask.png - images/build_hammerhead_mask@2x.png + images/build_hammer_mask.png + images/build_hammer_mask@2x.png images/targetpanel_bottom.png images/window.png images/buildstepdisable.png diff --git a/src/plugins/projectexplorer/projectexplorerconstants.h b/src/plugins/projectexplorer/projectexplorerconstants.h index 7638d323c96..8a053c243d8 100644 --- a/src/plugins/projectexplorer/projectexplorerconstants.h +++ b/src/plugins/projectexplorer/projectexplorerconstants.h @@ -171,6 +171,7 @@ const char NORMAL_RUN_MODE[]="RunConfiguration.NormalRunMode"; const char DEBUG_RUN_MODE[]="RunConfiguration.DebugRunMode"; const char DAP_CMAKE_DEBUG_RUN_MODE[]="RunConfiguration.CmakeDebugRunMode"; const char DAP_GDB_DEBUG_RUN_MODE[]="RunConfiguration.DapGdbDebugRunMode"; +const char DAP_LLDB_DEBUG_RUN_MODE[]="RunConfiguration.DapLldbDebugRunMode"; const char DAP_PY_DEBUG_RUN_MODE[]="RunConfiguration.DapPyDebugRunMode"; const char QML_PROFILER_RUN_MODE[]="RunConfiguration.QmlProfilerRunMode"; const char QML_PROFILER_RUNNER[]="RunConfiguration.QmlProfilerRunner"; diff --git a/src/plugins/projectexplorer/projectexplorericons.cpp b/src/plugins/projectexplorer/projectexplorericons.cpp index 2a61f5bb2f8..0d4440b4aee 100644 --- a/src/plugins/projectexplorer/projectexplorericons.cpp +++ b/src/plugins/projectexplorer/projectexplorericons.cpp @@ -10,14 +10,12 @@ namespace Icons { const Icon BUILD(":/projectexplorer/images/build.png"); const Icon BUILD_FLAT({ - {":/projectexplorer/images/build_hammerhandle_mask.png", Theme::IconsBuildHammerHandleColor}, - {":/projectexplorer/images/build_hammerhead_mask.png", Theme::IconsBuildHammerHeadColor}}); + {":/projectexplorer/images/build_hammer_mask.png", Theme::IconsBaseColor}}); const Icon BUILD_SMALL({ {":/projectexplorer/images/buildhammerhandle.png", Theme::IconsBuildHammerHandleColor}, {":/projectexplorer/images/buildhammerhead.png", Theme::IconsBuildHammerHeadColor}}, Icon::Tint); const Icon CANCELBUILD_FLAT({ - {":/projectexplorer/images/build_hammerhandle_mask.png", Theme::IconsDisabledColor}, - {":/projectexplorer/images/build_hammerhead_mask.png", Theme::IconsDisabledColor}, + {":/projectexplorer/images/build_hammer_mask.png", Theme::IconsBaseColor}, {":/projectexplorer/images/cancelbuild_overlay.png", Theme::IconsStopToolBarColor}}, Icon::Tint | Icon::PunchEdges); const Icon REBUILD({ diff --git a/src/plugins/projectexplorer/projectexplorersettings.cpp b/src/plugins/projectexplorer/projectexplorersettings.cpp index 1780a53eff7..3e36b84ab75 100644 --- a/src/plugins/projectexplorer/projectexplorersettings.cpp +++ b/src/plugins/projectexplorer/projectexplorersettings.cpp @@ -25,6 +25,7 @@ #include #include #include +#include using namespace Core; using namespace Utils; @@ -33,6 +34,7 @@ namespace ProjectExplorer { namespace Internal { namespace Constants { +const char REAPER_TIMEOUT_SETTINGS_KEY[] = "ProjectExplorer/Settings/ReaperTimeout"; const char BUILD_BEFORE_DEPLOY_SETTINGS_KEY[] = "ProjectExplorer/Settings/BuildBeforeDeploy"; const char DEPLOY_BEFORE_RUN_SETTINGS_KEY[] = "ProjectExplorer/Settings/DeployBeforeRun"; const char SAVE_BEFORE_BUILD_SETTINGS_KEY[] = "ProjectExplorer/Settings/SaveBeforeBuild"; @@ -65,6 +67,7 @@ void saveProjectExplorerSettings(); static bool operator==(const ProjectExplorerSettings &p1, const ProjectExplorerSettings &p2) { return p1.buildBeforeDeploy == p2.buildBeforeDeploy + && p1.reaperTimeoutInSeconds == p2.reaperTimeoutInSeconds && p1.deployBeforeRun == p2.deployBeforeRun && p1.saveBeforeBuild == p2.saveBeforeBuild && p1.useJom == p2.useJom @@ -120,6 +123,9 @@ static void loadProjectExplorerSettings() static const ProjectExplorerSettings defaultSettings; + settings.reaperTimeoutInSeconds + = s->value(Constants::REAPER_TIMEOUT_SETTINGS_KEY, defaultSettings.reaperTimeoutInSeconds) + .toInt(); settings.deployBeforeRun = s->value(Constants::DEPLOY_BEFORE_RUN_SETTINGS_KEY, defaultSettings.deployBeforeRun) .toBool(); @@ -186,6 +192,10 @@ void saveProjectExplorerSettings() static const ProjectExplorerSettings defaultSettings; const ProjectExplorerSettings &settings = projectExplorerSettings(); + s->setValueWithDefault( + Constants::REAPER_TIMEOUT_SETTINGS_KEY, + settings.reaperTimeoutInSeconds, + defaultSettings.reaperTimeoutInSeconds); s->setValueWithDefault(Constants::BUILD_BEFORE_DEPLOY_SETTINGS_KEY, int(settings.buildBeforeDeploy), int(defaultSettings.buildBeforeDeploy)); @@ -290,6 +300,7 @@ private: QComboBox *m_terminalModeComboBox; QCheckBox *m_jomCheckbox; QCheckBox *m_showAllKitsCheckBox; + QSpinBox *m_reaperTimeoutSpinBox; Utils::ElidingLabel *m_appEnvLabel; QButtonGroup *m_directoryButtonGroup; @@ -297,6 +308,13 @@ private: ProjectExplorerSettingsWidget::ProjectExplorerSettingsWidget() { + m_reaperTimeoutSpinBox = new QSpinBox; + m_reaperTimeoutSpinBox->setMinimum(1); + m_reaperTimeoutSpinBox->setSuffix(Tr::tr("s")); + m_reaperTimeoutSpinBox->setToolTip( + Tr::tr("The amount of seconds to wait between a \"soft kill\" and a \"hard kill\" of a " + "running application")); + m_currentDirectoryRadioButton = new QRadioButton(Tr::tr("Current directory")); m_directoryRadioButton = new QRadioButton(Tr::tr("Directory")); m_projectsDirectoryPathChooser = new PathChooser; @@ -406,6 +424,8 @@ ProjectExplorerSettingsWidget::ProjectExplorerSettingsWidget() Tr::tr("Build before deploying:"), m_buildBeforeDeployComboBox, br, Tr::tr("Stop applications before building:"), m_stopBeforeBuildComboBox, br, Tr::tr("Default for \"Run in terminal\":"), m_terminalModeComboBox, br, + Tr::tr("Time to wait before force-stopping applications:"), + m_reaperTimeoutSpinBox, st, br, }, m_jomCheckbox, jomLabel, @@ -434,6 +454,7 @@ ProjectExplorerSettingsWidget::ProjectExplorerSettingsWidget() ProjectExplorerSettings ProjectExplorerSettingsWidget::settings() const { ProjectExplorerSettings s; + s.reaperTimeoutInSeconds = m_reaperTimeoutSpinBox->value(); s.buildBeforeDeploy = static_cast( m_buildBeforeDeployComboBox->currentData().toInt()); s.deployBeforeRun = m_deployProjectBeforeRunCheckBox->isChecked(); @@ -458,6 +479,7 @@ ProjectExplorerSettings ProjectExplorerSettingsWidget::settings() const void ProjectExplorerSettingsWidget::setSettings(const ProjectExplorerSettings &s) { + m_reaperTimeoutSpinBox->setValue(s.reaperTimeoutInSeconds); m_appEnvChanges = s.appEnvChanges; m_buildBeforeDeployComboBox->setCurrentIndex( m_buildBeforeDeployComboBox->findData(int(s.buildBeforeDeploy))); diff --git a/src/plugins/projectexplorer/projectexplorersettings.h b/src/plugins/projectexplorer/projectexplorersettings.h index 0a99984dc24..3a30548d60d 100644 --- a/src/plugins/projectexplorer/projectexplorersettings.h +++ b/src/plugins/projectexplorer/projectexplorersettings.h @@ -22,6 +22,7 @@ class ProjectExplorerSettings { public: BuildBeforeRunMode buildBeforeDeploy = BuildBeforeRunMode::WholeProject; + int reaperTimeoutInSeconds = 1; bool deployBeforeRun = true; bool saveBeforeBuild = false; bool useJom = true; diff --git a/src/plugins/projectexplorer/projectnodeshelper.h b/src/plugins/projectexplorer/projectnodeshelper.h index b9e3cc27aa0..6809622af5b 100644 --- a/src/plugins/projectexplorer/projectnodeshelper.h +++ b/src/plugins/projectexplorer/projectnodeshelper.h @@ -8,67 +8,121 @@ #include #include +#include + #include +#include #include +#include #include namespace ProjectExplorer { namespace Internal { +struct DirectoryScanResult +{ + QList nodes; + Utils::FilePaths subDirectories; +}; + template -QList scanForFilesRecursively( +DirectoryScanResult scanForFiles( QPromise &promise, - double progressStart, - double progressRange, const Utils::FilePath &directory, const QDir::Filters &filter, const std::function factory, - QSet &visited, const QList &versionControls) { - QList result; - - // Do not follow directory loops: - if (!Utils::insert(visited, directory.canonicalPath())) - return result; + DirectoryScanResult result; const Utils::FilePaths entries = directory.dirEntries(filter); - double progress = 0; - const double progressIncrement = progressRange / static_cast(entries.count()); - int lastIntProgress = 0; for (const Utils::FilePath &entry : entries) { if (promise.isCanceled()) return result; - if (!Utils::contains(versionControls, [entry](const Core::IVersionControl *vc) { + if (Utils::anyOf(versionControls, [entry](const Core::IVersionControl *vc) { return vc->isVcsFileOrDirectory(entry); })) { - if (entry.isDir()) { - result.append(scanForFilesRecursively(promise, - progress, - progressIncrement, - entry, - filter, - factory, - visited, - versionControls)); - } else if (FileNode *node = factory(entry)) { - result.append(node); - } - } - progress += progressIncrement; - const int intProgress = std::min(static_cast(progressStart + progress), - promise.future().progressMaximum()); - if (lastIntProgress < intProgress) { - promise.setProgressValue(intProgress); - lastIntProgress = intProgress; + continue; } + + if (entry.isDir()) + result.subDirectories.append(entry); + else if (FileNode *node = factory(entry)) + result.nodes.append(node); } - promise.setProgressValue(std::min(static_cast(progressStart + progressRange), - promise.future().progressMaximum())); + return result; } + +template +QList scanForFilesRecursively( + QPromise &promise, + double progressRange, + const Utils::FilePath &directory, + const QDir::Filters &filter, + const std::function factory, + const QList &versionControls) +{ + QSet visited; + const DirectoryScanResult result + = scanForFiles(promise, directory, filter, factory, versionControls); + QList fileNodes = result.nodes; + const double progressIncrement = progressRange + / static_cast( + fileNodes.count() + result.subDirectories.count()); + promise.setProgressValue(fileNodes.count() * progressIncrement); + QList> subDirectories; + auto addSubDirectories = [&](const Utils::FilePaths &subdirs, int progressIncrement) { + for (const Utils::FilePath &subdir : subdirs) { + if (Utils::insert(visited, subdir.canonicalPath())) + subDirectories.append(qMakePair(subdir, progressIncrement)); + else + promise.setProgressValue(promise.future().progressValue() + progressIncrement); + } + }; + addSubDirectories(result.subDirectories, progressIncrement); + + while (!subDirectories.isEmpty()) { + using namespace Tasking; + LoopList iterator(subDirectories); + subDirectories.clear(); + + auto onSetup = [&, iterator](Utils::Async &task) { + task.setConcurrentCallData( + [&filter, &factory, &promise, &versionControls, subdir = iterator->first]( + QPromise &p) { + p.addResult(scanForFiles(promise, subdir, filter, factory, versionControls)); + }); + }; + + auto onDone = [&, iterator](const Utils::Async &task) { + const int progressRange = iterator->second; + const DirectoryScanResult result = task.result(); + fileNodes.append(result.nodes); + const int subDirCount = result.subDirectories.count(); + if (subDirCount == 0) { + promise.setProgressValue(promise.future().progressValue() + progressRange); + } else { + const int fileCount = result.nodes.count(); + const int increment = progressRange / static_cast(fileCount + subDirCount); + promise.setProgressValue( + promise.future().progressValue() + increment * fileCount); + addSubDirectories(result.subDirectories, increment); + } + }; + + const Group group{ + Utils::HostOsInfo::isLinuxHost() ? parallelLimit(2) : parallelIdealThreadCountLimit, + iterator, + Utils::AsyncTask(onSetup, onDone) + }; + TaskTree::runBlocking(group); + } + return fileNodes; +} + } // namespace Internal template @@ -78,15 +132,12 @@ QList scanForFiles( const QDir::Filters &filter, const std::function factory) { - QSet visited; promise.setProgressRange(0, 1000000); return Internal::scanForFilesRecursively(promise, - 0.0, 1000000.0, directory, filter, factory, - visited, Core::VcsManager::versionControls()); } diff --git a/src/plugins/projectexplorer/runcontrol.cpp b/src/plugins/projectexplorer/runcontrol.cpp index 02df4037afd..5eac3498bcf 100644 --- a/src/plugins/projectexplorer/runcontrol.cpp +++ b/src/plugins/projectexplorer/runcontrol.cpp @@ -1320,11 +1320,12 @@ void SimpleTargetRunnerPrivate::stop() m_resultData.m_exitStatus = QProcess::CrashExit; const bool isLocal = !m_command.executable().needsDevice(); + const auto totalTimeout = 2 * m_process.reaperTimeout(); if (isLocal) { if (!isRunning()) return; m_process.stop(); - m_process.waitForFinished(); + m_process.waitForFinished(totalTimeout); QTimer::singleShot(100, this, [this] { forwardDone(); }); } else { if (m_stopRequested) @@ -1334,8 +1335,7 @@ void SimpleTargetRunnerPrivate::stop() switch (m_state) { case Run: m_process.stop(); - using namespace std::chrono_literals; - if (!m_process.waitForFinished(2s)) { // TODO: it may freeze on some devices + if (!m_process.waitForFinished(totalTimeout)) { q->appendMessage(Tr::tr("Remote process did not finish in time. " "Connectivity lost?"), ErrorMessageFormat); m_process.close(); @@ -1444,6 +1444,7 @@ void SimpleTargetRunnerPrivate::start() else m_outputCodec = QTextCodec::codecForName("utf8"); + m_process.setForceDefaultErrorModeOnWindows(true); m_process.start(); } @@ -1520,6 +1521,8 @@ void SimpleTargetRunner::start() d->m_stopReported = false; d->disconnect(this); d->m_process.setTerminalMode(useTerminal ? Utils::TerminalMode::Run : Utils::TerminalMode::Off); + d->m_process.setReaperTimeout( + std::chrono::seconds(projectExplorerSettings().reaperTimeoutInSeconds)); d->m_runAsRoot = runAsRoot; const QString msg = Tr::tr("Starting %1...").arg(d->m_command.displayName()); diff --git a/src/plugins/qbsprojectmanager/qbsproject.cpp b/src/plugins/qbsprojectmanager/qbsproject.cpp index 74b64e2a5cc..2d2c27a2a83 100644 --- a/src/plugins/qbsprojectmanager/qbsproject.cpp +++ b/src/plugins/qbsprojectmanager/qbsproject.cpp @@ -798,6 +798,8 @@ static void getExpandedCompilerFlags(QStringList &cFlags, QStringList &cxxFlags, cxxFlags << "/std:c++20"; else if (cxxLanguageVersion.contains("c++17")) cxxFlags << "/std:c++17"; + } else { + cFlags = cxxFlags = commonFlags; } } diff --git a/src/plugins/qtsupport/qtkitaspect.cpp b/src/plugins/qtsupport/qtkitaspect.cpp index 18a18b6ae45..1608b31b845 100644 --- a/src/plugins/qtsupport/qtkitaspect.cpp +++ b/src/plugins/qtsupport/qtkitaspect.cpp @@ -364,7 +364,7 @@ int QtKitAspect::qtVersionId(const Kit *k) int id = -1; QVariant data = k->value(QtKitAspect::id(), -1); - if (data.typeId() == QVariant::Int) { + if (data.typeId() == QMetaType::Int) { bool ok; id = data.toInt(&ok); if (!ok) diff --git a/src/plugins/rustls/rustls/rustls.lua b/src/plugins/rustls/rustls/rustls.lua index ae2a5c6eb48..7e0056de25f 100644 --- a/src/plugins/rustls/rustls/rustls.lua +++ b/src/plugins/rustls/rustls/rustls.lua @@ -14,9 +14,8 @@ This plugin provides the Rust Language Server. It will try to install it if it is not found. ]], Dependencies = { - { Name = "Core", Version = "13.0.82", Required = true }, - { Name = "Lua", Version = "13.0.82", Required = true }, - { Name = "LuaLanguageClient", Version = "13.0.82", Required = true } + { Name = "Lua", Version = "14.0.0" }, + { Name = "LuaLanguageClient", Version = "14.0.0" } }, setup = function() require 'init'.setup() diff --git a/src/plugins/tellajoke/tellajoke/tellajoke.lua b/src/plugins/tellajoke/tellajoke/tellajoke.lua index 680e0420d2f..58d07e0b178 100644 --- a/src/plugins/tellajoke/tellajoke/tellajoke.lua +++ b/src/plugins/tellajoke/tellajoke/tellajoke.lua @@ -50,7 +50,7 @@ return { Category = "Fun", Description = "This plugin adds an action that tells a joke.", Dependencies = { - { Name = "Lua", Version = "13.0.82", Required = true }, + { Name = "Lua", Version = "14.0.0" }, }, setup = setup, } --[[@as QtcPlugin]] diff --git a/src/plugins/welcome/images/mode_welcome_mask.png b/src/plugins/welcome/images/mode_welcome_mask.png index 696af0c5499..f15a361e45d 100644 Binary files a/src/plugins/welcome/images/mode_welcome_mask.png and b/src/plugins/welcome/images/mode_welcome_mask.png differ diff --git a/src/plugins/welcome/images/mode_welcome_mask@2x.png b/src/plugins/welcome/images/mode_welcome_mask@2x.png index 060ada0cf54..63b8b88ed83 100644 Binary files a/src/plugins/welcome/images/mode_welcome_mask@2x.png and b/src/plugins/welcome/images/mode_welcome_mask@2x.png differ diff --git a/src/tools/icons/qtcreatoricons.svg b/src/tools/icons/qtcreatoricons.svg index 9c62d2a0ef3..7aa9fe1bed7 100644 --- a/src/tools/icons/qtcreatoricons.svg +++ b/src/tools/icons/qtcreatoricons.svg @@ -4866,35 +4866,22 @@ width="16" height="16" id="rect4959-4" /> - - - - - + + style="fill:#000000;stroke:none" + id="rect50185" + width="5" + height="7" + x="466" + y="576" + ry="2.5" /> + - + + + + + id="path43573" + style="fill:none;stroke:#000000;stroke-width:2;stroke-linecap:round" + d="m 100,63 h 16 m -16,-4 h 12 m -12,-4 h 16 m -16,-4 h 12 m -12,-4 h 16" /> + id="g49500" + inkscape:transform-center-y="0.70710678" + transform="rotate(-45,157.5,54.5)" + inkscape:transform-center-x="-0.70710678"> + id="path47960" + style="fill:none;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:round" + d="M 159,54.5 A 1.5,1.5 0 0 1 157.5,56 1.5,1.5 0 0 1 156,54.5 1.5,1.5 0 0 1 157.5,53 1.5,1.5 0 0 1 159,54.5 Z M 157.5,45 v 8 m -3.5,6 c 7,0 7,0 7,0 m -4.5,-14 h 2 l 4,10 -1.5,4 1.5,3 h -10 l 1.5,-3 -1.5,-4 z" /> + id="g73594" + style="fill:none;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:round"> + id="path72820" + d="m 207,58 h 2 m 6,4 v -2 h -2 m -12,2 v -2 h 2 m 12,-4 h -1.5 m 1.5,-4 h -2 m -6,2 h 2 m -8,2 h 1.5 M 201,52 h 2 m 8,-5 -1,2 m -5,-2 1,2" /> + - + + + + + + + + + style="fill:none;stroke:#000000;stroke-width:1.5;stroke-linecap:round" + d="m 356.7,52.44 c 0.57,-2 3.6,-2.35 4.33,-0.36 0.72,2 -1.54,2.2 -2.18,4.2" + id="path97127" + sodipodi:nodetypes="czc" /> @@ -8824,11 +8860,10 @@ id="use5913-0-8-1" width="100%" height="100%" /> - + - - - - - + + - + style="fill:#ffffff;stroke:#000000;stroke-width:4;stroke-linejoin:round;paint-order:stroke markers fill" + id="biginterruptbar" + width="2" + height="11" + x="757" + y="52" /> + - + + style="fill:none;stroke:#000000;stroke-width:2;stroke-linejoin:round" + d="m 765,51 6,6 -6,7 z" + id="path34590" /> + id="src/plugins/projectexplorer/images/build_hammer_mask"> - - - - - - - + id="g29289" + transform="rotate(30,861.61602,58.5)"> + + + style="fill:#ffffff;stroke:#000000;stroke-width:4;stroke-linejoin:round;paint-order:markers stroke fill" + id="rect38197" + width="10" + height="10" + x="757" + y="53" /> setStandardInputFile(packet.standardInputFile); ProcessStartHandler *handler = process->processStartHandler(); handler->setWindowsSpecificStartupFlags(packet.belowNormalPriority, - packet.createConsoleOnWindows); + packet.createConsoleOnWindows, + packet.forceDefaultErrorMode); handler->setProcessMode(packet.processMode); handler->setWriteData(packet.writeData); handler->setNativeArguments(packet.nativeArguments); diff --git a/tests/auto/extensionsystem/pluginspec/tst_pluginspec.cpp b/tests/auto/extensionsystem/pluginspec/tst_pluginspec.cpp index 66828f8e63b..ed8476a0b09 100644 --- a/tests/auto/extensionsystem/pluginspec/tst_pluginspec.cpp +++ b/tests/auto/extensionsystem/pluginspec/tst_pluginspec.cpp @@ -190,25 +190,25 @@ void tst_PluginSpec::provides() CppPluginSpec spec; QVERIFY(spec.readMetaData(metaData("testspecs/simplespec.json"))); - QVERIFY(!spec.provides("SomeOtherPlugin", "2.2.3_9")); - QVERIFY(!spec.provides("MyPlugin", "2.2.3_10")); - QVERIFY(!spec.provides("MyPlugin", "2.2.4")); - QVERIFY(!spec.provides("MyPlugin", "2.3.11_1")); - QVERIFY(!spec.provides("MyPlugin", "2.3")); - QVERIFY(!spec.provides("MyPlugin", "3.0")); - QVERIFY(!spec.provides("MyPlugin", "1.9.9_99")); - QVERIFY(!spec.provides("MyPlugin", "1.9")); - QVERIFY(!spec.provides("MyPlugin", "0.9")); - QVERIFY(!spec.provides("MyPlugin", "1")); + QVERIFY(!spec.provides(&spec, {"SomeOtherPlugin", "2.2.3_9"})); + QVERIFY(!spec.provides(&spec, {"MyPlugin", "2.2.3_10"})); + QVERIFY(!spec.provides(&spec, {"MyPlugin", "2.2.4"})); + QVERIFY(!spec.provides(&spec, {"MyPlugin", "2.3.11_1"})); + QVERIFY(!spec.provides(&spec, {"MyPlugin", "2.3"})); + QVERIFY(!spec.provides(&spec, {"MyPlugin", "3.0"})); + QVERIFY(!spec.provides(&spec, {"MyPlugin", "1.9.9_99"})); + QVERIFY(!spec.provides(&spec, {"MyPlugin", "1.9"})); + QVERIFY(!spec.provides(&spec, {"MyPlugin", "0.9"})); + QVERIFY(!spec.provides(&spec, {"MyPlugin", "1"})); - QVERIFY(spec.provides("myplugin", "2.2.3_9")); - QVERIFY(spec.provides("MyPlugin", "2.2.3_9")); - QVERIFY(spec.provides("MyPlugin", "2.2.3_8")); - QVERIFY(spec.provides("MyPlugin", "2.2.3")); - QVERIFY(spec.provides("MyPlugin", "2.2.2")); - QVERIFY(spec.provides("MyPlugin", "2.1.2_10")); - QVERIFY(spec.provides("MyPlugin", "2.0_10")); - QVERIFY(spec.provides("MyPlugin", "2")); + QVERIFY(spec.provides(&spec, {"myplugin", "2.2.3_9"})); + QVERIFY(spec.provides(&spec, {"MyPlugin", "2.2.3_9"})); + QVERIFY(spec.provides(&spec, {"MyPlugin", "2.2.3_8"})); + QVERIFY(spec.provides(&spec, {"MyPlugin", "2.2.3"})); + QVERIFY(spec.provides(&spec, {"MyPlugin", "2.2.2"})); + QVERIFY(spec.provides(&spec, {"MyPlugin", "2.1.2_10"})); + QVERIFY(spec.provides(&spec, {"MyPlugin", "2.0_10"})); + QVERIFY(spec.provides(&spec, {"MyPlugin", "2"})); } void tst_PluginSpec::experimental() diff --git a/tests/auto/ios/devicectlutils/tst_devicectlutils.cpp b/tests/auto/ios/devicectlutils/tst_devicectlutils.cpp index f75497f68a3..8924c58a867 100644 --- a/tests/auto/ios/devicectlutils/tst_devicectlutils.cpp +++ b/tests/auto/ios/devicectlutils/tst_devicectlutils.cpp @@ -287,6 +287,7 @@ void tst_Devicectlutils::parseDeviceInfo_data() {"deviceConnected", "YES"}, {"deviceName", "Some iOS device"}, {"osVersion", "17.3 (21D50)"}, + {"productType", "iPad11,2"}, {"uniqueDeviceId", "00000000-0000000000000000"}}); QTest::addRow("unhandled device") << data << QString("000000000000000000000001") diff --git a/tests/auto/solutions/tasking/tst_tasking.cpp b/tests/auto/solutions/tasking/tst_tasking.cpp index db293d4ebfb..f3d83b4806d 100644 --- a/tests/auto/solutions/tasking/tst_tasking.cpp +++ b/tests/auto/solutions/tasking/tst_tasking.cpp @@ -118,6 +118,7 @@ private slots: void storageOperators(); void storageDestructor(); void storageZeroInitialization(); + void nestedBrokenStorage(); void restart(); void destructorOfTaskEmittingDone(); }; @@ -3452,6 +3453,55 @@ void tst_Tasking::storageZeroInitialization() QCOMPARE(defaultValue, 0); } +// This test ensures that when a missing storage object inside the nested task tree is accessed +// directly from the outer task tree's handler, containing the same storage object, then we +// detect this misconfigured recipe, issue a warning, and return nullptr for the storage +// being accessed (instead of returning parent's task tree's storage instance). +// This test should also trigger a runtime assert that we are accessing the nullptr storage. +void tst_Tasking::nestedBrokenStorage() +{ + int *outerStorage = nullptr; + int *innerStorage1 = nullptr; + int *innerStorage2 = nullptr; + const Storage storage; + + const auto onOuterSync = [storage, &outerStorage, &innerStorage1, &innerStorage2] { + outerStorage = &*storage; + + const auto onInnerSync1 = [storage, &innerStorage1] { + innerStorage1 = &*storage; // Triggers the runtime assert on purpose. + }; + const auto onInnerSync2 = [storage, &innerStorage2] { + innerStorage2 = &*storage; // Storage is accessible in currently running tree - all OK. + }; + + const Group innerRecipe { + Group { + // Broken subrecipe, the storage wasn't placed inside the recipe. + // storage, + Sync(onInnerSync1) + }, + Group { + storage, // Subrecipe OK, another instance for the nested storage will be created. + Sync(onInnerSync2) + } + }; + + TaskTree::runBlocking(innerRecipe); + }; + + const Group outerRecipe { + storage, + Sync(onOuterSync) + }; + + TaskTree::runBlocking(outerRecipe); + QVERIFY(outerStorage != nullptr); + QCOMPARE(innerStorage1, nullptr); + QVERIFY(innerStorage2 != nullptr); + QVERIFY(innerStorage2 != outerStorage); +} + void tst_Tasking::restart() { TaskTree taskTree({TestTask([](TaskObject &taskObject) { taskObject = 1000ms; })}); diff --git a/tests/manual/subdirfilecontainer/tst_subdirfilecontainer.cpp b/tests/manual/subdirfilecontainer/tst_subdirfilecontainer.cpp index ca4925a9439..31abdca256d 100644 --- a/tests/manual/subdirfilecontainer/tst_subdirfilecontainer.cpp +++ b/tests/manual/subdirfilecontainer/tst_subdirfilecontainer.cpp @@ -155,7 +155,7 @@ private slots: tasks.append(AsyncTask(onCopySetup(parentDir.filePath(sourceDirName), parentDir.filePath(destDirName)))); } - QVERIFY(TaskTree::runBlocking(tasks)); + QCOMPARE(TaskTree::runBlocking(tasks), DoneWith::Success); } void cleanupTestCase() @@ -177,7 +177,7 @@ private slots: for (int i = 0; i < s_topLevelSubDirsCount; ++i) tasks.append(AsyncTask(onSetup(parentDir.filePath(dirName(i))))); - QVERIFY(TaskTree::runBlocking(tasks)); + QCOMPARE(TaskTree::runBlocking(tasks), DoneWith::Success); m_tempDir.reset(); Singleton::deleteAll();